PLY: C解析器中的令牌移动问题
我正在用 PLY 写一个 C 语言解析器,最近遇到了一个问题。
这段代码:
typedef int my_type;
my_type x;
是正确的 C 代码,因为 my_type 在使用之前已经定义过了。我通过在解析器中填充一个类型符号表来处理这个问题,这个符号表会被词法分析器用来区分类型和简单的标识符。
但是,虽然类型声明规则以分号(';')结束,PLY 在决定第一个声明完成之前,就已经把第二行的 my_type
这个标记移走了。因此,我没有机会把类型符号表的更新传递给词法分析器,结果它把 my_type 视为一个标识符,而不是一个类型。
有没有什么解决办法?
完整代码可以在这里找到:http://code.google.com/p/pycparser/source/browse/trunk/src/c_parser.py。我不太确定怎么从中创建一个更小的示例。
编辑:
问题解决了。请看我下面的解决方案。
3 个回答
我觉得你需要把检查一个ID是否是TYPEID的这部分,从c_lexer.py移动到c_parser.py。
正如你所说,解析器只看前面一个标记,所以在词法分析器里无法做出这个判断。
相反,你应该修改你的解析器,去检查ID是否在声明中是TYPEID,如果不是,就生成一个错误。
正如Pax Diablo在他精彩的回答中提到的,词法分析器/标记器的工作不是去做这些关于标记的判断。这是解析器的工作。
我不太明白你为什么要在词法分析器中进行这么复杂的分析。
词法分析的主要任务是把输入的数据流分成一个个词法单元,比如数字、换行符、关键字等等。真正进行深入分析的应该是解析阶段,这个阶段会处理像类型定义查找这样的事情。
这就是我一直以来在使用lex和yacc这两个工具时,分配任务的方式。
在Dave Beazley(PLY的创始人)的一些帮助下,我的问题解决了。
这个想法是使用特殊的子规则,并在其中执行操作。在我的例子中,我把declaration
规则拆分成了:
def p_decl_body(self, p):
""" decl_body : declaration_specifiers init_declarator_list_opt
"""
# <<Handle the declaration here>>
def p_declaration(self, p):
""" declaration : decl_body SEMI
"""
p[0] = p[1]
decl_body
总是在处理分号(SEMI)后面的标记之前被简化,所以我的操作在正确的时间执行。