set basic repo structure

This commit is contained in:
2024-08-05 07:18:10 +00:00
parent 1711be891f
commit 388e4fda04
27 changed files with 1771 additions and 1 deletions

4
.gitignore vendored
View File

@ -1,3 +1,7 @@
/.devcontainer
/.github
/.vscode
/grammar/.antlr
/build
/.cache
/.clang-format

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "description"]
path = description
url = https://github.com/ACMClassCourses/Compiler-Design-Implementation.git

44
CMakeLists.txt Normal file
View File

@ -0,0 +1,44 @@
cmake_minimum_required(VERSION 3.12)
# 设置项目名字为 MXCompiler
project(MXCompiler)
# 设置编译标准为 C++20
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# 设置如果没有指定,默认编译模式为 release
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
# 设置 Debug 模式下开启全部编译警告和 sanitizer
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
add_compile_options(-Wall -Wextra -Wpedantic -fsanitize=address,undefined)
add_link_options(-fsanitize=address,undefined)
elseif(MSVC)
add_compile_options(/W4 /WX)
endif()
endif()
include(FetchContent)
FetchContent_Declare(
googletest
URL_HASH SHA256=1f357c27ca988c3f7c6b4bf68a9395005ac6761f034046e9dde0896e3aba00e4
URL ${CMAKE_SOURCE_DIR}/deps/googletest-v1.14.0-mirror.zip
)
FetchContent_MakeAvailable(googletest)
include(GoogleTest)
FetchContent_Declare(
argparse
URL_HASH SHA256=cd07c1208c01bef28c5173f4bad0b2df73dd7316d2f56fc80344952c400fa711
URL ${CMAKE_SOURCE_DIR}/deps/argparse-9550b0a-mirror.zip
)
FetchContent_MakeAvailable(argparse)
include_directories(${CMAKE_SOURCE_DIR}/include)
add_subdirectory(src)

1
README.md Normal file
View File

@ -0,0 +1 @@
# MX Compiler

BIN
deps/argparse-9550b0a-mirror.zip vendored Normal file

Binary file not shown.

BIN
deps/googletest-v1.14.0-mirror.zip vendored Normal file

Binary file not shown.

1
description Submodule

Submodule description added at f531387a2e

32
grammar/MXLexer.g4 Normal file
View File

@ -0,0 +1,32 @@
lexer grammar MXLexer;
// Keywords
INT: 'int';
VOID: 'void';
IF: 'if';
ELSE: 'else';
RETURN: 'return';
// Operators
PLUS: '+';
MINUS: '-';
MULTIPLY: '*';
DIVIDE: '/';
ASSIGN: '=';
// Punctuation
LPAREN: '(';
RPAREN: ')';
LBRACE: '{';
RBRACE: '}';
SEMICOLON: ';';
// Identifiers
ID: [a-zA-Z_][a-zA-Z_0-9]*;
// Literals
INT_LITERAL: [0-9]+;
// Whitespace and comments
WS: [ \t\r\n]+ -> skip;
COMMENT: '//' ~[\r\n]* -> skip;

41
grammar/MXParser.g4 Normal file
View File

@ -0,0 +1,41 @@
parser grammar MXParser;
options { tokenVocab=MXLexer; }
mxprog
: function* EOF
;
function
: type ID LPAREN RPAREN block
;
type
: INT
| VOID
;
block
: LBRACE statement* RBRACE
;
statement
: expression SEMICOLON
| returnStmt
| ifStmt
;
expression
: INT_LITERAL
| ID
| expression (PLUS | MINUS | MULTIPLY | DIVIDE) expression
| LPAREN expression RPAREN
;
returnStmt
: RETURN expression? SEMICOLON
;
ifStmt
: IF LPAREN expression RPAREN statement (ELSE statement)?
;

13
grammar/build.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash
# Get the directory of the script
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# Change to the script directory
cd "$SCRIPT_DIR"
# Set the output directory
OUTPUT_DIR="../src/semantic/antlr-generated"
# Create the output directory if it doesn't exist
mkdir -p "$OUTPUT_DIR"
# Run ANTLR to generate lexer and parser
antlr4 -Dlanguage=Cpp -no-listener -visitor MXLexer.g4 MXParser.g4 -o "$OUTPUT_DIR"
# Return to the original directory
cd - > /dev/null

View File

@ -0,0 +1,2 @@
#include<ios>
int SemanticCheck(std::istream &fin);

6
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
add_subdirectory(semantic)
add_executable(code main.cpp)
target_link_libraries(code semantic argparse)
set_target_properties(code PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)

28
src/main.cpp Normal file
View File

@ -0,0 +1,28 @@
#include <argparse/argparse.hpp>
#include <fstream>
#include <iostream>
#include "semantic/semantic.h"
int main(int argc, char **argv) {
argparse::ArgumentParser program("mxcompiler");
program.add_argument("input").help("input file path").required();
program.add_argument("-o", "--output").help("output file path").nargs(1).required();
try {
program.parse_args(argc, argv);
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
return 1;
}
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;
return 0;
}

View File

@ -0,0 +1,5 @@
include_directories(/usr/include/antlr4-runtime/)
include_directories(${CMAKE_SOURCE_DIR}/include/semantic)
file(GLOB SEMANTIC_SOURCES "*.cpp")
add_library(semantic STATIC ${SEMANTIC_SOURCES})
target_link_libraries(semantic PUBLIC antlr4-runtime)

View File

