dbeurive/shuntingyard

这是shunting yard算法的实现。

1.0.3 2016-11-27 11:38 UTC

This package is not auto-updated.

Last update: 2024-09-23 15:51:10 UTC


README

此仓库包含Shunting Yard算法的实现(点击查看详细说明)

安装

从命令行

composer require dbeurive\shuntingyard

如果您想将此包包含到项目中,请编辑您的文件composer.json并添加以下条目

"require": {
	"dbeurive/shuntingyard": "*"
}

概要

	use dbeurive\Shuntingyard\ShuntingYard;
	
	define('TYPE_STRING',          'STRING');
	define('TYPE_VARIABLE',        'VARIABLE');
	define('TYPE_FUNCTION',        'FUNCTION');
	define('TYPE_NUMERIC',         'NUMERIC');
	define('TYPE_PARAM_SEPARATOR', 'PARAM_SEPARATOR');
	define('TYPE_OPEN_BRACKET',    'OPEN_BRACKET');
	define('TYPE_CLOSE_BRACKET',   'CLOSE_BRACKET');
	define('TYPE_OPERATOR',        'OPERATOR');
	define('TYPE_SPACE',           'SPACE');
	
	$tokens = array(
    	array('/"(?:[^"\\\\]|\\\\["\\\\])+"/',                TYPE_STRING),
    	array('/V\\d+/',                                      TYPE_VARIABLE),
    	array('/[a-z_]+[0-9]*/',                              TYPE_FUNCTION),
    	array('/\\d+/',                                       TYPE_NUMERIC),
    	array('/,/',                                          TYPE_PARAM_SEPARATOR),
    	array('/\\(/',                                        TYPE_OPEN_BRACKET),
    	array('/\\)/',                                        TYPE_CLOSE_BRACKET),
    	array('/(<>|~|%|\\+|\\-|\\*|\\/|\\^|>=|<=|>|<|=|&)/', TYPE_OPERATOR),
    	array('/\\s+/',                                       TYPE_SPACE, function(array $m) { return null; })
	);

	$precedences = array(
    	'%'     => 4,
    	'~'     => 4,
    	'^'     => 4,
    	'&'     => 3,
    	'*'     => 3,
    	'/'     => 3,
    	'+'     => 2,
    	'-'     => 2,
    	'>'     => 1,
    	'<'     => 1,
    	'>='    => 1,
    	'<='    => 1,
    	'='     => 1,
    	'<>'    => 1
	);

	$associativities = array(
    	'~'     => ShuntingYard::ASSOC_RIGHT,
    	'%'     => ShuntingYard::ASSOC_RIGHT,
    	'^'     => ShuntingYard::ASSOC_RIGHT,
    	'&'     => ShuntingYard::ASSOC_LEFT,
    	'*'     => ShuntingYard::ASSOC_LEFT,
    	'/'     => ShuntingYard::ASSOC_LEFT,
    	'+'     => ShuntingYard::ASSOC_LEFT,
    	'-'     => ShuntingYard::ASSOC_LEFT,
    	'>'     => ShuntingYard::ASSOC_LEFT,
    	'<'     => ShuntingYard::ASSOC_LEFT,
    	'>='    => ShuntingYard::ASSOC_LEFT,
    	'<='    => ShuntingYard::ASSOC_LEFT,
    	'='     => ShuntingYard::ASSOC_LEFT,
    	'<>'    => ShuntingYard::ASSOC_LEFT
	);

	$sy = new ShuntingYard(
    	$tokens,
    	$precedences,
    	$associativities,
    	array(TYPE_VARIABLE, TYPE_STRING, TYPE_NUMERIC),
    	array(TYPE_FUNCTION),
    	array(TYPE_OPERATOR),
    	TYPE_PARAM_SEPARATOR,
    	TYPE_OPEN_BRACKET,
    	TYPE_CLOSE_BRACKET
	);

	$text = '"azerty" / V1 + V2 * sin(10)';
	$tokens = $sy->convert($text, $error);
	print "$text:\n\n" . $sy->dumpRpn($tokens) . "\n\n";

结果

"azerty" / V1 + V2 * sin(10):

  STRING "azerty"
VARIABLE V1
OPERATOR /
VARIABLE V2
 NUMERIC 10
FUNCTION sin
OPERATOR *
OPERATOR +

配置

该算法通过以下方式配置

  • 令牌列表(请参阅dbeurive\Lexer\Lexer类的文档)。
  • 操作符的优先级。
  • 操作符的结合性。
  • 代表变量的令牌类型列表。
  • 代表函数的令牌类型列表。
  • 代表操作符的令牌类型列表。
  • 代表参数分隔符的令牌类型。
  • 代表参数列表开始的令牌类型(通常是"(")。
  • 代表参数列表结束的令牌类型(通常是")")。

警告

请确保在定义令牌的正则表达式中将所有"\"字符双写。也就是说:'/\s/'变为'/\\s/'

请注意,令牌声明的顺序很重要(请参阅dbeurive\Lexer\Lexer类的文档)。

概要应该足够清晰。您还可以参考示例