我正在使用PLY编写一个C解析器,最近遇到了一个问题。 这段代码:
typedef int my_type;
my_type x;
是否是正确的C代码,因为my_type被定义为以前的类型 被用作这样的。我通过填写一个类型符号表来处理它 词法分析器使用的解析器来区分类型和 简单的标识符。
然而,当类型声明规则以SEMI(';'标记)结束时,PLY将令牌my_type
从第二行移开,然后再决定它是否完成了第一行。因此,我没有机会将类型符号表中的更新传递给词法分析器
将my_type视为标识符,而不是类型。
有关修复的想法吗?
完整代码位于:http://code.google.com/p/pycparser/source/browse/trunk/src/c_parser.py 不知道如何创建一个更小的例子。
修改
问题解决了。请参阅下面的解决方案。
答案 0 :(得分:3)
不确定为什么你在你的词法分析器中进行那种级别的分析。
词法分析应该用于将输入流分离为词汇标记(数字,换行,关键字等)。这是解析阶段,应该进行该级别的分析,包括对typedef的表查找等。
这就是我总是将lexx和yacc(我选择的工具)之间的职责分开的方式。
答案 1 :(得分:2)
来自Dave Beazley(PLY的创造者)的some help,我的问题解决了。
这个想法是使用特殊的子规则并在其中执行操作。就我而言,我将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]
在转移到SEMI之后, decl_body
总是在令牌之前减少,所以我的行动会在正确的时间执行。
答案 2 :(得分:1)
我认为您需要检查ID是否是从c_lexer.py到c_parser.py的TYPEID。
正如你所说,由于解析器正在向前看1个令牌,你无法在词法分析器中做出这个决定。
相反,更改您的解析器以检查ID以查看它们是否在声明中是TYPEID,如果不是,则生成错误。
正如Pax Diablo在他的出色回答中所说,词法分析器/分词器的工作不是做出关于令牌的那些决定。那是解析器的工作。