Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 这个语法怎么会模棱两可?_Javascript_Parsing_Bison_Parser Generator_Jison - Fatal编程技术网

Javascript 这个语法怎么会模棱两可?

Javascript 这个语法怎么会模棱两可?,javascript,parsing,bison,parser-generator,jison,Javascript,Parsing,Bison,Parser Generator,Jison,我正在用Jison编写一个简单的表达式解析器。这是我的语法: { "operators": [ ["left", "+", "-"], ["left", "*", "/", "%"] ], "bnf": { "program": [ ["statement EOF", "return $1;"] ], "statement": [ ["expre

我正在用Jison编写一个简单的表达式解析器。这是我的语法:

{
    "operators": [
        ["left", "+", "-"],
        ["left", "*", "/", "%"]
    ],
    "bnf": {
        "program": [
            ["statement EOF", "return $1;"]
        ],
        "statement": [
            ["expression NEWLINE", "$$ = $1 + ';';"]
        ],
        "expression": [
            ["NUMBER",                       "$$ = yytext;"],
            ["expression binary expression", "$$ = $1 + $2 + $3;"]
        ],
        "binary": [
            ["+",              "$$ = ' + ';"],
            ["-",              "$$ = ' - ';"],
            ["*",              "$$ = ' * ';"],
            ["/",              "$$ = ' / ';"],
            ["%",              "$$ = ' % ';"],
            ["binary NEWLINE", "$$ = $1;"]
        ]
    }
}
当我尝试运行它时,会出现以下错误:

Conflict in grammar: multiple actions possible when lookahead token is + in state
13
- reduce by rule: expression -> expression binary expression
- shift token (then go to state 8)
Conflict in grammar: multiple actions possible when lookahead token is - in state
13
- reduce by rule: expression -> expression binary expression
- shift token (then go to state 9)
Conflict in grammar: multiple actions possible when lookahead token is * in state
13
- reduce by rule: expression -> expression binary expression
- shift token (then go to state 10)
Conflict in grammar: multiple actions possible when lookahead token is / in state
13
- reduce by rule: expression -> expression binary expression
- shift token (then go to state 11)
Conflict in grammar: multiple actions possible when lookahead token is % in state
13
- reduce by rule: expression -> expression binary expression
- shift token (then go to state 12)

States with conflicts:
State 13
  expression -> expression binary expression . #lookaheads= NEWLINE + - * / %
  expression -> expression .binary expression
  binary -> .+
  binary -> .-
  binary -> .*
  binary -> ./
  binary -> .%
  binary -> .binary NEWLINE
然而,它最终仍然会产生正确的输出。例如,将
2+3*5/7%11
正确翻译为
2+3*5/7%11

在我看来,我的语法似乎很明确,那么吉森为什么要抱怨呢

更新:正如@icktoofay解释的,这是一个运算符关联性问题。通过将运算符解析为非终端符号,运算符的优先级和关联性信息将丢失。因此,我解决了以下问题:

{
    "operators": [
        ["left", "+", "-"],
        ["left", "*", "/", "%"]
    ],
    "bnf": {
        "program": [
            ["statement EOF", "return $1;"]
        ],
        "statement": [
            ["expression NEWLINE", "$$ = $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 + NEWLINE expression", "$$ = $1 + ' + ' + $4;"],
            ["expression - NEWLINE expression", "$$ = $1 + ' - ' + $4;"],
            ["expression * NEWLINE expression", "$$ = $1 + ' * ' + $4;"],
            ["expression / NEWLINE expression", "$$ = $1 + ' / ' + $4;"],
            ["expression % NEWLINE expression", "$$ = $1 + ' % ' + $4;"]
        ]
    }
}

也就是说,这种语法只允许一个可选换行符跟在二进制运算符后面。如何重写它,以允许任意数量的换行符跟随二进制运算符?另外,必须有某种方式,我不必为每个运算符编写两条规则。

我对Jison不太熟悉,但看起来您正在定义一条如下所示的规则:

expression ::= number;
expression ::= expression binary expression;
考虑表达式
1-2-3
。这可以解释为
(1-2)-3
1-(2-3)
。是哪一个?你的语法模棱两可。正常的数学规则说它应该是左关联的。你需要让你的语法反映出:

expression ::= number;
expression ::= expression binary number;

你说得对。运算符关联性确实是个问题。非常感谢。我可以麻烦你做点别的事吗?我已经编辑了我的问题,我想知道你对此的看法。也许我应该把它作为一个单独的问题发布?@AaditMShah:我只是修改lexer来合并连续的换行符。至于有
新行
/无
新行
需要两个产品,也许你可以用两个产品制作一个新的
新行
,一个为空,一个为
新行
。(事实上,如果你不想修改lexer,你可以有一个
maybe\u newline
和一个
maybe\u newline
production。)