我正在用Jison编写一个简单的表达式解析器,允许在表达式中的二进制操作符后面跟随任意数量的换行符。这是我到目前为止的语法:
{
"operators": [
["left", "+", "-"],
["left", "*", "/", "%"]
],
"bnf": {
"program": [
["statement EOF", "return $1;"]
],
"statement": [
["expression newlines", "$$ = $1 + ';';"]
],
"expression": [
["NUMBER", "$$ = yytext;"],
["expression + expression", "$$ = $1 + ' + ' + $3;"],
["expression - expression", "$$ = $1 + ' - ' + $3;"],
["expression * expression", "$$ = $1 + ' * ' + $3;"],
["expression / expression", "$$ = $1 + ' / ' + $3;"],
["expression % expression", "$$ = $1 + ' % ' + $3;"],
["expression + newlines expression", "$$ = $1 + ' + ' + $4;"],
["expression - newlines expression", "$$ = $1 + ' - ' + $4;"],
["expression * newlines expression", "$$ = $1 + ' * ' + $4;"],
["expression / newlines expression", "$$ = $1 + ' / ' + $4;"],
["expression % newlines expression", "$$ = $1 + ' % ' + $4;"]
],
"newlines": [
["NEWLINE", ""],
["newlines NEWLINE", ""]
]
}
}
正如你所看到的,我为每个二进制运算符写了两个规则。在我看来,那是非常多余的。我宁愿有一个匹配零个或多个NEWLINE
代币(Kleene星号)的产品,而不是一个或多个代币(Kleene plus)。在杰森你会怎么做?
我使用Jison,忽略空白(包括换行)。
my %lex中的第一行是:
s+ /* ignore */
但是如果你不想的话,你可以不这样做。试试这样做:
"expression": [
["NUMBER", "$$ = yytext;"],
["expression + expression", "$$ = $1 + ' + ' + $3;"],
["expression - expression", "$$ = $1 + ' - ' + $3;"],
["expression * expression", "$$ = $1 + ' * ' + $3;"],
["expression / expression", "$$ = $1 + ' / ' + $3;"],
["expression % expression", "$$ = $1 + ' % ' + $3;"],
["expression newlines", "$$ = $1"],
["newlines expression", "$$ = $2"]
],
这应该允许任意数量的新行在任何表达式之前/之后。