yacc(bison) の %union と %type

yacc(bison)の %union と %typeについてのメモです。

%skeleton "lalr1.cc"

%define "parser_class_name" "script_parser"

としてます。

%unionはyacc(bison)にかませるparser.yyでは以下のように指定する。

%union {
int ival;
std::string* sval;
CStatement* statement;
CAssign* assign;
CNode* expr;
}

この記述は、bisonにかませることで生成されるparser.hh内で以下の様に展開される。

class script_parser {

//略

 union semantic_type {
  int ival;
  std::string* sval;

  CStatement* statement;
  CAssign* assign;
  CNode* node;
 };

//略

};

%type宣言は

%type <node> expr

のように宣言し、下のような意味を持つ。

%type 変数名 非終端記号

%unionで宣言したものは、スキャナから値を受け取る場合に
bison内部で使われる変数の型になる。
終端記号、非終端記号の情報がこの%unionでつくった型の変数に格納され、
%type宣言との対応で、どの変数を使うかが決定される。



具体的には、parser.yy内で以下の様に書いたとすると、

expr : expr '+' expr { $$ = new CNode('+', $1, $3);}

parser.cc内では

script_parser::parse()
{
// 略

// $$
semantic_type yyval;

// 略

// yysemantic_stack_ は名前の通り、semantic_typeのスタック
{yyval.node = new CNode('+', yysemantic_stack_[(3) - (1)].node, yysemantic_stack_[(5) - (1)].node); }
}

のように展開される。