用Bison解析:构造函数在行动中

时间:2017-08-17 05:37:46

标签: c++ parsing bison flex-lexer

我正在尝试用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); }
    ;

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

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

1 个答案:

答案 0 :(得分:1)

  
      
  1. %union真正代表什么?我认为它代表了词法分析者可以返回的类型。
  2.   

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

  

我的词法规则包含返回STAFFTYPE等语句,表示我已使用Staff对象填充了yylval.stafftype。

他们不应该。它们应该返回语法中使用的标记类型,除了文字之外,通常不应该将任何内容放入yylval。你正在使用解析器应该做的词法分析器。

  
      
  1. 联盟似乎也与语法行为中的$$ = statements有关。为什么结语类型的语法动作需要在联合中?
  2.   

因为这就是他们所在的位置。在yylval值的堆栈之上。

  
      
  1. 在我的示例中,Roman类有一个带参数的构造函数。但是,union中的声明会导致错误没有匹配函数来调用'Roman :: Roman()'。有没有办法解决?我正在尝试使用$$ =构建一个解析树,并且树中的节点肯定需要在其构造函数中使用参数。实际上,它甚至不允许使用0参数构造函数:error:union member YYSTYPE::roman with notvvial Roman::Roman()
  2.   

一般来说,%union应该包含整数,双精度数,其他基本类型和指针。联合中的对象无论如何都是有问题的,并且在解析器堆栈上大多浪费空间。