0

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

0 に答える 0