当前位置: 首页 > 知识库问答 >
问题:

如何在ANTLR中实现C语言解析器的lexer hack

温峻熙
2023-03-14

有没有可能实现经典的Yacc lexer hack来在由ANTLR4生成的C解析器中区分标识符名和类型名,使用标准的C语法(就像在官方的ANTLR4 GitHub repo上找到的一样)?

可以插入到ANTLR4 lexer中的ad-hoc代码似乎相当有限。Terrence Parr在《最终的ANTLR4参考》一书中说:

“一直存在的一种常见做法是将解析器的反馈发送给lexer,这样lexer就可以将精确的令牌发送给解析器。[...]不幸的是,这在ANTLR语法中是不可能的,因为ANTLR生成的解析器通常会在令牌流中遥遥无期地进行解析决策。[...]”

有什么方法可以绕过上述问题,实现反馈循环?或者在ANTLR4中实现C解析器在访问解析树时不借助疯狂的黑客是不可能的吗?

共有1个答案

宇文鸿畴
2023-03-14

谁说你必须问解析机器什么来实现lexer hack?黑客在雷克萨里。

C lexer攻击的关键是让lexer自己记录哪些标识符是类型名称。您可以通过跟踪发出的词法标记在lexer中实现这一点。有了足够的adhockery(这就是为什么它被称为hack的原因),您的lexer就可以识别“typedef....x;”并将“x”作为一个类型记录在lexer-local符号表中。

然后,当lexer遇到一个标识符(根据其本地符号表,该标识符恰好是typename),则lexer可以发出“type_identifier”而不是“identifier”。

如果typedef是作用域本地的,您的lexer还必须跟踪作用域构造,并在扫描作用域边界时相应地调整活动typedef的表。

当然,只有当您知道有一种类似于C语言的语言时,这种攻击才起作用,在这种语言中,解析器不会通过令牌返回,因为它们可能有不同的解析。AFAIK,ANTLR没有回溯。

(是的,如果解析器将提供对它跟踪的符号表的访问,作为解析的某种副作用,您可以简单地让lexer查询该表,前提是解析器不会返回。使其“安全”的可能是,当执行lexer时,解析子系统不在解析器中执行,因此符号表访问是安全的。如果您的lexer在解析器使用之前生成了一个lexems管道,那么它将异步WRT运行到解析器,现在它无法使用解析器的符号表;您必须回到上面描述的lexer-local符号表)。

(如果切换到GLR解析器,就可以避免黑客攻击。)

 类似资料:
  • 本文向大家介绍C语言实现xml构造解析器,包括了C语言实现xml构造解析器的使用技巧和注意事项,需要的朋友参考一下 纯C实现xml构造解析器,所有实现只有一个.c一个.h文件组成,简单易用,易于扩展。

  • 本文向大家介绍详细解析C语言中的开方实现,包括了详细解析C语言中的开方实现的使用技巧和注意事项,需要的朋友参考一下 关于C语言中的开方计算,首先想到的当然是sqrt()函数,让我们先来回顾一下它的基本用法: 头文件:#include <math.h> sqrt() 用来求给定值的平方根,其原型为: 参数 x 为要计算平方根的值。 如果 x < 0,将会导致 domain error 错误,并把全局

  • 本文向大家介绍Objective-C语言XML解析,包括了Objective-C语言XML解析的使用技巧和注意事项,需要的朋友参考一下

  • 问题内容: 任何人都可以为Java推荐一个不错的Java解析器吗?我相信可以使用Rhino,但是仅仅进行解析似乎是一个过大的选择,还是唯一的不错的解决方案?任何建议将不胜感激。谢谢。 问题答案: 来自https://github.com/google/caja/blob/master/src/com/google/caja/parser/js/Parser.java 下面的语法是此解析器解析的语法

  • 本文向大家介绍如何利用C语言实现最简单的HTTP服务器详解,包括了如何利用C语言实现最简单的HTTP服务器详解的使用技巧和注意事项,需要的朋友参考一下 此段代码的特点 如何编译运行? 编译: gcc -o hello_server hello_server.c 运行: ./hello_server 请求: curl http://localhost:8888/any 源文件 hello_serve

  • 我有一个复杂的jsf页面,其中有一些在PrimeFaces中开发的小部件。到目前为止,应用程序是完全ajaxified的,这意味着没有提交,但是所有的事件和更新都是通过Ajax行为来处理的(这不是必须的,而是一个很好的特性)。我还做了一个来切换语言: 在selectonemenu中有一个ajax更新: 这很好用,是首选的解决方案,因为它是Ajax,但是 已编辑 欢迎任何建议。