我在 C++ 中使用 Flex 和 Bison。在两者的 C 版本中,yylval 是一个全局联合变量,用于存储有关令牌的信息。
在 Bison C++ 中,yylval 被称为语义类型,它是一个类成员变量。如何为 Flex C++ 中的标记设置语义信息?在 Flex C++ 中,词法分析器也是一个类,它没有语义类型作为成员变量。
我想做这样的事情:
")" { 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;
}