使用 Bison 进行解析:实际构造函数

Parsing with Bison: constructor in action

我正在尝试用 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(); }
    | ACCIDENTAL NUMERAL { $$ = Roman(, ); }
    ;

我基本上有三个相关的问题。

  1. %union 真正代表什么?我认为它代表了词法分析器可以 return 的类型。我的词法分析器规则包含类似 return STAFFTYPE 的语句,以指示我已使用 Staff 对象填充 yylval.stafftype。很公平。然而;
  2. 联合似乎也与语法动作中的$$ =语句有关。为什么语法动作的结果类型需要在联合中?
  3. 在我的示例中,Roman class 有一个带参数的构造函数。但是,联合中的声明会导致错误 no matching function for call to 'Roman::Roman()'。有没有办法解决?我正在尝试用 $$ = 构建一个解析树,树中的节点肯定需要在它们的构造函数中使用参数。事实上,它甚至不允许 0 参数构造函数:error: union member 'YYSTYPE::roman' with non-trivial 'Roman::Roman().
  1. What does the %union really represent? I thought it represented types the lexer could return.

没有。它表示 productions 可以通过 $$ = return 的类型。词法分析器只是通过 %token 指令定义的 returns 整数常量。作为副作用,词法分析器可以填充 yylval 成员 但它在任何意义上都不是 return 类型的词法分析器。

My lexer rules contain statements like return STAFFTYPE, to indicate that I have populated yylval.stafftype with a Staff object.

他们不应该。它们应该 return 语法中使用的标记类型,并且通常不应该将任何内容放入 yylval 中,除非是文字。您正在词法分析器中执行解析器应该执行的工作。

  1. the union also seems to have something to do with the $$ = statements in the grammar actions. Why do the result types of grammar actions need to be in the union?

因为那是放置它们的地方。在 yylval 个值的堆栈之上。

  1. In my example, the Roman class has a constructor with parameters. However, declaration in the union causes the error no matching function for call to 'Roman::Roman()'. Is there any way around this? I'm trying to build up a parse tree with $$ =, and the nodes in the tree definitely need parameters in their constructors. In fact, it doesn't even allow a 0-parameter constructor: error: union member YYSTYPE::roman with non-trivial Roman::Roman().

一般来说,%union 应该由整数、双精度数、其他基本类型和 指针组成。 联合中的对象无论如何都是有问题的,并且在解析器堆栈上是主要是 space.

的巨大浪费