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); } }
のように展開される。