3

我正在使用 PLY 编写一个 C 解析器,最近遇到了一个问题。这段代码:

typedef int my_type;
my_type x;

是正确的 C 代码,因为 my_type 被定义为之前使用的类型。我通过在解析器中填充类型符号表来处理它,词法分析器使用该表来区分类型和简单标识符。

但是,虽然类型声明规则以 SEMI(';' 标记)结尾,但 PLYmy_type在决定使用第一行完成之前将标记从第二行转移。因此,我没有机会将类型符号表中的更新传递给词法分析器,它会将 my_type 视为标识符而不是类型。

任何修复的想法?

完整代码位于:http ://code.google.com/p/pycparser/source/browse/trunk/src/c_parser.py 不知道如何从中创建一个更小的示例。

编辑:

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

4

3 回答 3

3

不确定为什么要在词法分析器中进行这种级别的分析。

可能应该使用词法分析将输入流分离为词法标记(数字、换行、关键字等)。解析阶段应该进行该级别的分析,包括 typedef 的表查找等。

这就是我一直在 lexx 和 yacc 之间划分职责的方式,这是我选择的工具。

于 2008-09-20T12:47:23.487 回答
2

在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 移入后,总是在令牌之前减少,因此我的操作会在正确的时间执行。

于 2008-09-20T15:28:02.633 回答
1

我认为您需要将检查 ID 是否为 TYPEID 从 c_lexer.py 移动到 c_parser.py。

正如您所说,由于解析器正在查看 1 个标记,因此您无法在词法分析器中做出该决定。

相反,更改您的解析器以检查 ID 以查看它们是否是声明中的 TYPEID,如果不是,则生成错误。

正如 Pax Diablo 在他出色的回答中所说,词法分析器/标记器的工作不是做出关于标记的那些决定。这就是解析器的工作。

于 2008-09-20T12:31:30.733 回答