0

我在 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;
}
4

0 回答 0