PLY:C解析器中的令牌转移问题

时间:2008-09-20 12:14:41

标签: python parsing yacc ply

我正在使用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 不知道如何创建一个更小的例子。

修改

问题解决了。请参阅下面的解决方案。

3 个答案:

答案 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在他的出色回答中所说,词法分析器/分词器的工作不是做出关于令牌的那些决定。那是解析器的工作。