C++ で Flex と Bison を使用しています。両方の C バージョンでは、yylval はトークンに関する情報を格納するグローバル ユニオン変数です。
Bison C++では、yylvalはsemantic_typeと呼ばれ、クラスメンバー変数です。Flex C++ からトークンのセマンティック情報を設定するにはどうすればよいですか? Flex C++ では、lexer もクラスであり、メンバ変数として semantic_type を持ちません。
私はこのようなことをしたい:
")" { return create_token(TOK_RPAREN, yytext, start_line, start_column); }
"{" { return create_token(TOK_LBRACE, yytext, start_line, start_column); }
"}" { return create_token(TOK_RBRACE, yytext, start_line, start_column); }
[A-Za-z][A-Za-z0-9]* { return create_token(TOK_IDENTIFIER, yytext, start_line, start_column); }
[0-9]+ { return create_token(TOK_NUM, yytext, start_line, start_column); }
[ \t\n]+
"," { return create_token(TOK_COMMA, yytext, start_line, start_column); }
";" { return create_token(TOK_SEMICOLON, yytext, start_line, start_column); }
. { yyerror("Unknown character: %c\n", yytext[0]); }
%%
void lexer_set_source_file(const char *filename) {
g_srcfile = xstrdup(filename);
}
int CppLexer::create_token(yy::parseint tag, const char *lexeme, int line, int col) {
struct SourceInfo info;
info.filename = g_srcfile;
info.line = line;
info.col = col;
if (tag == TOK_NUM) {
nodeval.num_node = createNumberNode(lexeme, info);
} else if (IsOperation(tag)) {
nodeval.op_node = createOperationNode(tag, lexeme, info);
} else if (tag == TOK_IDENTIFIER) {
yylval.id_node = createIdentifierNode(lexeme, info);
} else {
nodeval.node = createCppNode(tag, lexeme, info);
}
return tag;
}")" { return create_token(TOK_RPAREN, yytext, start_line, start_column); }
"{" { return create_token(TOK_LBRACE, yytext, start_line, start_column); }
"}" { return create_token(TOK_RBRACE, yytext, start_line, start_column); }
[A-Za-z][A-Za-z0-9]* { return create_token(TOK_IDENTIFIER, yytext, start_line, start_column); }
[0-9]+ { return create_token(TOK_NUM, yytext, start_line, start_column); }
[ \t\n]+
"," { return create_token(TOK_COMMA, yytext, start_line, start_column); }
";" { return create_token(TOK_SEMICOLON, yytext, start_line, start_column); }
. { yyerror("Unknown character: %c\n", yytext[0]); }
%%
void lexer_set_source_file(const char *filename) {
g_srcfile = xstrdup(filename);
}
int CppLexer::create_token(yy::parseint tag, const char *lexeme, int line, int col) {
struct SourceInfo info;
info.filename = g_srcfile;
info.line = line;
info.col = col;
if (tag == TOK_NUM) {
nodeval.num_node = createNumberNode(lexeme, info);
} else if (IsOperation(tag)) {
nodeval.op_node = createOperationNode(tag, lexeme, info);
} else if (tag == TOK_IDENTIFIER) {
yylval.id_node = createIdentifierNode(lexeme, info);
} else {
nodeval.node = createCppNode(tag, lexeme, info);
}
return tag;
}