我正在使用JavaScript和Parsing Expression Grammar为Haskell编写词法分析器,我使用的实现是PEG.js。
我有一个问题,让它适用于保留字,如下面的简化形式所示:
program = ( word / " " )+
word = ( reserved / id )
id = ( "a" / "b" )+
reserved = ( "aa" )
这里的要点是得到一系列标记,它们是:s和/或b:s的任意序列或序列“aa”,它们用空格分隔。
我真正得到的是非空格的每个标记被识别为id
或者应该被识别为id
的标记具有以下所有的初始对:吃掉reserved
,例如
“aab”被识别为reserved "aa"
,后跟id "b"
。
Haskell词法规范解决这种歧义的方法是指定id如下:
id = ( "a" / "b" )+[BUT NOT reserved]
我尝试使用PEG的各种组合复制它!和& - 操作员实现同样的效果,但没有找到办法使其正常工作。
解决方案:
id = !reserved ( "a" / "b" )+
我在几个地方看到的建议不起作用
这是特定PEG实施的限制,PEG本身还是(希望)我的方法?
提前致谢!
答案 0 :(得分:1)
!reserved ident
是任何PEG实现中完全可接受的技术,PEG.js似乎也支持它。顺便说一下,您应该在!id
的定义之后添加reserved
。
答案 1 :(得分:0)
据我所知,PEG规则是定位的。这基本上意味着从第一个到最后一个确定性地尝试规则。也就是说,你只需要在声明“标识符”之前加上“保留”规则。