@ -0,0 +1,179 @@
// Generated from MXLexer.g4 by ANTLR 4.13.2
#include "MXLexer.h"
using namespace antlr4;
using namespace antlr4;
namespace {
struct MXLexerStaticData final {
MXLexerStaticData(std::vector<std::string> ruleNames,
std::vector<std::string> channelNames,
std::vector<std::string> modeNames,
std::vector<std::string> literalNames,
std::vector<std::string> symbolicNames)
: ruleNames(std::move(ruleNames)), channelNames(std::move(channelNames)),
modeNames(std::move(modeNames)), literalNames(std::move(literalNames)),
symbolicNames(std::move(symbolicNames)),
vocabulary(this->literalNames, this->symbolicNames) {}
MXLexerStaticData(const MXLexerStaticData&) = delete;
MXLexerStaticData(MXLexerStaticData&&) = delete;
MXLexerStaticData& operator=(const MXLexerStaticData&) = delete;
MXLexerStaticData& operator=(MXLexerStaticData&&) = delete;
std::vector<antlr4::dfa::DFA> decisionToDFA;
antlr4::atn::PredictionContextCache sharedContextCache;
const std::vector<std::string> ruleNames;
const std::vector<std::string> channelNames;
const std::vector<std::string> modeNames;
const std::vector<std::string> literalNames;
const std::vector<std::string> symbolicNames;
const antlr4::dfa::Vocabulary vocabulary;
antlr4::atn::SerializedATNView serializedATN;
std::unique_ptr<antlr4::atn::ATN> atn;
};
::antlr4::internal::OnceFlag mxlexerLexerOnceFlag;
#if ANTLR4_USE_THREAD_LOCAL_CACHE
static thread_local
#endif
std::unique_ptr<MXLexerStaticData> mxlexerLexerStaticData = nullptr;
void mxlexerLexerInitialize() {
#if ANTLR4_USE_THREAD_LOCAL_CACHE
if (mxlexerLexerStaticData != nullptr) {
return;
}
#else
assert(mxlexerLexerStaticData == nullptr);
#endif
auto staticData = std::make_unique<MXLexerStaticData>(
std::vector<std::string>{
"INT", "VOID", "IF", "ELSE", "RETURN", "PLUS", "MINUS", "MULTIPLY",
"DIVIDE", "ASSIGN", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "SEMICOLON",
"ID", "INT_LITERAL", "WS", "COMMENT"
},
std::vector<std::string>{
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
},
std::vector<std::string>{
"DEFAULT_MODE"
},
std::vector<std::string>{
"", "'int'", "'void'", "'if'", "'else'", "'return'", "'+'", "'-'",
"'*'", "'/'", "'='", "'('", "')'", "'{'", "'}'", "';'"
},
std::vector<std::string>{
"", "INT", "VOID", "IF", "ELSE", "RETURN", "PLUS", "MINUS", "MULTIPLY",
"DIVIDE", "ASSIGN", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "SEMICOLON",
"ID", "INT_LITERAL", "WS", "COMMENT"
}
);
static const int32_t serializedATNSegment[] = {
4,0,19,113,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,
6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14,
7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,1,0,1,0,1,0,1,0,1,1,1,1,
1,1,1,1,1,1,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,4,1,4,1,
4,1,5,1,5,1,6,1,6,1,7,1,7,1,8,1,8,1,9,1,9,1,10,1,10,1,11,1,11,1,12,1,
12,1,13,1,13,1,14,1,14,1,15,1,15,5,15,86,8,15,10,15,12,15,89,9,15,1,16,
4,16,92,8,16,11,16,12,16,93,1,17,4,17,97,8,17,11,17,12,17,98,1,17,1,17,
1,18,1,18,1,18,1,18,5,18,107,8,18,10,18,12,18,110,9,18,1,18,1,18,0,0,
19,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27,
14,29,15,31,16,33,17,35,18,37,19,1,0,5,3,0,65,90,95,95,97,122,4,0,48,
57,65,90,95,95,97,122,1,0,48,57,3,0,9,10,13,13,32,32,2,0,10,10,13,13,
116,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,
1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,
0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,
0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,1,39,1,0,0,0,3,43,1,0,0,0,5,48,
1,0,0,0,7,51,1,0,0,0,9,56,1,0,0,0,11,63,1,0,0,0,13,65,1,0,0,0,15,67,1,
0,0,0,17,69,1,0,0,0,19,71,1,0,0,0,21,73,1,0,0,0,23,75,1,0,0,0,25,77,1,
0,0,0,27,79,1,0,0,0,29,81,1,0,0,0,31,83,1,0,0,0,33,91,1,0,0,0,35,96,1,
0,0,0,37,102,1,0,0,0,39,40,5,105,0,0,40,41,5,110,0,0,41,42,5,116,0,0,
42,2,1,0,0,0,43,44,5,118,0,0,44,45,5,111,0,0,45,46,5,105,0,0,46,47,5,
100,0,0,47,4,1,0,0,0,48,49,5,105,0,0,49,50,5,102,0,0,50,6,1,0,0,0,51,
52,5,101,0,0,52,53,5,108,0,0,53,54,5,115,0,0,54,55,5,101,0,0,55,8,1,0,
0,0,56,57,5,114,0,0,57,58,5,101,0,0,58,59,5,116,0,0,59,60,5,117,0,0,60,
61,5,114,0,0,61,62,5,110,0,0,62,10,1,0,0,0,63,64,5,43,0,0,64,12,1,0,0,
0,65,66,5,45,0,0,66,14,1,0,0,0,67,68,5,42,0,0,68,16,1,0,0,0,69,70,5,47,
0,0,70,18,1,0,0,0,71,72,5,61,0,0,72,20,1,0,0,0,73,74,5,40,0,0,74,22,1,
0,0,0,75,76,5,41,0,0,76,24,1,0,0,0,77,78,5,123,0,0,78,26,1,0,0,0,79,80,
5,125,0,0,80,28,1,0,0,0,81,82,5,59,0,0,82,30,1,0,0,0,83,87,7,0,0,0,84,
86,7,1,0,0,85,84,1,0,0,0,86,89,1,0,0,0,87,85,1,0,0,0,87,88,1,0,0,0,88,
32,1,0,0,0,89,87,1,0,0,0,90,92,7,2,0,0,91,90,1,0,0,0,92,93,1,0,0,0,93,
91,1,0,0,0,93,94,1,0,0,0,94,34,1,0,0,0,95,97,7,3,0,0,96,95,1,0,0,0,97,
98,1,0,0,0,98,96,1,0,0,0,98,99,1,0,0,0,99,100,1,0,0,0,100,101,6,17,0,
0,101,36,1,0,0,0,102,103,5,47,0,0,103,104,5,47,0,0,104,108,1,0,0,0,105,
107,8,4,0,0,106,105,1,0,0,0,107,110,1,0,0,0,108,106,1,0,0,0,108,109,1,
0,0,0,109,111,1,0,0,0,110,108,1,0,0,0,111,112,6,18,0,0,112,38,1,0,0,0,
5,0,87,93,98,108,1,6,0,0
};
staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0]));
antlr4::atn::ATNDeserializer deserializer;
staticData->atn = deserializer.deserialize(staticData->serializedATN);
const size_t count = staticData->atn->getNumberOfDecisions();
staticData->decisionToDFA.reserve(count);
for (size_t i = 0; i < count; i++) {
staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i);
}
mxlexerLexerStaticData = std::move(staticData);
}
}
MXLexer::MXLexer(CharStream *input) : Lexer(input) {
MXLexer::initialize();
_interpreter = new atn::LexerATNSimulator(this, *mxlexerLexerStaticData->atn, mxlexerLexerStaticData->decisionToDFA, mxlexerLexerStaticData->sharedContextCache);
}
MXLexer::~MXLexer() {
delete _interpreter;
}
std::string MXLexer::getGrammarFileName() const {
return "MXLexer.g4";
}
const std::vector<std::string>& MXLexer::getRuleNames() const {
return mxlexerLexerStaticData->ruleNames;
}
const std::vector<std::string>& MXLexer::getChannelNames() const {
return mxlexerLexerStaticData->channelNames;
}
const std::vector<std::string>& MXLexer::getModeNames() const {
return mxlexerLexerStaticData->modeNames;
}
const dfa::Vocabulary& MXLexer::getVocabulary() const {
return mxlexerLexerStaticData->vocabulary;
}
antlr4::atn::SerializedATNView MXLexer::getSerializedATN() const {
return mxlexerLexerStaticData->serializedATN;
}
const atn::ATN& MXLexer::getATN() const {
return *mxlexerLexerStaticData->atn;
}
void MXLexer::initialize() {
#if ANTLR4_USE_THREAD_LOCAL_CACHE
mxlexerLexerInitialize();
#else
::antlr4::internal::call_once(mxlexerLexerOnceFlag, mxlexerLexerInitialize);
#endif
}

View File

