【问题标题】:Excluding certain elements from a specified set in Parsing Expressive Grammar (PEG.js)?从 Parsing Expressive Grammar (PEG.js) 中的指定集合中排除某些元素?
【发布时间】:2011-02-08 13:44:39
【问题描述】:

我正在使用 JavaScript 和 Parsing Expression Grammar 为 Haskell 编写一个词法分析器,我使用的实现是 PEG.js
我在使它适用于保留字时遇到问题,如下面的简化形式所示:

program = ( word / " " )+  
word = ( reserved / id )  
id = ( "a" / "b" )+  
reserved = ( "aa" )

这里的重点是获取一系列标记,这些标记要么是 a:s 和/或 b:s 的任意序列,要么是序列“aa”,它们之间用空格分隔。
我真正得到的是不是空格的 每个 标记被识别为id 或者应该被识别为id 的标记具有所有初始对 a:s 被吃掉reserved,例如
“aab”被识别为reserved "aa",后跟id "b"

Haskell 词法规范解决这种歧义的方法是像这样指定 id:

id = ( "a" / "b" )+[BUT NOT reserved]

我尝试使用 PEG 的各种组合来复制它!和 & -operators 来实现相同的效果,但还没有找到让它正常工作的方法。
解决办法:

id = !reserved ( "a" / "b" )+

我在几个地方看到的建议不起作用。
这是特定 PEG 实现、PEG 本身或(希望)我的方法的限制吗?

提前致谢!

【问题讨论】:

    标签: javascript parsing lexical-analysis


    【解决方案1】:

    !reserved ident 在任何 PEG 实现中都是一种完全可以接受的技术,而且 PEG.js 似乎也支持它。顺便说一句,您应该在reserved 的定义之后添加!id

    【讨论】:

    • 将 !id 添加到 reserved 的末尾,我得到了部分成功的结果。如果我的 "a":s 序列不均匀,它会正确解析,但即使序列仍然会给出错误的结果。
    • 我的意思与reservedBase = "aa"/"bb" reserved = reservedBase !idBase idBase = ("a"/"b")+ id = !reserved idBase 一致。查看提供的javascript.jspeg 示例。
    • 虽然我仍然遇到第一条评论中指定的相同问题,但我似乎找不到更好的解决方案,所以我暂时考虑这个问题。如果我发现更好的东西,我会更新。谢谢!
    【解决方案2】:

    据我所知,PEG 规则是位置性的。这基本上意味着从第一个到最后一个确定性地尝试规则。也就是说,您只需要在声明“标识符”之前放置“保留”规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      • 2021-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      相关资源
      最近更新 更多