野牛拾取 C 函数指针作为函数调用

Bison picking up C function pointer as a function call?

本文关键字:指针 函数调用 函数      更新时间:2023-10-16

有没有办法指定如果前瞻令牌是给定值,Bison规则不应匹配?

我目前有以下野牛语法(简化):

var_decl:
        type ident
        {
            $$ = new NVariableDeclaration(*$1, *$2);
        } |
        type ident ASSIGN_EQUAL expr
        {
            $$ = new NVariableDeclaration(*$1, *$2, $4);
        } |
        type CURVED_OPEN STAR ident CURVED_CLOSE CURVED_OPEN func_decl_args CURVED_CLOSE
        {
            $$ = new NVariableDeclaration(*(new NFunctionPointerType(*$1, *$7)) /* TODO: free this memory */, *$4);
        } |
        type CURVED_OPEN STAR ident CURVED_CLOSE CURVED_OPEN func_decl_args CURVED_CLOSE ASSIGN_EQUAL expr
        {
            $$ = new NVariableDeclaration(*(new NFunctionPointerType(*$1, *$7)) /* TODO: free this memory */, *$4, $10);
        } ;
...
deref:
        STAR ident
        {
            $$ = new NDereferenceOperator(*$<ident>2);
        } |
...
type:
        ident
        {
            $$ = new NType($<type>1->name, 0, false);
            delete $1;
        } |
        ... ;
...
expr:
        deref
        {
            $$ = $1;
        } |
        ...
        ident
        {
            $<ident>$ = $1;
        } |
        ...
        ident CURVED_OPEN call_args CURVED_CLOSE
        {
            $$ = new NMethodCall(*$1, *$3);
            delete $3;
        } |
        ...
        CURVED_OPEN expr CURVED_CLOSE
        {
            $$ = $2;
        } ;
...
call_args:
        /* empty */
        {
            $$ = new ExpressionList();
        } |
        expr
        {
            $$ = new ExpressionList();
            $$->push_back($1);
        } |
        call_args COMMA expr
        {
            $1->push_back($3);
        } ;

问题是在解析时:

void (*ident)(char* some_arg);

它看到 void (*ident) 并推断它一定是函数调用而不是函数声明。 有没有办法告诉野牛,它应该倾向于向前看以匹配var_decl,而不是将 *识别和无效减少为 deref 和 exprs?

任何标识符都可以是类型

这正是问题所在。类 C 语言的 LALR(1) 语法(或类型类语法的语言)需要在令牌级别区分类型和其他标识符。也就是说,您需要 IDENT 和 TYPEIDENT 是两个不同的令牌。(您必须将有关标识符的数据从编译器反馈回分词器)。这是消除歧义的最标准方法,否则模棱两可的语法。

更新 例如,请参阅Yacc的ANSI C语法。