我的语言有4种语句:s00,s01,s10,s11,其中前导1表示初始关键字,尾随1表示终止,我有一个分隔符“;”。我可以用“;”终止任何声明。我想解析一种允许最少使用“;”的语句列表的语言。解析器是Dypgen,它是GLR +。
示例:
{ x=1 fun f(){} x=1; x=1 var x=1 var x=1; x=1 }
是否可以这样做?如果是这样,怎么样?如果没有,为什么?
我相信它无法完成,主要是因为我想不出怎么做:) 但它确实看起来像上下文:规则是你必须插入一个“;” A和B之间如果A没有被终止而B没有被启动,那么B和C也是如此,这意味着B被使用了两次。
然而,因为解析器是GLR +,所以很容易使用
(s00|s01|s10|s11}*
作为规则,如果它错误地投入“;” (这是一个s11 no-op)来解决歧义。如果解析器报告语法错误会更好。也许这可以在合并替代制作时完成。真正的问题是当它们重叠而不是合并时:如果发生这种情况,程序解析可能会爆炸。
答案 0 :(得分:1)
我最近遇到了类似问题的顶级短语,其中一些需要在前一个短语中终止;;
,而其他短语(以短语引入关键字开头)则不然。我通过将短语的句法类别分成两部分来解决我的问题,并为表达这种行为的短语序列提供了精细的规则。但这导致了分裂语法的重复。
在你的情况下,它会是这样的:
sequence:
| (s00 | s10) sequence_closed
| (s01 | s11) sequence_open
| ε
sequence_closed:
| s10 sequence_closed
| s11 sequence_open
| ';' sequence_open
| ε
sequence_open:
| s00 sequence_closed
| s01 sequence_open
| ε
如果你想允许多余的分隔符(而且你很可能想要),这会有点复杂,但这就是想法。