@ -0,0 +1,51 @@
// Generated from MXLexer.g4 by ANTLR 4.13.2
#pragma once
#include "antlr4-runtime.h"
class MXLexer : public antlr4::Lexer {
public:
enum {
INT = 1, VOID = 2, IF = 3, ELSE = 4, RETURN = 5, PLUS = 6, MINUS = 7,
MULTIPLY = 8, DIVIDE = 9, ASSIGN = 10, LPAREN = 11, RPAREN = 12, LBRACE = 13,
RBRACE = 14, SEMICOLON = 15, ID = 16, INT_LITERAL = 17, WS = 18, COMMENT = 19
};
explicit MXLexer(antlr4::CharStream *input);
~MXLexer() override;
std::string getGrammarFileName() const override;
const std::vector<std::string>& getRuleNames() const override;
const std::vector<std::string>& getChannelNames() const override;
const std::vector<std::string>& getModeNames() const override;
const antlr4::dfa::Vocabulary& getVocabulary() const override;
antlr4::atn::SerializedATNView getSerializedATN() const override;
const antlr4::atn::ATN& getATN() const override;
// By default the static state used to implement the lexer is lazily initialized during the first
// call to the constructor. You can call this function if you wish to initialize the static state
// ahead of time.
static void initialize();
private:
// Individual action functions triggered by action() above.
// Individual semantic predicate functions triggered by sempred() above.
};

View File

@ -0,0 +1,74 @@
token literal names:
null
'int'
'void'
'if'
'else'
'return'
'+'
'-'
'*'
'/'
'='
'('
')'
'{'
'}'
';'
null
null
null
null
token symbolic names:
null
INT
VOID
IF
ELSE
RETURN
PLUS
MINUS
MULTIPLY
DIVIDE
ASSIGN
LPAREN
RPAREN
LBRACE
RBRACE
SEMICOLON
ID
INT_LITERAL
WS
COMMENT
rule names:
INT
VOID
IF
ELSE
RETURN
PLUS
MINUS
MULTIPLY
DIVIDE
ASSIGN
LPAREN
RPAREN
LBRACE
RBRACE
SEMICOLON
ID
INT_LITERAL
WS
COMMENT
channel names:
DEFAULT_TOKEN_CHANNEL
HIDDEN
mode names:
DEFAULT_MODE
atn:
[4, 0, 19, 113, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 5, 15, 86, 8, 15, 10, 15, 12, 15, 89, 9, 15, 1, 16, 4, 16, 92, 8, 16, 11, 16, 12, 16, 93, 1, 17, 4, 17, 97, 8, 17, 11, 17, 12, 17, 98, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 5, 18, 107, 8, 18, 10, 18, 12, 18, 110, 9, 18, 1, 18, 1, 18, 0, 0, 19, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 1, 0, 5, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 1, 0, 48, 57, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 10, 10, 13, 13, 116, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 1, 39, 1, 0, 0, 0, 3, 43, 1, 0, 0, 0, 5, 48, 1, 0, 0, 0, 7, 51, 1, 0, 0, 0, 9, 56, 1, 0, 0, 0, 11, 63, 1, 0, 0, 0, 13, 65, 1, 0, 0, 0, 15, 67, 1, 0, 0, 0, 17, 69, 1, 0, 0, 0, 19, 71, 1, 0, 0, 0, 21, 73, 1, 0, 0, 0, 23, 75, 1, 0, 0, 0, 25, 77, 1, 0, 0, 0, 27, 79, 1, 0, 0, 0, 29, 81, 1, 0, 0, 0, 31, 83, 1, 0, 0, 0, 33, 91, 1, 0, 0, 0, 35, 96, 1, 0, 0, 0, 37, 102, 1, 0, 0, 0, 39, 40, 5, 105, 0, 0, 40, 41, 5, 110, 0, 0, 41, 42, 5, 116, 0, 0, 42, 2, 1, 0, 0, 0, 43, 44, 5, 118, 0, 0, 44, 45, 5, 111, 0, 0, 45, 46, 5, 105, 0, 0, 46, 47, 5, 100, 0, 0, 47, 4, 1, 0, 0, 0, 48, 49, 5, 105, 0, 0, 49, 50, 5, 102, 0, 0, 50, 6, 1, 0, 0, 0, 51, 52, 5, 101, 0, 0, 52, 53, 5, 108, 0, 0, 53, 54, 5, 115, 0, 0, 54, 55, 5, 101, 0, 0, 55, 8, 1, 0, 0, 0, 56, 57, 5, 114, 0, 0, 57, 58, 5, 101, 0, 0, 58, 59, 5, 116, 0, 0, 59, 60, 5, 117, 0, 0, 60, 61, 5, 114, 0, 0, 61, 62, 5, 110, 0, 0, 62, 10, 1, 0, 0, 0, 63, 64, 5, 43, 0, 0, 64, 12, 1, 0, 0, 0, 65, 66, 5, 45, 0, 0, 66, 14, 1, 0, 0, 0, 67, 68, 5, 42, 0, 0, 68, 16, 1, 0, 0, 0, 69, 70, 5, 47, 0, 0, 70, 18, 1, 0, 0, 0, 71, 72, 5, 61, 0, 0, 72, 20, 1, 0, 0, 0, 73, 74, 5, 40, 0, 0, 74, 22, 1, 0, 0, 0, 75, 76, 5, 41, 0, 0, 76, 24, 1, 0, 0, 0, 77, 78, 5, 123, 0, 0, 78, 26, 1, 0, 0, 0, 79, 80, 5, 125, 0, 0, 80, 28, 1, 0, 0, 0, 81, 82, 5, 59, 0, 0, 82, 30, 1, 0, 0, 0, 83, 87, 7, 0, 0, 0, 84, 86, 7, 1, 0, 0, 85, 84, 1, 0, 0, 0, 86, 89, 1, 0, 0, 0, 87, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 32, 1, 0, 0, 0, 89, 87, 1, 0, 0, 0, 90, 92, 7, 2, 0, 0, 91, 90, 1, 0, 0, 0, 92, 93, 1, 0, 0, 0, 93, 91, 1, 0, 0, 0, 93, 94, 1, 0, 0, 0, 94, 34, 1, 0, 0, 0, 95, 97, 7, 3, 0, 0, 96, 95, 1, 0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 96, 1, 0, 0, 0, 98, 99, 1, 0, 0, 0, 99, 100, 1, 0, 0, 0, 100, 101, 6, 17, 0, 0, 101, 36, 1, 0, 0, 0, 102, 103, 5, 47, 0, 0, 103, 104, 5, 47, 0, 0, 104, 108, 1, 0, 0, 0, 105, 107, 8, 4, 0, 0, 106, 105, 1, 0, 0, 0, 107, 110, 1, 0, 0, 0, 108, 106, 1, 0, 0, 0, 108, 109, 1, 0, 0, 0, 109, 111, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 111, 112, 6, 18, 0, 0, 112, 38, 1, 0, 0, 0, 5, 0, 87, 93, 98, 108, 1, 6, 0, 0]

View File

