ready to build AST
This commit is contained in:
@ -52,12 +52,12 @@ expr
|
|||||||
;
|
;
|
||||||
|
|
||||||
basic_expr
|
basic_expr
|
||||||
: THIS
|
: THIS #this_expr
|
||||||
| LPAREN expr RPAREN
|
| LPAREN expr RPAREN #paren_expr
|
||||||
| ID
|
| ID #id_expr
|
||||||
| ID LPAREN (expr (COMMA expr)*)? RPAREN
|
| ID LPAREN (expr (COMMA expr)*)? RPAREN #function_call_expr
|
||||||
| formatted_string
|
| formatted_string #formatted_string_expr
|
||||||
| constant
|
| constant #constant_expr
|
||||||
;
|
;
|
||||||
|
|
||||||
formatted_string : FORMAT_STRING_WHOLE | (FORMAT_STRING_HEAD expr (FORMAT_STRING_BODY expr)*? FORMAT_STRING_TAIL);
|
formatted_string : FORMAT_STRING_WHOLE | (FORMAT_STRING_HEAD expr (FORMAT_STRING_BODY expr)*? FORMAT_STRING_TAIL);
|
||||||
|
8
include/ast/ast.h
Normal file
8
include/ast/ast.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef AST_H
|
||||||
|
#define AST_H
|
||||||
|
#include "astnode.h"
|
||||||
|
#include "astnode_visitor.h"
|
||||||
|
#include "expr_astnode.h"
|
||||||
|
#include "statement_astnode.h"
|
||||||
|
#include "structural_astnode.h"
|
||||||
|
#endif // AST_H
|
31
include/ast/astnode.h
Normal file
31
include/ast/astnode.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef ASTNODE_H
|
||||||
|
#define ASTNODE_H
|
||||||
|
#include <memory>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
using IdentifierType = std::string;
|
||||||
|
struct ArrayType {
|
||||||
|
bool has_base_type;
|
||||||
|
IdentifierType basetype;
|
||||||
|
size_t level;
|
||||||
|
};
|
||||||
|
using ExprTypeInfo = std::variant<IdentifierType, ArrayType>;
|
||||||
|
class ASTNodeVisitorBase {
|
||||||
|
public:
|
||||||
|
virtual ~ASTNodeVisitorBase() = default;
|
||||||
|
virtual void visit(class ASTNodeBase *context) = 0;
|
||||||
|
};
|
||||||
|
enum class ASTNodeType {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ASTNodeBase {
|
||||||
|
ASTNodeType type;
|
||||||
|
// std::vector<std::shared_ptr<ASTNodeBase>> children;
|
||||||
|
size_t start_line, start_char_pos, end_line, end_char_pos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~ASTNodeBase() = default;
|
||||||
|
virtual void accept(class ASTNodeVisitorBase *visitor) = 0;
|
||||||
|
};
|
||||||
|
#endif
|
6
include/ast/astnode_visitor.h
Normal file
6
include/ast/astnode_visitor.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef ASTNODE_VISITOR_H
|
||||||
|
#define ASTNODE_VISITOR_H
|
||||||
|
#include "astnode.h"
|
||||||
|
#include "expr_astnode.h"
|
||||||
|
class ASTNodeVisitor : public ASTNodeVisitorBase {};
|
||||||
|
#endif
|
126
include/ast/expr_astnode.h
Normal file
126
include/ast/expr_astnode.h
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#ifndef EXPR_ASTNODE_H
|
||||||
|
#define EXPR_ASTNODE_H
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include "astnode.h"
|
||||||
|
|
||||||
|
class Expr_ASTNode : public ASTNodeBase {
|
||||||
|
ExprTypeInfo expr_type_info;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~Expr_ASTNode() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BasicExpr_ASTNode : public Expr_ASTNode {}; // This is a virtual class
|
||||||
|
class NewArrayExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
bool has_initial_value;
|
||||||
|
std::shared_ptr<class ConstantExpr_ASTNode> initial_value;
|
||||||
|
};
|
||||||
|
class NewConstructExpr_ASTNode : public Expr_ASTNode {};
|
||||||
|
class NewExpr_ASTNode : public Expr_ASTNode {};
|
||||||
|
class AccessExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> base;
|
||||||
|
IdentifierType member;
|
||||||
|
};
|
||||||
|
class MemberVariableAccessExpr_ASTNode : public AccessExpr_ASTNode {};
|
||||||
|
class MemberFunctionAccessExpr_ASTNode : public AccessExpr_ASTNode {
|
||||||
|
std::vector<std::shared_ptr<Expr_ASTNode>> arguments;
|
||||||
|
};
|
||||||
|
class IndexExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> base;
|
||||||
|
std::vector<std::shared_ptr<Expr_ASTNode>> indices;
|
||||||
|
};
|
||||||
|
class SuffixExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> base;
|
||||||
|
};
|
||||||
|
class PrefixExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> base;
|
||||||
|
};
|
||||||
|
class OppositeExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> base;
|
||||||
|
};
|
||||||
|
class LNotExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class BNotExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class MDMExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class PMExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class RLExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class GGLLExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class NEExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class BAndExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class BXorExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class BOrExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class LAndExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class LOrExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> left;
|
||||||
|
std::shared_ptr<Expr_ASTNode> right;
|
||||||
|
};
|
||||||
|
class TernaryExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> condition;
|
||||||
|
std::shared_ptr<Expr_ASTNode> src1;
|
||||||
|
std::shared_ptr<Expr_ASTNode> src2;
|
||||||
|
};
|
||||||
|
class AssignExpr_ASTNode : public Expr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> dest;
|
||||||
|
std::shared_ptr<Expr_ASTNode> src;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThisExpr_ASTNode : public BasicExpr_ASTNode {};
|
||||||
|
class ParenExpr_ASTNode : public BasicExpr_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> expr;
|
||||||
|
};
|
||||||
|
class IDExpr_ASTNode : public BasicExpr_ASTNode {
|
||||||
|
IdentifierType id;
|
||||||
|
};
|
||||||
|
class FunctionCallExpr_ASTNode : public BasicExpr_ASTNode {
|
||||||
|
IdentifierType func_name;
|
||||||
|
std::vector<std::shared_ptr<Expr_ASTNode>> arguments;
|
||||||
|
};
|
||||||
|
class FormattedStringExpr_ASTNode : public BasicExpr_ASTNode {
|
||||||
|
using SegmentType = std::variant<std::string, std::shared_ptr<Expr_ASTNode>>;
|
||||||
|
std::vector<SegmentType> segments;
|
||||||
|
};
|
||||||
|
struct NullType {};
|
||||||
|
using AtomicConstantType = std::variant<uint32_t, bool, std::string, NullType>;
|
||||||
|
struct ArrayConstantType {
|
||||||
|
std::vector<std::variant<std::shared_ptr<ArrayConstantType>, NullType, AtomicConstantType>> elements;
|
||||||
|
size_t level;
|
||||||
|
};
|
||||||
|
class ConstantExpr_ASTNode : public BasicExpr_ASTNode {
|
||||||
|
std::variant<AtomicConstantType, ArrayConstantType> value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EXPR_ASTNODE_H
|
42
include/ast/statement_astnode.h
Normal file
42
include/ast/statement_astnode.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef STATEMENT_ASTNODE_H
|
||||||
|
#define STATEMENT_ASTNODE_H
|
||||||
|
#include <vector>
|
||||||
|
#include "astnode.h"
|
||||||
|
#include "expr_astnode.h"
|
||||||
|
class Statement_ASTNode : public ASTNodeBase {
|
||||||
|
public:
|
||||||
|
virtual ~Statement_ASTNode() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EmptyStatement_ASTNode : public Statement_ASTNode {};
|
||||||
|
class DefinitionStatement_ASTNode : public Statement_ASTNode {
|
||||||
|
ExprTypeInfo type;
|
||||||
|
std::vector<std::pair<IdentifierType, std::shared_ptr<Expr_ASTNode>>> vars;
|
||||||
|
};
|
||||||
|
class ExprStatement_ASTNode : public Statement_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> expr;
|
||||||
|
};
|
||||||
|
class IfStatement_ASTNode : public Statement_ASTNode {
|
||||||
|
bool has_else_clause;
|
||||||
|
std::shared_ptr<Expr_ASTNode> condition;
|
||||||
|
std::shared_ptr<Statement_ASTNode> if_clause;
|
||||||
|
std::shared_ptr<Statement_ASTNode> else_clause;
|
||||||
|
};
|
||||||
|
class WhileStatement_ASTNode : public Statement_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> condition;
|
||||||
|
std::shared_ptr<Statement_ASTNode> loop_body;
|
||||||
|
};
|
||||||
|
class ForStatement_ASTNode : public Statement_ASTNode {
|
||||||
|
std::shared_ptr<Statement_ASTNode> initial;
|
||||||
|
std::shared_ptr<Expr_ASTNode> condition;
|
||||||
|
std::shared_ptr<Statement_ASTNode> update;
|
||||||
|
std::shared_ptr<Statement_ASTNode> loop_body;
|
||||||
|
};
|
||||||
|
class JmpStatement_ASTNode : public Statement_ASTNode {
|
||||||
|
std::shared_ptr<Expr_ASTNode> return_value;
|
||||||
|
};
|
||||||
|
class SuiteStatement_ASTNode : public Statement_ASTNode {
|
||||||
|
std::vector<std::shared_ptr<Statement_ASTNode>> statements;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STATEMENT_ASTNODE_H
|
27
include/ast/structural_astnode.h
Normal file
27
include/ast/structural_astnode.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef STRUCTURAL_ASTNODE_H
|
||||||
|
#define STRUCTURAL_ASTNODE_H
|
||||||
|
#include <memory>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
#include "astnode.h"
|
||||||
|
#include "expr_astnode.h"
|
||||||
|
#include "statement_astnode.h"
|
||||||
|
class FuncDef_ASTNode : public ASTNodeBase {
|
||||||
|
IdentifierType func_name;
|
||||||
|
std::vector<std::pair<IdentifierType, ExprTypeInfo>> params;
|
||||||
|
std::shared_ptr<SuiteStatement_ASTNode> func_body;
|
||||||
|
};
|
||||||
|
class Constructor_ASTNode : public FuncDef_ASTNode {};
|
||||||
|
class ClassVariable_ASTNode : public DefinitionStatement_ASTNode {};
|
||||||
|
class ClassDef_ASTNode : public ASTNodeBase {
|
||||||
|
private:
|
||||||
|
using ClassElement = std::variant<std::shared_ptr<Constructor_ASTNode>, std::shared_ptr<ClassVariable_ASTNode>,
|
||||||
|
std::shared_ptr<FuncDef_ASTNode>>;
|
||||||
|
std::vector<ClassElement> elements;
|
||||||
|
};
|
||||||
|
class Program_ASTNode : public ASTNodeBase {
|
||||||
|
using ProgramElement = std::variant<std::shared_ptr<FuncDef_ASTNode>, std::shared_ptr<ClassDef_ASTNode>,
|
||||||
|
std::shared_ptr<DefinitionStatement_ASTNode>>;
|
||||||
|
std::vector<ProgramElement> elements;
|
||||||
|
};
|
||||||
|
#endif
|
@ -1,5 +1,18 @@
|
|||||||
#ifndef SEMANTIC_H
|
#ifndef SEMANTIC_H
|
||||||
#define SEMANTIC_H
|
#define SEMANTIC_H
|
||||||
#include <ios>
|
#include <ios>
|
||||||
int SemanticCheck(std::istream &fin);
|
#include "ast/ast.h"
|
||||||
|
#include "visitor.h"
|
||||||
|
|
||||||
|
class SemanticError : public std::exception {
|
||||||
|
std::string msg;
|
||||||
|
int error_code;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SemanticError(const std::string &msg, int error_code) : msg(msg), error_code(error_code) {}
|
||||||
|
const char *what() const noexcept override { return msg.c_str(); }
|
||||||
|
int GetErrorCode() const { return error_code; }
|
||||||
|
};
|
||||||
|
std::shared_ptr<ASTNodeBase> BuildAST(Visitor *visitor, antlr4::tree::ParseTree *tree);
|
||||||
|
void SemanticCheck(std::istream &fin, std::shared_ptr<ASTNodeBase> &ast);
|
||||||
#endif
|
#endif
|
@ -1,15 +1,57 @@
|
|||||||
#ifndef VISITOR_H
|
#ifndef VISITOR_H
|
||||||
#define VISITOR_H
|
#define VISITOR_H
|
||||||
|
|
||||||
#include "MXParserVisitor.h"
|
#include "MXParserVisitor.h"
|
||||||
|
|
||||||
class Visitor : public MXParserVisitor {
|
class Visitor : public MXParserVisitor {
|
||||||
public:
|
public:
|
||||||
virtual std::any visitMxprog(MXParser::MxprogContext *context);
|
std::any visitMxprog(MXParser::MxprogContext *context) override;
|
||||||
virtual std::any visitFunction(MXParser::FunctionContext *context);
|
std::any visitFunction_def(MXParser::Function_defContext *context) override;
|
||||||
virtual std::any visitType(MXParser::TypeContext *context);
|
std::any visitClass_def(MXParser::Class_defContext *context) override;
|
||||||
virtual std::any visitBlock(MXParser::BlockContext *context);
|
std::any visitClass_var_def(MXParser::Class_var_defContext *context) override;
|
||||||
virtual std::any visitStatement(MXParser::StatementContext *context);
|
std::any visitClass_constructor(MXParser::Class_constructorContext *context) override;
|
||||||
virtual std::any visitExpression(MXParser::ExpressionContext *context);
|
std::any visitSuite(MXParser::SuiteContext *context) override;
|
||||||
virtual std::any visitReturnStmt(MXParser::ReturnStmtContext *context);
|
std::any visitEmpty_statement(MXParser::Empty_statementContext *context) override;
|
||||||
virtual std::any visitIfStmt(MXParser::IfStmtContext *context);
|
std::any visitDefinition_statement(MXParser::Definition_statementContext *context) override;
|
||||||
|
std::any visitExpr_statement(MXParser::Expr_statementContext *context) override;
|
||||||
|
std::any visitIf_statement(MXParser::If_statementContext *context) override;
|
||||||
|
std::any visitWhile_statement(MXParser::While_statementContext *context) override;
|
||||||
|
std::any visitFor_statement(MXParser::For_statementContext *context) override;
|
||||||
|
std::any visitJmp_statement(MXParser::Jmp_statementContext *context) override;
|
||||||
|
std::any visitSuite_statement(MXParser::Suite_statementContext *context) override;
|
||||||
|
std::any visitDefine_statement(MXParser::Define_statementContext *context) override;
|
||||||
|
std::any visitGgll_expression(MXParser::Ggll_expressionContext *context) override;
|
||||||
|
std::any visitBxor_expression(MXParser::Bxor_expressionContext *context) override;
|
||||||
|
std::any visitSuffix_expression(MXParser::Suffix_expressionContext *context) override;
|
||||||
|
std::any visitLand_expression(MXParser::Land_expressionContext *context) override;
|
||||||
|
std::any visitPm_expression(MXParser::Pm_expressionContext *context) override;
|
||||||
|
std::any visitIndex_expression(MXParser::Index_expressionContext *context) override;
|
||||||
|
std::any visitOpposite_expression(MXParser::Opposite_expressionContext *context) override;
|
||||||
|
std::any visitNew_array_expression(MXParser::New_array_expressionContext *context) override;
|
||||||
|
std::any visitBasic_expression(MXParser::Basic_expressionContext *context) override;
|
||||||
|
std::any visitAccess_expression(MXParser::Access_expressionContext *context) override;
|
||||||
|
std::any visitBand_expression(MXParser::Band_expressionContext *context) override;
|
||||||
|
std::any visitNew_construct_expression(MXParser::New_construct_expressionContext *context) override;
|
||||||
|
std::any visitTernary_expression(MXParser::Ternary_expressionContext *context) override;
|
||||||
|
std::any visitBnot_expression(MXParser::Bnot_expressionContext *context) override;
|
||||||
|
std::any visitLnot_expression(MXParser::Lnot_expressionContext *context) override;
|
||||||
|
std::any visitPrefix_expression(MXParser::Prefix_expressionContext *context) override;
|
||||||
|
std::any visitRl_expression(MXParser::Rl_expressionContext *context) override;
|
||||||
|
std::any visitAssign_expression(MXParser::Assign_expressionContext *context) override;
|
||||||
|
std::any visitMdm_expression(MXParser::Mdm_expressionContext *context) override;
|
||||||
|
std::any visitNew_expression(MXParser::New_expressionContext *context) override;
|
||||||
|
std::any visitNe_expression(MXParser::Ne_expressionContext *context) override;
|
||||||
|
std::any visitBor_expression(MXParser::Bor_expressionContext *context) override;
|
||||||
|
std::any visitLor_expression(MXParser::Lor_expressionContext *context) override;
|
||||||
|
std::any visitThis_expr(MXParser::This_exprContext *context) override;
|
||||||
|
std::any visitParen_expr(MXParser::Paren_exprContext *context) override;
|
||||||
|
std::any visitId_expr(MXParser::Id_exprContext *context) override;
|
||||||
|
std::any visitFunction_call_expr(MXParser::Function_call_exprContext *context) override;
|
||||||
|
std::any visitFormatted_string_expr(MXParser::Formatted_string_exprContext *context) override;
|
||||||
|
std::any visitConstant_expr(MXParser::Constant_exprContext *context) override;
|
||||||
|
std::any visitFormatted_string(MXParser::Formatted_stringContext *context) override;
|
||||||
|
std::any visitConstant(MXParser::ConstantContext *context) override;
|
||||||
|
std::any visitType(MXParser::TypeContext *context) override;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
#endif // VISITOR_H
|
@ -1,3 +1,4 @@
|
|||||||
|
add_subdirectory(ast)
|
||||||
add_subdirectory(semantic)
|
add_subdirectory(semantic)
|
||||||
add_executable(code main.cpp)
|
add_executable(code main.cpp)
|
||||||
target_link_libraries(code semantic argparse)
|
target_link_libraries(code semantic argparse)
|
||||||
|
3
src/ast/CMakeLists.txt
Normal file
3
src/ast/CMakeLists.txt
Normal 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
2
src/ast/astnode.cpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#include "astnode.h"
|
||||||
|
#include "astnode_visitor.h"
|
0
src/ast/astnode_visitor.cpp
Normal file
0
src/ast/astnode_visitor.cpp
Normal file
1
src/ast/expr_astnode.cpp
Normal file
1
src/ast/expr_astnode.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "expr_astnode.h"
|
1
src/ast/statement_astnode.cpp
Normal file
1
src/ast/statement_astnode.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "statement_astnode.h"
|
1
src/ast/structural_astnode.cpp
Normal file
1
src/ast/structural_astnode.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "structural_astnode.h"
|
16
src/main.cpp
16
src/main.cpp
@ -21,8 +21,18 @@ int main(int argc, char **argv) {
|
|||||||
auto input_file = program.get<std::string>("input");
|
auto input_file = program.get<std::string>("input");
|
||||||
auto output_file = program.get<std::string>("output");
|
auto output_file = program.get<std::string>("output");
|
||||||
std::ifstream fin(input_file);
|
std::ifstream fin(input_file);
|
||||||
int err_code = SemanticCheck(fin);
|
std::shared_ptr<ASTNodeBase> ast;
|
||||||
if (err_code != 0) return err_code;
|
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;
|
return 0;
|
||||||
}
|
}
|
@ -1,9 +1,10 @@
|
|||||||
include_directories(/usr/include/antlr4-runtime/)
|
include_directories(/usr/include/antlr4-runtime/)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/include/semantic)
|
include_directories(${CMAKE_SOURCE_DIR}/include/semantic)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/antlr-generated)
|
|
||||||
file(GLOB ANLTR_SOURCES "antlr-generated/*.cpp")
|
file(GLOB ANLTR_SOURCES "antlr-generated/*.cpp")
|
||||||
file(GLOB SEMANTIC_SOURCES "*.cpp")
|
file(GLOB SEMANTIC_SOURCES "*.cpp")
|
||||||
add_library(mx-antlr STATIC ${ANLTR_SOURCES})
|
add_library(mx-antlr STATIC ${ANLTR_SOURCES})
|
||||||
add_library(semantic STATIC ${SEMANTIC_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(mx-antlr PUBLIC antlr4-runtime)
|
||||||
target_link_libraries(semantic PUBLIC antlr4-runtime mx-antlr)
|
target_link_libraries(semantic PUBLIC antlr4-runtime mx-antlr ast)
|
@ -2660,59 +2660,137 @@ MXParser::Basic_exprContext::Basic_exprContext(ParserRuleContext *parent, size_t
|
|||||||
: ParserRuleContext(parent, invokingState) {
|
: 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 {
|
size_t MXParser::Basic_exprContext::getRuleIndex() const {
|
||||||
return MXParser::RuleBasic_expr;
|
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))
|
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
|
||||||
return parserVisitor->visitBasic_expr(this);
|
return parserVisitor->visitParen_expr(this);
|
||||||
else
|
else
|
||||||
return visitor->visitChildren(this);
|
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() {
|
MXParser::Basic_exprContext* MXParser::basic_expr() {
|
||||||
Basic_exprContext *_localctx = _tracker.createInstance<Basic_exprContext>(_ctx, getState());
|
Basic_exprContext *_localctx = _tracker.createInstance<Basic_exprContext>(_ctx, getState());
|
||||||
enterRule(_localctx, 18, MXParser::RuleBasic_expr);
|
enterRule(_localctx, 18, MXParser::RuleBasic_expr);
|
||||||
@ -2730,6 +2808,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
|
|||||||
_errHandler->sync(this);
|
_errHandler->sync(this);
|
||||||
switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 35, _ctx)) {
|
switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 35, _ctx)) {
|
||||||
case 1: {
|
case 1: {
|
||||||
|
_localctx = _tracker.createInstance<MXParser::This_exprContext>(_localctx);
|
||||||
enterOuterAlt(_localctx, 1);
|
enterOuterAlt(_localctx, 1);
|
||||||
setState(306);
|
setState(306);
|
||||||
match(MXParser::THIS);
|
match(MXParser::THIS);
|
||||||
@ -2737,6 +2816,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 2: {
|
case 2: {
|
||||||
|
_localctx = _tracker.createInstance<MXParser::Paren_exprContext>(_localctx);
|
||||||
enterOuterAlt(_localctx, 2);
|
enterOuterAlt(_localctx, 2);
|
||||||
setState(307);
|
setState(307);
|
||||||
match(MXParser::LPAREN);
|
match(MXParser::LPAREN);
|
||||||
@ -2748,6 +2828,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 3: {
|
case 3: {
|
||||||
|
_localctx = _tracker.createInstance<MXParser::Id_exprContext>(_localctx);
|
||||||
enterOuterAlt(_localctx, 3);
|
enterOuterAlt(_localctx, 3);
|
||||||
setState(311);
|
setState(311);
|
||||||
match(MXParser::ID);
|
match(MXParser::ID);
|
||||||
@ -2755,6 +2836,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 4: {
|
case 4: {
|
||||||
|
_localctx = _tracker.createInstance<MXParser::Function_call_exprContext>(_localctx);
|
||||||
enterOuterAlt(_localctx, 4);
|
enterOuterAlt(_localctx, 4);
|
||||||
setState(312);
|
setState(312);
|
||||||
match(MXParser::ID);
|
match(MXParser::ID);
|
||||||
@ -2787,6 +2869,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 5: {
|
case 5: {
|
||||||
|
_localctx = _tracker.createInstance<MXParser::Formatted_string_exprContext>(_localctx);
|
||||||
enterOuterAlt(_localctx, 5);
|
enterOuterAlt(_localctx, 5);
|
||||||
setState(325);
|
setState(325);
|
||||||
formatted_string();
|
formatted_string();
|
||||||
@ -2794,6 +2877,7 @@ MXParser::Basic_exprContext* MXParser::basic_expr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 6: {
|
case 6: {
|
||||||
|
_localctx = _tracker.createInstance<MXParser::Constant_exprContext>(_localctx);
|
||||||
enterOuterAlt(_localctx, 6);
|
enterOuterAlt(_localctx, 6);
|
||||||
setState(326);
|
setState(326);
|
||||||
constant();
|
constant();
|
||||||
|
@ -610,21 +610,76 @@ public:
|
|||||||
class Basic_exprContext : public antlr4::ParserRuleContext {
|
class Basic_exprContext : public antlr4::ParserRuleContext {
|
||||||
public:
|
public:
|
||||||
Basic_exprContext(antlr4::ParserRuleContext *parent, size_t invokingState);
|
Basic_exprContext(antlr4::ParserRuleContext *parent, size_t invokingState);
|
||||||
virtual size_t getRuleIndex() const override;
|
|
||||||
antlr4::tree::TerminalNode *THIS();
|
Basic_exprContext() = default;
|
||||||
antlr4::tree::TerminalNode *LPAREN();
|
void copyFrom(Basic_exprContext *context);
|
||||||
std::vector<ExprContext *> expr();
|
using antlr4::ParserRuleContext::copyFrom;
|
||||||
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();
|
|
||||||
|
|
||||||
|
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;
|
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Basic_exprContext* basic_expr();
|
Basic_exprContext* basic_expr();
|
||||||
|
@ -95,7 +95,17 @@ public:
|
|||||||
|
|
||||||
virtual std::any visitLor_expression(MXParser::Lor_expressionContext *context) = 0;
|
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;
|
virtual std::any visitFormatted_string(MXParser::Formatted_stringContext *context) = 0;
|
||||||
|
|
||||||
|
@ -3,15 +3,37 @@
|
|||||||
#include "MXLexer.h"
|
#include "MXLexer.h"
|
||||||
#include "MXParser.h"
|
#include "MXParser.h"
|
||||||
#include "antlr4-runtime.h"
|
#include "antlr4-runtime.h"
|
||||||
|
#include "ast/ast.h"
|
||||||
#include "visitor.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);
|
antlr4::ANTLRInputStream input(fin);
|
||||||
MXLexer lexer(&input);
|
MXLexer lexer(&input);
|
||||||
antlr4::CommonTokenStream tokens(&lexer);
|
antlr4::CommonTokenStream tokens(&lexer);
|
||||||
tokens.fill();
|
tokens.fill();
|
||||||
MXParser parser(&tokens);
|
MXParser parser(&tokens);
|
||||||
|
parser.removeErrorListeners();
|
||||||
|
MXErrorListener error_listener;
|
||||||
|
parser.addErrorListener(&error_listener);
|
||||||
antlr4::tree::ParseTree *tree = parser.mxprog();
|
antlr4::tree::ParseTree *tree = parser.mxprog();
|
||||||
|
if (!error_listener.IsOk()) throw SemanticError("Fatal error: syntax error", 1);
|
||||||
Visitor visitor;
|
Visitor visitor;
|
||||||
visitor.visit(tree);
|
std::shared_ptr<ASTNodeBase> ast = BuildAST(&visitor, tree);
|
||||||
return 0;
|
ast_out = CheckAndDecorate(ast);
|
||||||
}
|
}
|
@ -1,41 +1,128 @@
|
|||||||
#include "visitor.h"
|
#include "visitor.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
std::any Visitor::visitMxprog(MXParser::MxprogContext *context) {
|
std::any Visitor::visitMxprog(MXParser::MxprogContext *context) { throw std::runtime_error("Not implemented"); }
|
||||||
// 空的函数体
|
std::any Visitor::visitFunction_def(MXParser::Function_defContext *context) {
|
||||||
return {};
|
throw std::runtime_error("Not implemented");
|
||||||
}
|
}
|
||||||
|
std::any Visitor::visitClass_def(MXParser::Class_defContext *context) { throw std::runtime_error("Not implemented"); }
|
||||||
std::any Visitor::visitFunction(MXParser::FunctionContext *context) {
|
std::any Visitor::visitClass_var_def(MXParser::Class_var_defContext *context) {
|
||||||
// 空的函数体
|
throw std::runtime_error("Not implemented");
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
std::any Visitor::visitClass_constructor(MXParser::Class_constructorContext *context) {
|
||||||
std::any Visitor::visitType(MXParser::TypeContext *context) {
|
throw std::runtime_error("Not implemented");
|
||||||
// 空的函数体
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
std::any Visitor::visitSuite(MXParser::SuiteContext *context) { throw std::runtime_error("Not implemented"); }
|
||||||
std::any Visitor::visitBlock(MXParser::BlockContext *context) {
|
std::any Visitor::visitEmpty_statement(MXParser::Empty_statementContext *context) {
|
||||||
// 空的函数体
|
throw std::runtime_error("Not implemented");
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
std::any Visitor::visitDefinition_statement(MXParser::Definition_statementContext *context) {
|
||||||
std::any Visitor::visitStatement(MXParser::StatementContext *context) {
|
throw std::runtime_error("Not implemented");
|
||||||
// 空的函数体
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
std::any Visitor::visitExpr_statement(MXParser::Expr_statementContext *context) {
|
||||||
std::any Visitor::visitExpression(MXParser::ExpressionContext *context) {
|
throw std::runtime_error("Not implemented");
|
||||||
// 空的函数体
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
std::any Visitor::visitIf_statement(MXParser::If_statementContext *context) {
|
||||||
std::any Visitor::visitReturnStmt(MXParser::ReturnStmtContext *context) {
|
throw std::runtime_error("Not implemented");
|
||||||
// 空的函数体
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
std::any Visitor::visitWhile_statement(MXParser::While_statementContext *context) {
|
||||||
std::any Visitor::visitIfStmt(MXParser::IfStmtContext *context) {
|
throw std::runtime_error("Not implemented");
|
||||||
// 空的函数体
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
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"); }
|
||||||
|
Reference in New Issue
Block a user