如果前瞻标记是给定值,有没有办法指定Bison规则不匹配?
我目前有以下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)并推断它必须是函数调用而不是函数声明。 有没有办法可以告诉Bison它应该支持展望未来匹配var_decl而不是将* ident和void减少为derefs和exprs?
答案 0 :(得分:3)
任何标识符都可以是类型
这正是问题所在。 LALR(1)类似C语言的语法(或类型为C语言的语言)需要在令牌级别区分类型和其他标识符。也就是说,你需要IDENT和TYPEIDENT是两个不同的标记。 (您必须将有关标识符的数据从编译器提供回令牌器)。这是消除模糊语法歧义的最标准方法。
更新例如,请参阅this ANSI C grammar for Yacc。