@ -0,0 +1,34 @@
INT=1
VOID=2
IF=3
ELSE=4
RETURN=5
PLUS=6
MINUS=7
MULTIPLY=8
DIVIDE=9
ASSIGN=10
LPAREN=11
RPAREN=12
LBRACE=13
RBRACE=14
SEMICOLON=15
ID=16
INT_LITERAL=17
WS=18
COMMENT=19
'int'=1
'void'=2
'if'=3
'else'=4
'return'=5
'+'=6
'-'=7
'*'=8
'/'=9
'='=10
'('=11
')'=12
'{'=13
'}'=14
';'=15

View File

@ -0,0 +1,854 @@
// Generated from MXParser.g4 by ANTLR 4.13.2
#include "MXParserVisitor.h"
#include "MXParser.h"
using namespace antlrcpp;
using namespace antlr4;
namespace {
struct MXParserStaticData final {
MXParserStaticData(std::vector<std::string> ruleNames,
std::vector<std::string> literalNames,
std::vector<std::string> symbolicNames)
: ruleNames(std::move(ruleNames)), literalNames(std::move(literalNames)),
symbolicNames(std::move(symbolicNames)),
vocabulary(this->literalNames, this->symbolicNames) {}
MXParserStaticData(const MXParserStaticData&) = delete;
MXParserStaticData(MXParserStaticData&&) = delete;
MXParserStaticData& operator=(const MXParserStaticData&) = delete;
MXParserStaticData& operator=(MXParserStaticData&&) = delete;
std::vector<antlr4::dfa::DFA> decisionToDFA;
antlr4::atn::PredictionContextCache sharedContextCache;
const std::vector<std::string> ruleNames;
const std::vector<std::string> literalNames;
const std::vector<std::string> symbolicNames;
const antlr4::dfa::Vocabulary vocabulary;
antlr4::atn::SerializedATNView serializedATN;
std::unique_ptr<antlr4::atn::ATN> atn;
};
::antlr4::internal::OnceFlag mxparserParserOnceFlag;
#if ANTLR4_USE_THREAD_LOCAL_CACHE
static thread_local
#endif
std::unique_ptr<MXParserStaticData> mxparserParserStaticData = nullptr;
void mxparserParserInitialize() {
#if ANTLR4_USE_THREAD_LOCAL_CACHE
if (mxparserParserStaticData != nullptr) {
return;
}
#else
assert(mxparserParserStaticData == nullptr);
#endif
auto staticData = std::make_unique<MXParserStaticData>(
std::vector<std::string>{
"mxprog", "function", "type", "block", "statement", "expression",
"returnStmt", "ifStmt"
},
std::vector<std::string>{
"", "'int'", "'void'", "'if'", "'else'", "'return'", "'+'", "'-'",
"'*'", "'/'", "'='", "'('", "')'", "'{'", "'}'", "';'"
},
std::vector<std::string>{
"", "INT", "VOID", "IF", "ELSE", "RETURN", "PLUS", "MINUS", "MULTIPLY",
"DIVIDE", "ASSIGN", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "SEMICOLON",
"ID", "INT_LITERAL", "WS", "COMMENT"
}
);
static const int32_t serializedATNSegment[] = {
4,1,19,81,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,
7,7,1,0,5,0,18,8,0,10,0,12,0,21,9,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,1,2,1,3,1,3,5,3,35,8,3,10,3,12,3,38,9,3,1,3,1,3,1,4,1,4,1,4,1,4,1,4,
3,4,47,8,4,1,5,1,5,1,5,1,5,1,5,1,5,1,5,3,5,56,8,5,1,5,1,5,1,5,5,5,61,
8,5,10,5,12,5,64,9,5,1,6,1,6,3,6,68,8,6,1,6,1,6,1,7,1,7,1,7,1,7,1,7,1,
7,1,7,3,7,79,8,7,1,7,0,1,10,8,0,2,4,6,8,10,12,14,0,2,1,0,1,2,1,0,6,9,
81,0,19,1,0,0,0,2,24,1,0,0,0,4,30,1,0,0,0,6,32,1,0,0,0,8,46,1,0,0,0,10,
55,1,0,0,0,12,65,1,0,0,0,14,71,1,0,0,0,16,18,3,2,1,0,17,16,1,0,0,0,18,
21,1,0,0,0,19,17,1,0,0,0,19,20,1,0,0,0,20,22,1,0,0,0,21,19,1,0,0,0,22,
23,5,0,0,1,23,1,1,0,0,0,24,25,3,4,2,0,25,26,5,16,0,0,26,27,5,11,0,0,27,
28,5,12,0,0,28,29,3,6,3,0,29,3,1,0,0,0,30,31,7,0,0,0,31,5,1,0,0,0,32,
36,5,13,0,0,33,35,3,8,4,0,34,33,1,0,0,0,35,38,1,0,0,0,36,34,1,0,0,0,36,
37,1,0,0,0,37,39,1,0,0,0,38,36,1,0,0,0,39,40,5,14,0,0,40,7,1,0,0,0,41,
42,3,10,5,0,42,43,5,15,0,0,43,47,1,0,0,0,44,47,3,12,6,0,45,47,3,14,7,
0,46,41,1,0,0,0,46,44,1,0,0,0,46,45,1,0,0,0,47,9,1,0,0,0,48,49,6,5,-1,
0,49,56,5,17,0,0,50,56,5,16,0,0,51,52,5,11,0,0,52,53,3,10,5,0,53,54,5,
12,0,0,54,56,1,0,0,0,55,48,1,0,0,0,55,50,1,0,0,0,55,51,1,0,0,0,56,62,
1,0,0,0,57,58,10,2,0,0,58,59,7,1,0,0,59,61,3,10,5,3,60,57,1,0,0,0,61,
64,1,0,0,0,62,60,1,0,0,0,62,63,1,0,0,0,63,11,1,0,0,0,64,62,1,0,0,0,65,
67,5,5,0,0,66,68,3,10,5,0,67,66,1,0,0,0,67,68,1,0,0,0,68,69,1,0,0,0,69,
70,5,15,0,0,70,13,1,0,0,0,71,72,5,3,0,0,72,73,5,11,0,0,73,74,3,10,5,0,
74,75,5,12,0,0,75,78,3,8,4,0,76,77,5,4,0,0,77,79,3,8,4,0,78,76,1,0,0,
0,78,79,1,0,0,0,79,15,1,0,0,0,7,19,36,46,55,62,67,78
};
staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0]));
antlr4::atn::ATNDeserializer deserializer;
staticData->atn = deserializer.deserialize(staticData->serializedATN);
const size_t count = staticData->atn->getNumberOfDecisions();
staticData->decisionToDFA.reserve(count);
for (size_t i = 0; i < count; i++) {
staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i);
}
mxparserParserStaticData = std::move(staticData);
}
}
MXParser::MXParser(TokenStream *input) : MXParser(input, antlr4::atn::ParserATNSimulatorOptions()) {}
MXParser::MXParser(TokenStream *input, const antlr4::atn::ParserATNSimulatorOptions &options) : Parser(input) {
MXParser::initialize();
_interpreter = new atn::ParserATNSimulator(this, *mxparserParserStaticData->atn, mxparserParserStaticData->decisionToDFA, mxparserParserStaticData->sharedContextCache, options);
}
MXParser::~MXParser() {
delete _interpreter;
}
const atn::ATN& MXParser::getATN() const {
return *mxparserParserStaticData->atn;
}
std::string MXParser::getGrammarFileName() const {
return "MXParser.g4";
}
const std::vector<std::string>& MXParser::getRuleNames() const {
return mxparserParserStaticData->ruleNames;
}
const dfa::Vocabulary& MXParser::getVocabulary() const {
return mxparserParserStaticData->vocabulary;
}
antlr4::atn::SerializedATNView MXParser::getSerializedATN() const {
return mxparserParserStaticData->serializedATN;
}
//----------------- MxprogContext ------------------------------------------------------------------
MXParser::MxprogContext::MxprogContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* MXParser::MxprogContext::EOF() {
return getToken(MXParser::EOF, 0);
}
std::vector<MXParser::FunctionContext *> MXParser::MxprogContext::function() {
return getRuleContexts<MXParser::FunctionContext>();
}
MXParser::FunctionContext* MXParser::MxprogContext::function(size_t i) {
return getRuleContext<MXParser::FunctionContext>(i);
}
size_t MXParser::MxprogContext::getRuleIndex() const {
return MXParser::RuleMxprog;
}
std::any MXParser::MxprogContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitMxprog(this);
else
return visitor->visitChildren(this);
}
MXParser::MxprogContext* MXParser::mxprog() {
MxprogContext *_localctx = _tracker.createInstance<MxprogContext>(_ctx, getState());
enterRule(_localctx, 0, MXParser::RuleMxprog);
size_t _la = 0;
#if __cplusplus > 201703L
auto onExit = finally([=, this] {
#else
auto onExit = finally([=] {
#endif
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(19);
_errHandler->sync(this);
_la = _input->LA(1);
while (_la == MXParser::INT
|| _la == MXParser::VOID) {
setState(16);
function();
setState(21);
_errHandler->sync(this);
_la = _input->LA(1);
}
setState(22);
match(MXParser::EOF);
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- FunctionContext ------------------------------------------------------------------
MXParser::FunctionContext::FunctionContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
MXParser::TypeContext* MXParser::FunctionContext::type() {
return getRuleContext<MXParser::TypeContext>(0);
}
tree::TerminalNode* MXParser::FunctionContext::ID() {
return getToken(MXParser::ID, 0);
}
tree::TerminalNode* MXParser::FunctionContext::LPAREN() {
return getToken(MXParser::LPAREN, 0);
}
tree::TerminalNode* MXParser::FunctionContext::RPAREN() {
return getToken(MXParser::RPAREN, 0);
}
MXParser::BlockContext* MXParser::FunctionContext::block() {
return getRuleContext<MXParser::BlockContext>(0);
}
size_t MXParser::FunctionContext::getRuleIndex() const {
return MXParser::RuleFunction;
}
std::any MXParser::FunctionContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitFunction(this);
else
return visitor->visitChildren(this);
}
MXParser::FunctionContext* MXParser::function() {
FunctionContext *_localctx = _tracker.createInstance<FunctionContext>(_ctx, getState());
enterRule(_localctx, 2, MXParser::RuleFunction);
#if __cplusplus > 201703L
auto onExit = finally([=, this] {
#else
auto onExit = finally([=] {
#endif
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(24);
type();
setState(25);
match(MXParser::ID);
setState(26);
match(MXParser::LPAREN);
setState(27);
match(MXParser::RPAREN);
setState(28);
block();
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- TypeContext ------------------------------------------------------------------
MXParser::TypeContext::TypeContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* MXParser::TypeContext::INT() {
return getToken(MXParser::INT, 0);
}
tree::TerminalNode* MXParser::TypeContext::VOID() {
return getToken(MXParser::VOID, 0);
}
size_t MXParser::TypeContext::getRuleIndex() const {
return MXParser::RuleType;
}
std::any MXParser::TypeContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitType(this);
else
return visitor->visitChildren(this);
}
MXParser::TypeContext* MXParser::type() {
TypeContext *_localctx = _tracker.createInstance<TypeContext>(_ctx, getState());
enterRule(_localctx, 4, MXParser::RuleType);
size_t _la = 0;
#if __cplusplus > 201703L
auto onExit = finally([=, this] {
#else
auto onExit = finally([=] {
#endif
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(30);
_la = _input->LA(1);
if (!(_la == MXParser::INT
|| _la == MXParser::VOID)) {
_errHandler->recoverInline(this);
}
else {
_errHandler->reportMatch(this);
consume();
}
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- BlockContext ------------------------------------------------------------------
MXParser::BlockContext::BlockContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* MXParser::BlockContext::LBRACE() {
return getToken(MXParser::LBRACE, 0);
}
tree::TerminalNode* MXParser::BlockContext::RBRACE() {
return getToken(MXParser::RBRACE, 0);
}
std::vector<MXParser::StatementContext *> MXParser::BlockContext::statement() {
return getRuleContexts<MXParser::StatementContext>();
}
MXParser::StatementContext* MXParser::BlockContext::statement(size_t i) {
return getRuleContext<MXParser::StatementContext>(i);
}
size_t MXParser::BlockContext::getRuleIndex() const {
return MXParser::RuleBlock;
}
std::any MXParser::BlockContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitBlock(this);
else
return visitor->visitChildren(this);
}
MXParser::BlockContext* MXParser::block() {
BlockContext *_localctx = _tracker.createInstance<BlockContext>(_ctx, getState());
enterRule(_localctx, 6, MXParser::RuleBlock);
size_t _la = 0;
#if __cplusplus > 201703L
auto onExit = finally([=, this] {
#else
auto onExit = finally([=] {
#endif
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(32);
match(MXParser::LBRACE);
setState(36);
_errHandler->sync(this);
_la = _input->LA(1);
while ((((_la & ~ 0x3fULL) == 0) &&
((1ULL << _la) & 198696) != 0)) {
setState(33);
statement();
setState(38);
_errHandler->sync(this);
_la = _input->LA(1);
}
setState(39);
match(MXParser::RBRACE);
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- StatementContext ------------------------------------------------------------------
MXParser::StatementContext::StatementContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
MXParser::ExpressionContext* MXParser::StatementContext::expression() {
return getRuleContext<MXParser::ExpressionContext>(0);
}
tree::TerminalNode* MXParser::StatementContext::SEMICOLON() {
return getToken(MXParser::SEMICOLON, 0);
}
MXParser::ReturnStmtContext* MXParser::StatementContext::returnStmt() {
return getRuleContext<MXParser::ReturnStmtContext>(0);
}
MXParser::IfStmtContext* MXParser::StatementContext::ifStmt() {
return getRuleContext<MXParser::IfStmtContext>(0);
}
size_t MXParser::StatementContext::getRuleIndex() const {
return MXParser::RuleStatement;
}
std::any MXParser::StatementContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitStatement(this);
else
return visitor->visitChildren(this);
}
MXParser::StatementContext* MXParser::statement() {
StatementContext *_localctx = _tracker.createInstance<StatementContext>(_ctx, getState());
enterRule(_localctx, 8, MXParser::RuleStatement);
#if __cplusplus > 201703L
auto onExit = finally([=, this] {
#else
auto onExit = finally([=] {
#endif
exitRule();
});
try {
setState(46);
_errHandler->sync(this);
switch (_input->LA(1)) {
case MXParser::LPAREN:
case MXParser::ID:
case MXParser::INT_LITERAL: {
enterOuterAlt(_localctx, 1);
setState(41);
expression(0);
setState(42);
match(MXParser::SEMICOLON);
break;
}
case MXParser::RETURN: {
enterOuterAlt(_localctx, 2);
setState(44);
returnStmt();
break;
}
case MXParser::IF: {
enterOuterAlt(_localctx, 3);
setState(45);
ifStmt();
break;
}
default:
throw NoViableAltException(this);
}
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- ExpressionContext ------------------------------------------------------------------
MXParser::ExpressionContext::ExpressionContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* MXParser::ExpressionContext::INT_LITERAL() {
return getToken(MXParser::INT_LITERAL, 0);
}
tree::TerminalNode* MXParser::ExpressionContext::ID() {
return getToken(MXParser::ID, 0);
}
tree::TerminalNode* MXParser::ExpressionContext::LPAREN() {
return getToken(MXParser::LPAREN, 0);
}
std::vector<MXParser::ExpressionContext *> MXParser::ExpressionContext::expression() {
return getRuleContexts<MXParser::ExpressionContext>();
}
MXParser::ExpressionContext* MXParser::ExpressionContext::expression(size_t i) {
return getRuleContext<MXParser::ExpressionContext>(i);
}
tree::TerminalNode* MXParser::ExpressionContext::RPAREN() {
return getToken(MXParser::RPAREN, 0);
}
tree::TerminalNode* MXParser::ExpressionContext::PLUS() {
return getToken(MXParser::PLUS, 0);
}
tree::TerminalNode* MXParser::ExpressionContext::MINUS() {
return getToken(MXParser::MINUS, 0);
}
tree::TerminalNode* MXParser::ExpressionContext::MULTIPLY() {
return getToken(MXParser::MULTIPLY, 0);
}
tree::TerminalNode* MXParser::ExpressionContext::DIVIDE() {
return getToken(MXParser::DIVIDE, 0);
}
size_t MXParser::ExpressionContext::getRuleIndex() const {
return MXParser::RuleExpression;
}
std::any MXParser::ExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitExpression(this);
else
return visitor->visitChildren(this);
}
MXParser::ExpressionContext* MXParser::expression() {
return expression(0);
}
MXParser::ExpressionContext* MXParser::expression(int precedence) {
ParserRuleContext *parentContext = _ctx;
size_t parentState = getState();
MXParser::ExpressionContext *_localctx = _tracker.createInstance<ExpressionContext>(_ctx, parentState);
MXParser::ExpressionContext *previousContext = _localctx;
(void)previousContext; // Silence compiler, in case the context is not used by generated code.
size_t startState = 10;
enterRecursionRule(_localctx, 10, MXParser::RuleExpression, precedence);
size_t _la = 0;
#if __cplusplus > 201703L
auto onExit = finally([=, this] {
#else
auto onExit = finally([=] {
#endif
unrollRecursionContexts(parentContext);
});
try {
size_t alt;
enterOuterAlt(_localctx, 1);
setState(55);
_errHandler->sync(this);
switch (_input->LA(1)) {
case MXParser::INT_LITERAL: {
setState(49);
match(MXParser::INT_LITERAL);
break;
}
case MXParser::ID: {
setState(50);
match(MXParser::ID);
break;
}
case MXParser::LPAREN: {
setState(51);
match(MXParser::LPAREN);
setState(52);
expression(0);
setState(53);
match(MXParser::RPAREN);
break;
}
default:
throw NoViableAltException(this);
}
_ctx->stop = _input->LT(-1);
setState(62);
_errHandler->sync(this);
alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 4, _ctx);
while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
if (alt == 1) {
if (!_parseListeners.empty())
triggerExitRuleEvent();
previousContext = _localctx;
_localctx = _tracker.createInstance<ExpressionContext>(parentContext, parentState);
pushNewRecursionContext(_localctx, startState, RuleExpression);
setState(57);
if (!(precpred(_ctx, 2))) throw FailedPredicateException(this, "precpred(_ctx, 2)");
setState(58);
_la = _input->LA(1);
if (!((((_la & ~ 0x3fULL) == 0) &&
((1ULL << _la) & 960) != 0))) {
_errHandler->recoverInline(this);
}
else {
_errHandler->reportMatch(this);
consume();
}
setState(59);
expression(3);
}
setState(64);
_errHandler->sync(this);
alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 4, _ctx);
}
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- ReturnStmtContext ------------------------------------------------------------------
MXParser::ReturnStmtContext::ReturnStmtContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* MXParser::ReturnStmtContext::RETURN() {
return getToken(MXParser::RETURN, 0);
}
tree::TerminalNode* MXParser::ReturnStmtContext::SEMICOLON() {
return getToken(MXParser::SEMICOLON, 0);
}
MXParser::ExpressionContext* MXParser::ReturnStmtContext::expression() {
return getRuleContext<MXParser::ExpressionContext>(0);
}
size_t MXParser::ReturnStmtContext::getRuleIndex() const {
return MXParser::RuleReturnStmt;
}
std::any MXParser::ReturnStmtContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitReturnStmt(this);
else
return visitor->visitChildren(this);
}
MXParser::ReturnStmtContext* MXParser::returnStmt() {
ReturnStmtContext *_localctx = _tracker.createInstance<ReturnStmtContext>(_ctx, getState());
enterRule(_localctx, 12, MXParser::RuleReturnStmt);
size_t _la = 0;
#if __cplusplus > 201703L
auto onExit = finally([=, this] {
#else
auto onExit = finally([=] {
#endif
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(65);
match(MXParser::RETURN);
setState(67);
_errHandler->sync(this);
_la = _input->LA(1);
if ((((_la & ~ 0x3fULL) == 0) &&
((1ULL << _la) & 198656) != 0)) {
setState(66);
expression(0);
}
setState(69);
match(MXParser::SEMICOLON);
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
//----------------- IfStmtContext ------------------------------------------------------------------
MXParser::IfStmtContext::IfStmtContext(ParserRuleContext *parent, size_t invokingState)
: ParserRuleContext(parent, invokingState) {
}
tree::TerminalNode* MXParser::IfStmtContext::IF() {
return getToken(MXParser::IF, 0);
}
tree::TerminalNode* MXParser::IfStmtContext::LPAREN() {
return getToken(MXParser::LPAREN, 0);
}
MXParser::ExpressionContext* MXParser::IfStmtContext::expression() {
return getRuleContext<MXParser::ExpressionContext>(0);
}
tree::TerminalNode* MXParser::IfStmtContext::RPAREN() {
return getToken(MXParser::RPAREN, 0);
}
std::vector<MXParser::StatementContext *> MXParser::IfStmtContext::statement() {
return getRuleContexts<MXParser::StatementContext>();
}
MXParser::StatementContext* MXParser::IfStmtContext::statement(size_t i) {
return getRuleContext<MXParser::StatementContext>(i);
}
tree::TerminalNode* MXParser::IfStmtContext::ELSE() {
return getToken(MXParser::ELSE, 0);
}
size_t MXParser::IfStmtContext::getRuleIndex() const {
return MXParser::RuleIfStmt;
}
std::any MXParser::IfStmtContext::accept(tree::ParseTreeVisitor *visitor) {
if (auto parserVisitor = dynamic_cast<MXParserVisitor*>(visitor))
return parserVisitor->visitIfStmt(this);
else
return visitor->visitChildren(this);
}
MXParser::IfStmtContext* MXParser::ifStmt() {
IfStmtContext *_localctx = _tracker.createInstance<IfStmtContext>(_ctx, getState());
enterRule(_localctx, 14, MXParser::RuleIfStmt);
#if __cplusplus > 201703L
auto onExit = finally([=, this] {
#else
auto onExit = finally([=] {
#endif
exitRule();
});
try {
enterOuterAlt(_localctx, 1);
setState(71);
match(MXParser::IF);
setState(72);
match(MXParser::LPAREN);
setState(73);
expression(0);
setState(74);
match(MXParser::RPAREN);
setState(75);
statement();
setState(78);
_errHandler->sync(this);
switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 6, _ctx)) {
case 1: {
setState(76);
match(MXParser::ELSE);
setState(77);
statement();
break;
}
default:
break;
}
}
catch (RecognitionException &e) {
_errHandler->reportError(this, e);
_localctx->exception = std::current_exception();
_errHandler->recover(this, _localctx->exception);
}
return _localctx;
}
bool MXParser::sempred(RuleContext *context, size_t ruleIndex, size_t predicateIndex) {
switch (ruleIndex) {
case 5: return expressionSempred(antlrcpp::downCast<ExpressionContext *>(context), predicateIndex);
default:
break;
}
return true;
}
bool MXParser::expressionSempred(ExpressionContext *_localctx, size_t predicateIndex) {
switch (predicateIndex) {
case 0: return precpred(_ctx, 2);
default:
break;
}
return true;
}
void MXParser::initialize() {
#if ANTLR4_USE_THREAD_LOCAL_CACHE
mxparserParserInitialize();
#else
::antlr4::internal::call_once(mxparserParserOnceFlag, mxparserParserInitialize);
#endif
}

View File

@ -0,0 +1,197 @@
// Generated from MXParser.g4 by ANTLR 4.13.2
#pragma once
#include "antlr4-runtime.h"
class MXParser : public antlr4::Parser {
public:
enum {
INT = 1, VOID = 2, IF = 3, ELSE = 4, RETURN = 5, PLUS = 6, MINUS = 7,
MULTIPLY = 8, DIVIDE = 9, ASSIGN = 10, LPAREN = 11, RPAREN = 12, LBRACE = 13,
RBRACE = 14, SEMICOLON = 15, ID = 16, INT_LITERAL = 17, WS = 18, COMMENT = 19
};
enum {
RuleMxprog = 0, RuleFunction = 1, RuleType = 2, RuleBlock = 3, RuleStatement = 4,
RuleExpression = 5, RuleReturnStmt = 6, RuleIfStmt = 7
};
explicit MXParser(antlr4::TokenStream *input);
MXParser(antlr4::TokenStream *input, const antlr4::atn::ParserATNSimulatorOptions &options);
~MXParser() override;
std::string getGrammarFileName() const override;
const antlr4::atn::ATN& getATN() const override;
const std::vector<std::string>& getRuleNames() const override;
const antlr4::dfa::Vocabulary& getVocabulary() const override;
antlr4::atn::SerializedATNView getSerializedATN() const override;
class MxprogContext;
class FunctionContext;
class TypeContext;
class BlockContext;
class StatementContext;
class ExpressionContext;
class ReturnStmtContext;
class IfStmtContext;
class MxprogContext : public antlr4::ParserRuleContext {
public:
MxprogContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *EOF();
std::vector<FunctionContext *> function();
FunctionContext* function(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
MxprogContext* mxprog();
class FunctionContext : public antlr4::ParserRuleContext {
public:
FunctionContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
TypeContext *type();
antlr4::tree::TerminalNode *ID();
antlr4::tree::TerminalNode *LPAREN();
antlr4::tree::TerminalNode *RPAREN();
BlockContext *block();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FunctionContext* function();
class TypeContext : public antlr4::ParserRuleContext {
public:
TypeContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *INT();
antlr4::tree::TerminalNode *VOID();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
TypeContext* type();
class BlockContext : public antlr4::ParserRuleContext {
public:
BlockContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *LBRACE();
antlr4::tree::TerminalNode *RBRACE();
std::vector<StatementContext *> statement();
StatementContext* statement(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
BlockContext* block();
class StatementContext : public antlr4::ParserRuleContext {
public:
StatementContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
ExpressionContext *expression();
antlr4::tree::TerminalNode *SEMICOLON();
ReturnStmtContext *returnStmt();
IfStmtContext *ifStmt();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
StatementContext* statement();
class ExpressionContext : public antlr4::ParserRuleContext {
public:
ExpressionContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *INT_LITERAL();
antlr4::tree::TerminalNode *ID();
antlr4::tree::TerminalNode *LPAREN();
std::vector<ExpressionContext *> expression();
ExpressionContext* expression(size_t i);
antlr4::tree::TerminalNode *RPAREN();
antlr4::tree::TerminalNode *PLUS();
antlr4::tree::TerminalNode *MINUS();
antlr4::tree::TerminalNode *MULTIPLY();
antlr4::tree::TerminalNode *DIVIDE();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ExpressionContext* expression();
ExpressionContext* expression(int precedence);
class ReturnStmtContext : public antlr4::ParserRuleContext {
public:
ReturnStmtContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *RETURN();
antlr4::tree::TerminalNode *SEMICOLON();
ExpressionContext *expression();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ReturnStmtContext* returnStmt();
class IfStmtContext : public antlr4::ParserRuleContext {
public:
IfStmtContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *IF();
antlr4::tree::TerminalNode *LPAREN();
ExpressionContext *expression();
antlr4::tree::TerminalNode *RPAREN();
std::vector<StatementContext *> statement();
StatementContext* statement(size_t i);
antlr4::tree::TerminalNode *ELSE();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
IfStmtContext* ifStmt();
bool sempred(antlr4::RuleContext *_localctx, size_t ruleIndex, size_t predicateIndex) override;
bool expressionSempred(ExpressionContext *_localctx, size_t predicateIndex);
// By default the static state used to implement the parser is lazily initialized during the first
// call to the constructor. You can call this function if you wish to initialize the static state
// ahead of time.
static void initialize();
private:
};

View File

@ -0,0 +1,57 @@
token literal names:
null
'int'
'void'
'if'
'else'
'return'
'+'
'-'
'*'
'/'
'='
'('
')'
'{'
'}'
';'
null
null
null
null
token symbolic names:
null
INT
VOID
IF
ELSE
RETURN
PLUS
MINUS
MULTIPLY
DIVIDE
ASSIGN
LPAREN
RPAREN
LBRACE
RBRACE
SEMICOLON
ID
INT_LITERAL
WS
COMMENT
rule names:
mxprog
function
type
block
statement
expression
returnStmt
ifStmt
atn:
[4, 1, 19, 81, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 1, 0, 5, 0, 18, 8, 0, 10, 0, 12, 0, 21, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 5, 3, 35, 8, 3, 10, 3, 12, 3, 38, 9, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 47, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 56, 8, 5, 1, 5, 1, 5, 1, 5, 5, 5, 61, 8, 5, 10, 5, 12, 5, 64, 9, 5, 1, 6, 1, 6, 3, 6, 68, 8, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 79, 8, 7, 1, 7, 0, 1, 10, 8, 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 1, 0, 1, 2, 1, 0, 6, 9, 81, 0, 19, 1, 0, 0, 0, 2, 24, 1, 0, 0, 0, 4, 30, 1, 0, 0, 0, 6, 32, 1, 0, 0, 0, 8, 46, 1, 0, 0, 0, 10, 55, 1, 0, 0, 0, 12, 65, 1, 0, 0, 0, 14, 71, 1, 0, 0, 0, 16, 18, 3, 2, 1, 0, 17, 16, 1, 0, 0, 0, 18, 21, 1, 0, 0, 0, 19, 17, 1, 0, 0, 0, 19, 20, 1, 0, 0, 0, 20, 22, 1, 0, 0, 0, 21, 19, 1, 0, 0, 0, 22, 23, 5, 0, 0, 1, 23, 1, 1, 0, 0, 0, 24, 25, 3, 4, 2, 0, 25, 26, 5, 16, 0, 0, 26, 27, 5, 11, 0, 0, 27, 28, 5, 12, 0, 0, 28, 29, 3, 6, 3, 0, 29, 3, 1, 0, 0, 0, 30, 31, 7, 0, 0, 0, 31, 5, 1, 0, 0, 0, 32, 36, 5, 13, 0, 0, 33, 35, 3, 8, 4, 0, 34, 33, 1, 0, 0, 0, 35, 38, 1, 0, 0, 0, 36, 34, 1, 0, 0, 0, 36, 37, 1, 0, 0, 0, 37, 39, 1, 0, 0, 0, 38, 36, 1, 0, 0, 0, 39, 40, 5, 14, 0, 0, 40, 7, 1, 0, 0, 0, 41, 42, 3, 10, 5, 0, 42, 43, 5, 15, 0, 0, 43, 47, 1, 0, 0, 0, 44, 47, 3, 12, 6, 0, 45, 47, 3, 14, 7, 0, 46, 41, 1, 0, 0, 0, 46, 44, 1, 0, 0, 0, 46, 45, 1, 0, 0, 0, 47, 9, 1, 0, 0, 0, 48, 49, 6, 5, -1, 0, 49, 56, 5, 17, 0, 0, 50, 56, 5, 16, 0, 0, 51, 52, 5, 11, 0, 0, 52, 53, 3, 10, 5, 0, 53, 54, 5, 12, 0, 0, 54, 56, 1, 0, 0, 0, 55, 48, 1, 0, 0, 0, 55, 50, 1, 0, 0, 0, 55, 51, 1, 0, 0, 0, 56, 62, 1, 0, 0, 0, 57, 58, 10, 2, 0, 0, 58, 59, 7, 1, 0, 0, 59, 61, 3, 10, 5, 3, 60, 57, 1, 0, 0, 0, 61, 64, 1, 0, 0, 0, 62, 60, 1, 0, 0, 0, 62, 63, 1, 0, 0, 0, 63, 11, 1, 0, 0, 0, 64, 62, 1, 0, 0, 0, 65, 67, 5, 5, 0, 0, 66, 68, 3, 10, 5, 0, 67, 66, 1, 0, 0, 0, 67, 68, 1, 0, 0, 0, 68, 69, 1, 0, 0, 0, 69, 70, 5, 15, 0, 0, 70, 13, 1, 0, 0, 0, 71, 72, 5, 3, 0, 0, 72, 73, 5, 11, 0, 0, 73, 74, 3, 10, 5, 0, 74, 75, 5, 12, 0, 0, 75, 78, 3, 8, 4, 0, 76, 77, 5, 4, 0, 0, 77, 79, 3, 8, 4, 0, 78, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, 15, 1, 0, 0, 0, 7, 19, 36, 46, 55, 62, 67, 78]

View File

@ -0,0 +1,34 @@
INT=1
VOID=2
IF=3
ELSE=4
RETURN=5
PLUS=6
MINUS=7
MULTIPLY=8
DIVIDE=9
ASSIGN=10
LPAREN=11
RPAREN=12
LBRACE=13
RBRACE=14
SEMICOLON=15
ID=16
INT_LITERAL=17
WS=18
COMMENT=19
'int'=1
'void'=2
'if'=3
'else'=4
'return'=5
'+'=6
'-'=7
'*'=8
'/'=9
'='=10
'('=11
')'=12
'{'=13
'}'=14
';'=15

View File

@ -0,0 +1,7 @@
// Generated from MXParser.g4 by ANTLR 4.13.2
#include "MXParserBaseVisitor.h"

View File

@ -0,0 +1,52 @@
// Generated from MXParser.g4 by ANTLR 4.13.2
#pragma once
#include "antlr4-runtime.h"
#include "MXParserVisitor.h"
/**
* This class provides an empty implementation of MXParserVisitor, which can be
* extended to create a visitor which only needs to handle a subset of the available methods.
*/
class MXParserBaseVisitor : public MXParserVisitor {
public:
virtual std::any visitMxprog(MXParser::MxprogContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitFunction(MXParser::FunctionContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitType(MXParser::TypeContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitBlock(MXParser::BlockContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitStatement(MXParser::StatementContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitExpression(MXParser::ExpressionContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitReturnStmt(MXParser::ReturnStmtContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitIfStmt(MXParser::IfStmtContext *ctx) override {
return visitChildren(ctx);
}
};

View File

@ -0,0 +1,7 @@
// Generated from MXParser.g4 by ANTLR 4.13.2
#include "MXParserVisitor.h"

View File

@ -0,0 +1,40 @@
// Generated from MXParser.g4 by ANTLR 4.13.2
#pragma once
#include "antlr4-runtime.h"
#include "MXParser.h"
/**
* This class defines an abstract visitor for a parse tree
* produced by MXParser.
*/
class MXParserVisitor : public antlr4::tree::AbstractParseTreeVisitor {
public:
/**
* Visit parse trees produced by MXParser.
*/
virtual std::any visitMxprog(MXParser::MxprogContext *context) = 0;
virtual std::any visitFunction(MXParser::FunctionContext *context) = 0;
virtual std::any visitType(MXParser::TypeContext *context) = 0;
virtual std::any visitBlock(MXParser::BlockContext *context) = 0;
virtual std::any visitStatement(MXParser::StatementContext *context) = 0;
virtual std::any visitExpression(MXParser::ExpressionContext *context) = 0;
virtual std::any visitReturnStmt(MXParser::ReturnStmtContext *context) = 0;
virtual std::any visitIfStmt(MXParser::IfStmtContext *context) = 0;
};

View File

@ -0,0 +1,4 @@
#include "semantic.h"
int SemanticCheck(std::istream &fin) {
;
}