ready to build AST

This commit is contained in:
2024-08-08 13:05:56 +00:00
parent f1eb6abcc1
commit 9900d5aaf3
23 changed files with 683 additions and 110 deletions

View File

@ -1,3 +1,4 @@
add_subdirectory(ast)
add_subdirectory(semantic)
add_executable(code main.cpp)
target_link_libraries(code semantic argparse)

3
src/ast/CMakeLists.txt Normal file
View File

@ -0,0 +1,3 @@
include_directories(${CMAKE_SOURCE_DIR}/include/ast)
file(GLOB AST_SOURCES "*.cpp")
add_library(ast STATIC ${AST_SOURCES})

2
src/ast/astnode.cpp Normal file
View File

@ -0,0 +1,2 @@
#include "astnode.h"
#include "astnode_visitor.h"

View File

1
src/ast/expr_astnode.cpp Normal file
View File

@ -0,0 +1 @@
#include "expr_astnode.h"

View File

@ -0,0 +1 @@
#include "statement_astnode.h"

View File

@ -0,0 +1 @@
#include "structural_astnode.h"

View File

@ -21,8 +21,18 @@ int main(int argc, char **argv) {
auto input_file = program.get<std::string>("input");
auto output_file = program.get<std::string>("output");
std::ifstream fin(input_file);
int err_code = SemanticCheck(fin);
if (err_code != 0) return err_code;
std::shared_ptr<ASTNodeBase> ast;
try {
SemanticCheck(fin, ast);
} catch (const SemanticError &err) {
std::cout << err.what() << std::endl;
return err.GetErrorCode();
} catch (const std::exception &err) {
std::cout << "Unknown error: " << err.what() << std::endl;
return 254;
} catch (...) {
std::cout << "Unknown error without message" << std::endl;
return 255;
}
return 0;
}

View File

@ -1,9 +1,10 @@
include_directories(/usr/include/antlr4-runtime/)
include_directories(${CMAKE_SOURCE_DIR}/include/semantic)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/antlr-generated)
file(GLOB ANLTR_SOURCES "antlr-generated/*.cpp")
file(GLOB SEMANTIC_SOURCES "*.cpp")
add_library(mx-antlr STATIC ${ANLTR_SOURCES})
add_library(semantic STATIC ${SEMANTIC_SOURCES})
target_include_directories(semantic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/antlr-generated)
target_include_directories(semantic PUBLIC /usr/include/antlr4-runtime/)
target_link_libraries(mx-antlr PUBLIC antlr4-runtime)
target_link_libraries(semantic PUBLIC antlr4-runtime mx-antlr)
target_link_libraries(semantic PUBLIC antlr4-runtime mx-antlr ast)

View File

