Bla*_*ble 5 javascript grammar abstract-syntax-tree
我正在 github 上使用来自 Zach Carter 的reflect.js(一个不错的Javascript 解析器);我正在尝试修改他的解析器的行为,以将注释作为应该像其他任何东西一样被解析的普通标记来处理。reflect.js 的默认行为是跟踪所有注释(词法分析器将它们作为标记抓取),然后将它们的列表附加到它创建的 AST(抽象语法树)的末尾。
但是,我希望将这些注释就地包含在 AST 中。我相信此更改将涉及向这里的grammar.y 文件添加语法规则。目前没有评论规则——如果我的理解是正确的,这就是为什么它们被主要解析代码忽略的原因。
您如何编写规则以在 AST 中包含注释?
天真的版本修改了原始语法的每条规则:
LHS = RHS1 RHS2 ... RHSN ;
Run Code Online (Sandbox Code Playgroud)
成为:
LHS = RHS1 COMMENTS RHS2 COMMENTS ... COMMENTS RHSN ;
Run Code Online (Sandbox Code Playgroud)
虽然这在抽象中是有效的,但如果它是基于 LL 或 LALR 的,这可能会搞砸你的解析器生成器,因为现在它无法仅凭下一个标记来决定要做什么。因此,您必须切换到更强大的解析器生成器,例如 GLR。
更聪明的版本将(仅并且)每个终端T 替换为非终端:
T = COMMENTS t ;
Run Code Online (Sandbox Code Playgroud)
并修改原始词法分析器以简单地发出 t 而不是 T。您仍然遇到前瞻问题。
但这为我们提供了真正解决方案的基础。
一个更复杂的版本是使词法分析器收集在令牌之前看到的注释并将它们附加到它发出的下一个令牌;本质上,我们正在词法分析器中实现语法的最终规则修改。
现在解析器(您不必切换技术)只看到它最初看到的标记;标记带有注释作为注释。您会发现将注释分为附加到前一个标记的注释和附加到下一个标记的注释很有用,但是您无法使这比启发式更好,因为没有实际的方法来决定评论真正属于哪个标记。
您会发现弄清楚如何捕获标记和注释上的定位信息以启用原始文本的重新生成(“在适当位置的注释”)很有趣。您会发现,以不违反语言语法规则的方式,使用适当的基数值、字符串转义符等实际重新生成文本会更有趣。
我们使用通用语言处理工具来做到这一点,并且效果相当好。令人惊讶的是,要完成这一切需要付出多少工作,以便您可以专注于转型任务。人们低估了这一点。
| 归档时间: |
|
| 查看次数: |
201 次 |
| 最近记录: |