我正在尝试使用Jison,它是解析器生成器Bison的JS端口。我的目标是转换此输入:
foo(10)
bar()
foo(28)
baz(28)
进入这个:
[
{ func: 'foo', arg: 10 },
{ func: 'bar' },
{ func: 'foo', arg: 28 },
{ func: 'baz', arg: 28 }
]
这是我的野牛档案:
%lex
%%
[0-9]+\b return 'INTEGER'
\( return 'OPEN_PAREN'
\) return 'CLOSE_PAREN'
[\w]+\s*(?=\() return 'FUNC_NAME'
\n+ return 'LINE_END'
/lex
%%
expressions
: expressions expression
| expression
;
expression
: LINE_END
| e LINE_END
{return $1}
;
e
: FUNC_NAME OPEN_PAREN INTEGER CLOSE_PAREN
{$$ = { func: $1, arg: $3 };}
| FUNC_NAME OPEN_PAREN CLOSE_PAREN
{$$ = { func: $1 };}
;
生成的生成的解析器的输出为{ func: 'foo', arg: 10 }
。换句话说,它只返回第一个语句中的解析对象,而忽略其余的。
我知道我的问题与语义价值和expression
的“右侧”有关,但我很遗憾。
非常感谢任何帮助!
答案 0 :(得分:1)
我附加了一个符合你要求的语法。显着的变化是:
LINE_END
的正则表达式\n+|$
也匹配输出的结尾。
我添加了start
作品,其作用只是返回最终结果。
重写expression
作品以生成数组。我还从{return $1}
规则中删除了e LINE_END
,因为这导致解析器提前返回。
修改了expressions
生产以连接数组。
对于expression
和expressions
制作,我在那里使用了规则的简写语法。例如,expression -> [$1]
相当于expression { $$ = [$1] }
。
这是语法:
%lex
%%
[0-9]+\b return 'INTEGER'
\( return 'OPEN_PAREN'
\) return 'CLOSE_PAREN'
[\w]+\s*(?=\() return 'FUNC_NAME'
\n+|$ return 'LINE_END'
/lex
%%
start:
expressions
{ return $1 }
;
expressions
: expressions expression -> $1.concat($2)
| expression
;
expression
: LINE_END -> []
| e LINE_END -> [$1]
;
e
: FUNC_NAME OPEN_PAREN INTEGER CLOSE_PAREN
{$$ = { func: $1, arg: $3 };}
| FUNC_NAME OPEN_PAREN CLOSE_PAREN
{$$ = { func: $1 };}
;
旁边:杰森不是野牛的港口。它是一个解析器生成器,其功能受到Bison 的强烈启发,但它具有Bison没有的功能,并且Jison不支持Bison的一些功能。