【问题标题】:handing lists of variable names in bison/yacc处理 bison/yacc 中的变量名列表
【发布时间】:2013-04-16 04:37:19
【问题描述】:

我无法弄清楚如何使用 bison 编写解析器。

为了将变量插入到我的符号表中,以便我可以进行一些类型检查和其他废话,我需要变量名称和类型。

我特别关注以下几行:

%union {tokentype token;
        char *type;
        sPtr names; //stack pointer
       }
<%token definitions>
%token <token> ID ICONST
%type <type> stype type
%type <names> IDlist

vardcl          : IDlist ':' type
                ;

IDlist          : IDlist ',' ID
                | ID
                ;

type            : ARRAY '[' integer_constant RANGE integer_constant ']' OF stype { $$ = $8 }
                | stype { $$ = $1 }
                ;

stype           : INT { $$ = "INT" }
                | BOOLEAN { $$ = "BOOLEAN" }
                ;

如果我的语法是这样的:

vardcl          : ID ':' type
                ;

我可以这样做:

vardcl          : ID ':' type { SymbolTableInsert($1, $3); }
                ;

但是我的语法看起来是这样的:

vardcl          : IDlist ':' type
                ;

IDlist          : IDlist ',' ID
                | ID
                ;

所以我试图将每个 ID 放入一个数据结构中(我已经为符号表使用了一个堆栈,所以我想我也可以使用它)但是我不断收到关于 $arguments 类型的不兼容错误和我也不确定我是否在推动我需要的一切:

IDlist          : IDlist ',' ID { $$ = SCreate(CompareStrings); SPush($$, $3); }
                | ID { $$ = SCreate(CompareStrings); SPush($$, $1);
                ;

我收到错误“SPush 的参数 2 的类型不兼容,预期 void * 不是 tokentype”。尝试将内容插入符号表时,我也会遇到同样的错误。

有什么好的方法可以做到这一点?

提前感谢您的帮助。

【问题讨论】:

    标签: c parsing attributes bison yacc


    【解决方案1】:

    在语法方面,一切看起来都不错。看起来您的问题实际上是 C 的问题:检查您的 SPush 函数的签名,它似乎是一个函数,其第二个参数是 void*,而不是 tokentype(这是 @987654324 的声明类型@)。

    【讨论】:

    • 除此之外,我怀疑tokentypeenum 并且标识符本身没有从标记器传递到解析器。
    • 我故意对堆栈进行编码以接受 void* 对象,以便我可以插入任何数据类型。事实上,我在我的符号表中广泛使用它,所以我不能简单地将它切换到 tokentype。不过,我会进一步研究枚举业务,谢谢。
    • 我通过创建一个新函数 SPushT 解决了这个问题,该函数专门接受 tokentype 对象。这似乎有点骇人听闻,它会从不兼容的指针类型警告中产生一堆赋值,但它确实有效。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多