我正在尝试用Bison构建一个解析器。我在第一部分中有以下内容:
%union {
int ttype;
// enums used in lexer
Staff stafftype;
Numeral numeral;
Quality quality;
Inversion inversion;
Pitch pitch;
Accidental accidental;
// Classes used in parser
Roman roman;
}
%token <stafftype> STAFFTYPE
%token <numeral> NUMERAL
%token <quality> QUALITY
%token <inversion> INVERSION
%token <pitch> PITCH
%token <accidental> ACCIDENTAL
%token <ttype> COLON
%token <ttype> SLASH
%token <ttype> COMMA
%type <roman> accidentalRoman
有一些语法规则。这是一个:
accidentalRoman
: NUMERAL { $$ = Roman($1); }
| ACCIDENTAL NUMERAL { $$ = Roman($2, $1); }
;
我基本上有三个相关的问题。
return STAFFTYPE
之类的语句,表示我已使用yylval.stafftype
对象填充Staff
。很公平。然而; $$ =
语句有关。为什么结语类型的语法动作需要在联合中?Roman
类有一个带参数的构造函数。但是,联合中的声明会导致错误no matching function for call to 'Roman::Roman()'
。有没有办法解决?我正在尝试使用$$ =
构建一个解析树,并且树中的节点肯定需要在其构造函数中使用参数。实际上,它甚至不允许使用0参数构造函数:error: union member 'YYSTYPE::roman' with non-trivial 'Roman::Roman().
答案 0 :(得分:1)
- 醇>
%union
真正代表什么?我认为它代表了词法分析者可以返回的类型。
没有。它表示制作可以通过$$ =
返回的类型。词法分析器只返回通过%token
指令定义的整数常量。词法分析器可以填充yylval
成员作为副作用,但它在任何意义上都不是词法分析器的返回类型。
我的词法规则包含返回STAFFTYPE等语句,表示我已使用Staff对象填充了yylval.stafftype。
他们不应该。它们应该返回语法中使用的标记类型,除了文字之外,通常不应该将任何内容放入yylval
。你正在使用解析器应该做的词法分析器。
- 联盟似乎也与语法行为中的
醇>$$ = statements
有关。为什么结语类型的语法动作需要在联合中?
因为这就是他们所在的位置。在yylval
值的堆栈之上。
- 在我的示例中,Roman类有一个带参数的构造函数。但是,union中的声明会导致错误没有匹配函数来调用'Roman :: Roman()'。有没有办法解决?我正在尝试使用
醇>$$ =
构建一个解析树,并且树中的节点肯定需要在其构造函数中使用参数。实际上,它甚至不允许使用0参数构造函数:error:union memberYYSTYPE::roman
with notvvialRoman::Roman()
。
一般来说,%union
应该包含整数,双精度数,其他基本类型和指针。联合中的对象无论如何都是有问题的,并且在解析器堆栈上大多浪费空间。