我正在编写一个简单的Jison语法,以便在开始更复杂的项目之前获得一些经验。我尝试了一个简单的语法,它是一个逗号分隔的数字范围列表,其范围的开头和结束值相同,以使用单个数字速记。但是,当在某些测试输入上运行生成的解析器时,我收到一个对我来说没有多大意义的错误。这是我想出的语法:
/* description: Parses end executes mathematical expressions. */
/* lexical grammar */
%lex
%%
s+ /* skip whitespace */
[0-9]+ {return 'NUMBER'}
"-" {return '-'}
"," {return ','}
<<EOF>> {return 'EOF'}
. {return 'INVALID'}
/lex
/* operator associations and precedence */
%start ranges
%% /* language grammar */
ranges
: e EOF
{return $1;}
;
e : rng { $$ = $1;}
| e ',' e {alert('e,e');$$ = new Array(); $$.push($1); $$.push($3);}
;
rng
: NUMBER '-' NUMBER
{$$ = new Array(); var rng = {Start:$1, End: $3; }; $$.push(rng); }
| NUMBER
{$$ = new Array(); var rng = {Start:$1, End: $1; }; $$.push(rng);}
;
NUMBER: {$$ = Number(yytext);};
测试输入如下:
5-10,12-16
输出为:
Parse error on line 1:
5-10,12-16
^
Expecting '-', 'EOF', ',', got '8'
如果它在前面放了一个"a",我会收到有关查找"无效"的预期错误,但我在输入字符串中没有"8",所以我想知道这是否是内部状态?
我正在使用在线解析器生成器: http://zaach.github.io/jison/try/
思潮?
这个制作让Jison感到困惑(它也让我感到困惑,:)):
NUMBER: {$$ = Number(yytext);};
NUMBER
应该是终端,但上述生产将其声明为具有空体的非终端。由于它不能匹配任何内容,因此它会立即匹配,并且您的语法不允许连续两个NUMBER
。因此错误。
另外,你的语法是模棱两可的,尽管我想Jison的默认值会解决这个问题。不过,最好是明确一点,因为这很容易。您的规则:
e : rng
| e ',' e
没有具体说明如何,
"关联":换句话说,rng , rng , rng
应被视为e , rng
还是rng , e
。第一个可能更适合你,所以你应该明确地写出来:
e : rng
| e ',' rng
上述方法的一大优点是,您不需要在第二个生产中创建新数组;您只需将$3
推到$1
末尾并将$$
设置为 $1
即可。