@ -2660,59 +2660,137 @@ MXParser::Basic_exprContext::Basic_exprContext(ParserRuleContext *parent, size_t
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* MXParser::Basic_exprContext::THIS() {
return getToken(MXParser::THIS, 0);
}
tree::TerminalNode* MXParser::Basic_exprContext::LPAREN() {
return getToken(MXParser::LPAREN, 0);
}
std::vector<MXParser::ExprContext *> MXParser::Basic_exprContext::expr() {
return getRuleContexts<MXParser::ExprContext>();
}
MXParser::ExprContext* MXParser::Basic_exprContext::expr(size_t i) {
return getRuleContext<MXParser::ExprContext>(i);
}
tree::TerminalNode* MXParser::Basic_exprContext::RPAREN() {
return getToken(MXParser::RPAREN, 0);
}
tree::TerminalNode* MXParser::Basic_exprContext::ID() {
return getToken(MXParser::ID, 0);
}
std::vector<tree::TerminalNode *> MXParser::Basic_exprContext::COMMA() {
return getTokens(MXParser::COMMA);
}
tree::TerminalNode* MXParser::Basic_exprContext::COMMA(size_t i) {
return getToken(MXParser::COMMA, i);
}
MXParser::Formatted_stringContext* MXParser::Basic_exprContext::formatted_string() {
return getRuleContext<MXParser::Formatted_stringContext>(0);
}
MXParser::ConstantContext* MXParser::Basic_exprContext::constant() {
return getRuleContext<MXParser::ConstantContext>(0);
}
size_t MXParser::Basic_exprContext::getRuleIndex() const {
return MXParser::RuleBasic_expr;
}
void MXParser::Basic_exprContext::copyFrom(Basic_exprContext *ctx) {
ParserRuleContext::copyFrom(ctx);
}
std::any MXParser::Basic_exprContext::accept(tree::ParseTreeVisitor *visitor) {
//----------------- Paren_exprContext ------------------------------------------------------------------
tree::TerminalNode* MXParser::Paren_exprContext::LPAREN() {
return getToken(MXParser::LPAREN, 0);
}
MXParser::ExprContext* MXParser::Paren_exprContext::expr() {
return getRuleContext<MXParser::ExprContext>(0);
}
tree::TerminalNode* MXParser::Paren_exprContext::RPAREN() {
return getToken(MXParser::RPAREN, 0);
}
MXParser::Paren_exprContext::Paren_exprContext(Basic_exprContext *ctx) { copyFrom(ctx); }
std::any MXParser::Paren_exprContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitBasic_expr(this);
return parserVisitor->visitParen_expr(this);
else
return visitor->visitChildren(this);
}
//----------------- Constant_exprContext ------------------------------------------------------------------
MXParser::ConstantContext* MXParser::Constant_exprContext::constant() {
return getRuleContext<MXParser::ConstantContext>(0);
}
MXParser::Constant_exprContext::Constant_exprContext(Basic_exprContext *ctx) { copyFrom(ctx); }
std::any MXParser::Constant_exprContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitConstant_expr(this);
else
return visitor->visitChildren(this);
}
//----------------- This_exprContext ------------------------------------------------------------------
tree::TerminalNode* MXParser::This_exprContext::THIS() {
return getToken(MXParser::THIS, 0);
}
MXParser::This_exprContext::This_exprContext(Basic_exprContext *ctx) { copyFrom(ctx); }
std::any MXParser::This_exprContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitThis_expr(this);
else
return visitor->visitChildren(this);
}
//----------------- Id_exprContext ------------------------------------------------------------------
tree::TerminalNode* MXParser::Id_exprContext::ID() {
return getToken(MXParser::ID, 0);
}
MXParser::Id_exprContext::Id_exprContext(Basic_exprContext *ctx) { copyFrom(ctx); }
std::any MXParser::Id_exprContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitId_expr(this);
else
return visitor->visitChildren(this);
}
//----------------- Formatted_string_exprContext ------------------------------------------------------------------
MXParser::Formatted_stringContext* MXParser::Formatted_string_exprContext::formatted_string() {
return getRuleContext<MXParser::Formatted_stringContext>(0);
}
MXParser::Formatted_string_exprContext::Formatted_string_exprContext(Basic_exprContext *ctx) { copyFrom(ctx); }
std::any MXParser::Formatted_string_exprContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitFormatted_string_expr(this);
else
return visitor->visitChildren(this);
}
//----------------- Function_call_exprContext ------------------------------------------------------------------
tree::TerminalNode* MXParser::Function_call_exprContext::ID() {
return getToken(MXParser::ID, 0);
}
tree::TerminalNode* MXParser::Function_call_exprContext::LPAREN() {
return getToken(MXParser::LPAREN, 0);
}
tree::TerminalNode* MXParser::Function_call_exprContext::RPAREN() {
return getToken(MXParser::RPAREN, 0);
}
std::vector<MXParser::ExprContext *> MXParser::Function_call_exprContext::expr() {
return getRuleContexts<MXParser::ExprContext>();
}
MXParser::ExprContext* MXParser::Function_call_exprContext::expr(size_t i) {
return getRuleContext<MXParser::ExprContext>(i);
}
std::vector<tree::TerminalNode *> MXParser::Function_call_exprContext::COMMA() {
return getTokens(MXParser::COMMA);
}
tree::TerminalNode* MXParser::Function_call_exprContext::COMMA(size_t i) {
return getToken(MXParser::COMMA, i);
}
MXParser::Function_call_exprContext::Function_call_exprContext(Basic_exprContext *ctx) { copyFrom(ctx); }
std::any MXParser::Function_call_exprContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitFunction_call_expr(this);
else
return visitor->visitChildren(this);
}
MXParser::Basic_exprContext* MXParser::basic_expr() {
Basic_exprContext *_localctx = _tracker.createInstance<Basic_exprContext>(_ctx, getState());
enterRule(_localctx, 18, MXParser::RuleBasic_expr);
@ -2730,6 +2808,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
_errHandler->sync(this);
switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 35, _ctx)) {
case 1: {
_localctx = _tracker.createInstance<MXParser::This_exprContext>(_localctx);
enterOuterAlt(_localctx, 1);
setState(306);
match(MXParser::THIS);
@ -2737,6 +2816,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
}
case 2: {
_localctx = _tracker.createInstance<MXParser::Paren_exprContext>(_localctx);
enterOuterAlt(_localctx, 2);
setState(307);
match(MXParser::LPAREN);
@ -2748,6 +2828,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
}
case 3: {
_localctx = _tracker.createInstance<MXParser::Id_exprContext>(_localctx);
enterOuterAlt(_localctx, 3);
setState(311);
match(MXParser::ID);
@ -2755,6 +2836,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
}
case 4: {
_localctx = _tracker.createInstance<MXParser::Function_call_exprContext>(_localctx);
enterOuterAlt(_localctx, 4);
setState(312);
match(MXParser::ID);
@ -2787,6 +2869,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
}
case 5: {
_localctx = _tracker.createInstance<MXParser::Formatted_string_exprContext>(_localctx);
enterOuterAlt(_localctx, 5);
setState(325);
formatted_string();
@ -2794,6 +2877,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
}
case 6: {
_localctx = _tracker.createInstance<MXParser::Constant_exprContext>(_localctx);
enterOuterAlt(_localctx, 6);
setState(326);
constant();

View File

@ -610,21 +610,76 @@ public:
class Basic_exprContext : public antlr4::ParserRuleContext {
public:
Basic_exprContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *THIS();
antlr4::tree::TerminalNode *LPAREN();
std::vector<ExprContext *> expr();
ExprContext* expr(size_t i);
antlr4::tree::TerminalNode *RPAREN();
antlr4::tree::TerminalNode *ID();
std::vector<antlr4::tree::TerminalNode *> COMMA();
antlr4::tree::TerminalNode* COMMA(size_t i);
Formatted_stringContext *formatted_string();
ConstantContext *constant();
Basic_exprContext() = default;
void copyFrom(Basic_exprContext *context);
using antlr4::ParserRuleContext::copyFrom;
virtual size_t getRuleIndex() const override;
};
class Paren_exprContext : public Basic_exprContext {
public:
Paren_exprContext(Basic_exprContext *ctx);
antlr4::tree::TerminalNode *LPAREN();
ExprContext *expr();
antlr4::tree::TerminalNode *RPAREN();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
class Constant_exprContext : public Basic_exprContext {
public:
Constant_exprContext(Basic_exprContext *ctx);
ConstantContext *constant();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
class This_exprContext : public Basic_exprContext {
public:
This_exprContext(Basic_exprContext *ctx);
antlr4::tree::TerminalNode *THIS();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
class Id_exprContext : public Basic_exprContext {
public:
Id_exprContext(Basic_exprContext *ctx);
antlr4::tree::TerminalNode *ID();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
class Formatted_string_exprContext : public Basic_exprContext {
public:
Formatted_string_exprContext(Basic_exprContext *ctx);
Formatted_stringContext *formatted_string();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
class Function_call_exprContext : public Basic_exprContext {
public:
Function_call_exprContext(Basic_exprContext *ctx);
antlr4::tree::TerminalNode *ID();
antlr4::tree::TerminalNode *LPAREN();
antlr4::tree::TerminalNode *RPAREN();
std::vector<ExprContext *> expr();
ExprContext* expr(size_t i);
std::vector<antlr4::tree::TerminalNode *> COMMA();
antlr4::tree::TerminalNode* COMMA(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
Basic_exprContext* basic_expr();

View File

@ -95,7 +95,17 @@ public:
virtual std::any visitLor_expression(MXParser::Lor_expressionContext *context) = 0;
virtual std::any visitBasic_expr(MXParser::Basic_exprContext *context) = 0;
virtual std::any visitThis_expr(MXParser::This_exprContext *context) = 0;
virtual std::any visitParen_expr(MXParser::Paren_exprContext *context) = 0;
virtual std::any visitId_expr(MXParser::Id_exprContext *context) = 0;
virtual std::any visitFunction_call_expr(MXParser::Function_call_exprContext *context) = 0;
virtual std::any visitFormatted_string_expr(MXParser::Formatted_string_exprContext *context) = 0;
virtual std::any visitConstant_expr(MXParser::Constant_exprContext *context) = 0;
virtual std::any visitFormatted_string(MXParser::Formatted_stringContext *context) = 0;

View File

@ -3,15 +3,37 @@
#include "MXLexer.h"
#include "MXParser.h"
#include "antlr4-runtime.h"
#include "ast/ast.h"
#include "visitor.h"
int SemanticCheck(std::istream &fin) {
class MXErrorListener : public antlr4::BaseErrorListener {
bool no_problem;
public:
MXErrorListener() : no_problem(true) {}
void syntaxError(antlr4::Recognizer *recognizer, antlr4::Token *offendingSymbol, size_t line,
size_t charPositionInLine, const std::string &msg, std::exception_ptr e) override {
std::cout << "line " << line << ":" << charPositionInLine << " AT "
<< offendingSymbol->getText() << ": " << msg << std::endl;
no_problem = false;
}
bool IsOk() { return no_problem; }
};
std::shared_ptr<ASTNodeBase> BuildAST(Visitor *visitor, antlr4::tree::ParseTree *tree) { ; }
std::shared_ptr<ASTNodeBase> CheckAndDecorate(std::shared_ptr<ASTNodeBase> src) { ; }
void SemanticCheck(std::istream &fin, std::shared_ptr<ASTNodeBase> &ast_out) {
antlr4::ANTLRInputStream input(fin);
MXLexer lexer(&input);
antlr4::CommonTokenStream tokens(&lexer);
tokens.fill();
MXParser parser(&tokens);
parser.removeErrorListeners();
MXErrorListener error_listener;
parser.addErrorListener(&error_listener);
antlr4::tree::ParseTree *tree = parser.mxprog();
if (!error_listener.IsOk()) throw SemanticError("Fatal error: syntax error", 1);
Visitor visitor;
visitor.visit(tree);
return 0;
std::shared_ptr<ASTNodeBase> ast = BuildAST(&visitor, tree);
ast_out = CheckAndDecorate(ast);
}

View File

@ -1,41 +1,128 @@
#include "visitor.h"
#include <stdexcept>
std::any Visitor::visitMxprog(MXParser::MxprogContext *context) {
// 空的函数体
return {};
std::any Visitor::visitMxprog(MXParser::MxprogContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitFunction_def(MXParser::Function_defContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitFunction(MXParser::FunctionContext *context) {
// 空的函数体
return {};
std::any Visitor::visitClass_def(MXParser::Class_defContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitClass_var_def(MXParser::Class_var_defContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitType(MXParser::TypeContext *context) {
// 空的函数体
return {};
std::any Visitor::visitClass_constructor(MXParser::Class_constructorContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitBlock(MXParser::BlockContext *context) {
// 空的函数体
return {};
std::any Visitor::visitSuite(MXParser::SuiteContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitEmpty_statement(MXParser::Empty_statementContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitStatement(MXParser::StatementContext *context) {
// 空的函数体
return {};
std::any Visitor::visitDefinition_statement(MXParser::Definition_statementContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitExpression(MXParser::ExpressionContext *context) {
// 空的函数体
return {};
std::any Visitor::visitExpr_statement(MXParser::Expr_statementContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitReturnStmt(MXParser::ReturnStmtContext *context) {
// 空的函数体
return {};
std::any Visitor::visitIf_statement(MXParser::If_statementContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitIfStmt(MXParser::IfStmtContext *context) {
// 空的函数体
return {};
std::any Visitor::visitWhile_statement(MXParser::While_statementContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitFor_statement(MXParser::For_statementContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitJmp_statement(MXParser::Jmp_statementContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitSuite_statement(MXParser::Suite_statementContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitDefine_statement(MXParser::Define_statementContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitGgll_expression(MXParser::Ggll_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitBxor_expression(MXParser::Bxor_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitSuffix_expression(MXParser::Suffix_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitLand_expression(MXParser::Land_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitPm_expression(MXParser::Pm_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitIndex_expression(MXParser::Index_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitOpposite_expression(MXParser::Opposite_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitNew_array_expression(MXParser::New_array_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitBasic_expression(MXParser::Basic_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitAccess_expression(MXParser::Access_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitBand_expression(MXParser::Band_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitNew_construct_expression(MXParser::New_construct_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitTernary_expression(MXParser::Ternary_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitBnot_expression(MXParser::Bnot_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitLnot_expression(MXParser::Lnot_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitPrefix_expression(MXParser::Prefix_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitRl_expression(MXParser::Rl_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitAssign_expression(MXParser::Assign_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitMdm_expression(MXParser::Mdm_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitNew_expression(MXParser::New_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitNe_expression(MXParser::Ne_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitBor_expression(MXParser::Bor_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitLor_expression(MXParser::Lor_expressionContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitThis_expr(MXParser::This_exprContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitParen_expr(MXParser::Paren_exprContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitId_expr(MXParser::Id_exprContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitFunction_call_expr(MXParser::Function_call_exprContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitFormatted_string_expr(MXParser::Formatted_string_exprContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitConstant_expr(MXParser::Constant_exprContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitFormatted_string(MXParser::Formatted_stringContext *context) {
throw std::runtime_error("Not implemented");
}
std::any Visitor::visitConstant(MXParser::ConstantContext *context) { throw std::runtime_error("Not implemented"); }
std::any Visitor::visitType(MXParser::TypeContext *context) { throw std::runtime_error("Not implemented"); }