Bugs Fixed; Code Modified;

This commit is contained in:
Saturneric 2021-04-30 20:55:56 +08:00
parent 75f6dd87f1
commit a5d808cabc
26 changed files with 1770 additions and 1252 deletions

View File

@ -3,4 +3,12 @@ project(syntaxParser)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)
add_executable(syntaxParser main.cpp) set(CMAKE_CXX_FLAGS_RELEASE "/Ox")
include_directories(./include)
aux_source_directory(src SRC_FILES)
add_executable(LR1Generator LR1Generator.cpp ${SRC_FILES})
add_executable(syntaxParser LR1Generator.cpp ${SRC_FILES})

57
LR1Generator.cpp Normal file
View File

@ -0,0 +1,57 @@
#include <iostream>
#include <ctime>
#include <SymbolTable.h>
#include <GrammarResourcePool.h>
#include <AnalyseTableGenerator.h>
using std::vector;
using std::wstring;
using std::wcout;
using std::endl;
#include <LR1Generator.h>
#include <SyntaxParser.h>
int main() {
clock_t start,end;//定义clock_t变量
start = clock(); //开始时间
const GrammarResourcePool *pool;
const AnalyseTableGenerator *atg;
LR1Generator generator;
generator.getProductions();
generator.run();
generator.output(pool, atg);
//输出时间
end = clock(); //结束时间
double times = double(end-start)/CLOCKS_PER_SEC;
wcout<<"LR1Generator Run time = "<< times <<"s MicroSeconds" << " = " << times * 1000 <<"ms" << endl;
start = clock(); //开始时间
SyntaxParser syntaxParser(pool, atg);
syntaxParser.getToken();
syntaxParser.parse();
//输出时间
end = clock(); //结束时间
times = double(end-start)/CLOCKS_PER_SEC;
wcout<<"SyntaxParser Run time = "<<times<<"s MicroSeconds " << " = " << times * 1000 <<"ms" << endl;
return 0;
}

7
SyntaxParser.cpp Normal file
View File

@ -0,0 +1,7 @@
//
// Created by Administrator on 2021/4/30.
//
int main() {
}

View File

@ -1,7 +1,12 @@
@struct_type -> "struct" "ID" "{" member_list "}" "EOF" @struct_type -> "struct" "ID" "{" member_list "}" more_struct_type
member_list-> type_spec declarators ";" more_struct_type -> "EOF"
more_struct_type -> ε
member_list -> type_spec declarators ";" member_list
member_list -> ε
type_spec -> base_type_spec type_spec -> base_type_spec
type_spec -> struct_type type_spec -> @struct_type
base_type_spec -> floating_pt_type base_type_spec -> floating_pt_type
base_type_spec -> integer_type base_type_spec -> integer_type
base_type_spec -> "char" base_type_spec -> "char"
@ -23,13 +28,13 @@ signed_int -> "int8"
unsigned_int -> "unsigned" "short" unsigned_int -> "unsigned" "short"
unsigned_int -> "unsigned" "long" unsigned_int -> "unsigned" "long"
unsigned_int -> "unsigned" "long" "long" unsigned_int -> "unsigned" "long" "long"
unsigned_int -> "unit16" unsigned_int -> "uint16"
unsigned_int -> "unit32" unsigned_int -> "uint32"
unsigned_int -> "unit64" unsigned_int -> "uint64"
unsigned_int -> "unit8" unsigned_int -> "uint8"
declarators -> declarator more_declarators declarators -> declarator more_declarators
more_declarators -> "," declarator more_declarators -> "," declarator more_declarators
more_declarators -> ε more_declarators -> ε
declarator -> "ID" more_declarator declarator -> "ID" more_declarator
@ -37,32 +42,48 @@ more_declarator -> exp_list
more_declarator -> ε more_declarator -> ε
exp_list -> "[" or_expr more_or_expr "]" exp_list -> "[" or_expr more_or_expr "]"
more_or_expr -> "," or_expr more_or_expr -> "," or_expr more_or_expr
more_or_expr -> ε more_or_expr -> ε
or_expr -> xor_expr more_xor_expr
more_xor_expr -> "|" xor_expr more_xor_expr
more_xor_expr -> ε
xor_expr -> and_expr more_and_expr xor_expr -> and_expr more_and_expr
more_and_expr -> "^" and_expr more_and_expr -> "^" and_expr more_and_expr
more_and_expr -> ε more_and_expr -> ε
and_expr -> shift_expr more_shift_expr and_expr -> shift_expr more_shift_expr
more_shift_expr -> "&" shift_expr more_shift_expr -> "&" shift_expr more_shift_expr
more_shift_expr -> ε more_shift_expr -> ε
shift_expr -> add_expr more_add_expr shift_expr -> add_expr more_add_expr
more_add_expr -> shift_sign add_expr more_add_expr -> shift_sign add_expr more_add_expr
shift_sign -> ">>" shift_sign -> ">>"
shift_sign -> "<<" shift_sign -> "<<"
more_add_expr -> ε
add_expr -> multi_expr more_multi_expr add_expr -> multi_expr more_multi_expr
more_multi_expr -> multi_sign multi_expr more_multi_expr -> multi_sign multi_expr more_multi_expr
multi_sign -> "+" multi_sign -> "+"
multi_sign -> "-" multi_sign -> "-"
more_multi_expr -> ε
multi_expr -> unary_expr more_unary_expr multi_expr -> unary_expr more_unary_expr
more_unary_expr -> unary_sign unary_expr more_unary_expr -> unary_sign unary_expr more_unary_expr
more_unary_expr -> ε
unary_sign -> "*" unary_sign -> "*"
unary_sign -> "/" unary_sign -> "/"
unary_sign -> "%" unary_sign -> "%"
more_unary_expr -> ε
unary_expr -> unary_sign_2 unary_declare unary_expr -> unary_sign_2 unary_declare
unary_sign_2 -> "-" unary_sign_2 -> "-"
unary_sign_2 -> "+" unary_sign_2 -> "+"
unary_sign_2 -> "~" unary_sign_2 -> "~"
unary_sign_2 -> ε
unary_declare -> "INTEGER" unary_declare -> "INTEGER"
unary_declare -> "STRING" unary_declare -> "STRING"
unary_declare -> "BOOLEAN" unary_declare -> BOOLEAN
BOOLEAN -> "TRUE"
BOOLEAN -> "FALSE"

View File

@ -0,0 +1,36 @@
1 STRUCT(struct) ID(test) OPENING_BRACE({)
2 FLOAT(float) ID(a1) SEMICOLON(;)
3 DOUBLE(double) ID(a2) COMMA(,) ID(a3) COMMA(,) ID(a4) SEMICOLON(;)
4 LONG(long) DOUBLE(double) ID(a5) SEMICOLON(;)
5 STRUCT(struct) ID(warp_int) OPENING_BRACE({)
6 INT8(int8) ID(i1) SEMICOLON(;)
7 INT16(int16) ID(i2) SEMICOLON(;)
8 INT32(int32) ID(i3) COMMA(,) ID(i4) SEMICOLON(;)
9 INT64(int64) ID(i5) SEMICOLON(;)
10 SHORT(short) ID(i6) SEMICOLON(;)
11 LONG(long) ID(i7) SEMICOLON(;)
12 LONG(long) LONG(long) ID(i8) SEMICOLON(;)
13 CLOSING_BRACE(}) ID(int1) COMMA(,) ID(int2) SEMICOLON(;)
14 STRUCT(struct) ID(warp_signInt) OPENING_BRACE({)
15 UINT8(uint8) ID(s1) SEMICOLON(;)
16 UINT16(uint16) ID(s2) SEMICOLON(;)
17 UINT32(uint32) ID(s3) COMMA(,) ID(s4) SEMICOLON(;)
18 UINT64(uint64) ID(s5) SEMICOLON(;)
19 UNSIGNED(unsigned) SHORT(short) ID(s6) COMMA(,) ID(s7) SEMICOLON(;)
20 UNSIGNED(unsigned) LONG(long) ID(s8) SEMICOLON(;)
21 UNSIGNED(unsigned) LONG(long) LONG(long) ID(s9) SEMICOLON(;)
22 CLOSING_BRACE(}) ID(sign1) COMMA(,) ID(SIGN2) SEMICOLON(;)
23 CHAR(char) ID(a_6) LEFT_BRACKET([) STRING("compile") PLUS(+) STRING("studying") COMMA(,) STRING("\40") COMMA(,) STRING("abs\b\t\n\f\r\"\\abs") RIGHT_BRACKET(]) SEMICOLON(;)
24 BOOLEAN(boolean) ID(a_bool_7) LEFT_BRACKET([) INTEGER(10) INSERT(^) INTEGER(2) COMMA(,) INTEGER(1) AND(&) INTEGER(2) AND(&) INTEGER(3) COMMA(,) TRUE(TRUE) DELIMITER(|) FALSE(FALSE) COMMA(,) TILDE(~) FALSE(FALSE) DELIMITER(|) TILDE(~) TRUE(TRUE) RIGHT_BRACKET(]) SEMICOLON(;)
25 LONG(long) ID(a8) LEFT_BRACKET([) INTEGER(1024) RIGHT_SHIFT(>>) INTEGER(10) COMMA(,) INTEGER(0) LEFT_SHIFT(<<) INTEGER(10) COMMA(,) INTEGER(100) MULT(*) INTEGER(2) SLASH(/) INTEGER(10) PERCENT(%) INTEGER(2) COMMA(,) INTEGER(100) PLUS(+) INTEGER(21) SUB(-) INTEGER(19) RIGHT_BRACKET(]) SEMICOLON(;)
26 BOOLEAN(boolean) ID(a9) LEFT_BRACKET([) INTEGER(10) INSERT(^) INTEGER(2) AND(&) INTEGER(3) DELIMITER(|) SUB(-) INTEGER(1) RIGHT_SHIFT(>>) INTEGER(10) AND(&) INTEGER(100) LEFT_SHIFT(<<) SUB(-) INTEGER(10) SUB(-) INTEGER(10) PLUS(+) INTEGER(100) MULT(*) INTEGER(2) SLASH(/) INTEGER(10) PERCENT(%) INTEGER(2) RIGHT_BRACKET(]) SEMICOLON(;)
27 STRUCT(struct) ID(warp_1) OPENING_BRACE({)
28 FLOAT(float) ID(w1) SEMICOLON(;)
29 LONG(long) ID(w2) SEMICOLON(;)
30 STRUCT(struct) ID(warp_2) OPENING_BRACE({)
31 BOOLEAN(boolean) ID(w3) LEFT_BRACKET([) INTEGER(111) AND(&) INTEGER(2) RIGHT_BRACKET(]) SEMICOLON(;)
32 CHAR(char) ID(w4) LEFT_BRACKET([) STRING("\40\b\t\n\f\r\"\\\40") RIGHT_BRACKET(]) SEMICOLON(;)
33 CLOSING_BRACE(}) ID(w5) COMMA(,) ID(w6) SEMICOLON(;)
34 CLOSING_BRACE(}) ID(w7) COMMA(,) ID(w8) SEMICOLON(;)
35 CLOSING_BRACE(})
36 EOF()

View File

@ -0,0 +1,73 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_ANALYSETABLEGENERATOR_H
#define SYNTAXPARSER_ANALYSETABLEGENERATOR_H
#include <fstream>
#include <iomanip>
#include <GrammarResourcePool.h>
#include <ItemCollectionManager.h>
using Action = enum {
MOVE, REDUCE, ACC, STEP_GOTO
};
class AnalyseTableGenerator {
struct Step {
const Action action;
union Target{
int index;
const Production *production;
} target{};
Step(Action action, int index) : action(action), target(Target{index}){}
Step(Action action, const Production *p_pdt) : action(action) {
target.production = p_pdt;
}
};
std::map<size_t, Step *> ACTION;
std::map<size_t, Step *> GOTO;
const ItemCollectionManager *icm;
const GrammarResourcePool *pool;
template <class T>
inline void hash_combine(std::size_t& seed, const T& v) const
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
void add_action(int index, int terminator_symbol, Action action, const Production *target_pdt);
void add_action(int index, int terminator_symbol, Action action, int target_index);
void add_goto(int index, int non_terminator_symbol, int target_index);
public:
explicit AnalyseTableGenerator(const GrammarResourcePool *p_pool, const ItemCollectionManager *p_icm)
:pool(p_pool) , icm(p_icm) {}
void generate();
const Step *findActionStep(int index, int terminator_symbol) const;
const Step *findGotoStep(int index, int non_terminator_symbol) const;
void print() const;
};
#endif //SYNTAXPARSER_ANALYSETABLEGENERATOR_H

View File

@ -0,0 +1,93 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_GRAMMARRESOURCEPOOL_H
#define SYNTAXPARSER_GRAMMARRESOURCEPOOL_H
#include <set>
#include <sstream>
#include <iostream>
#include <SymbolTable.h>
#include <Production.h>
// 语法资源池
class GrammarResourcePool {
int pdt_index = 0;
// 符号表
SymbolTable symbolTable;
// 产生式
std::vector<const Production *> productions;
// FIRST结果存储表
std::map<int, const std::set<int> *> firsts;
// FOLLOW结果存储表
std::map<int, std::set<int> *> follows;
// 去掉首尾空格
static std::wstring& trim(std::wstring &&str) {
if (str.empty()) {
return str;
}
str.erase(0,str.find_first_not_of(' '));
str.erase(str.find_last_not_of(' ') + 1);
return str;
}
public:
const std::set<int > *FIRST(const std::vector<int> &symbols, int start_index);
const std::set<int>* FIRST(int symbol);
const std::set<int> *FOLLOW(int symbol);
void FOLLOW();
std::set<int>* get_follow_set(int symbol);
void print_symbols(const std::set<int> &symbols_index);
void parse_production_string_line(const std::wstring &temp_line);
[[nodiscard]] const std::vector<const Production *> &get_productions() const {
return productions;
}
[[nodiscard]] const Symbol *getSymbol(int symbol_index) const {
return symbolTable.getSymbol(symbol_index);
}
[[nodiscard]] const Symbol *getStartSymbol() const {
return symbolTable.getStartSymbol();
}
int addSymbol(const std::wstring &name, bool terminator) {
return symbolTable.addSymbol(name, terminator);
}
const Production *addProduction(int left, std::initializer_list<int> right);
[[nodiscard]] const std::vector<const Symbol *> &getAllSymbols() const {
return symbolTable.getAllSymbols();
}
void modifySymbol(int index, const std::wstring &name, bool terminator, bool start) {
symbolTable.modifySymbol(index, name, terminator, start);
}
[[nodiscard]] int getSymbolIndex(const std::wstring &name) const {
return symbolTable.getSymbolIndex(name);
}
};
#endif //SYNTAXPARSER_GRAMMARRESOURCEPOOL_H

53
include/Item.h Normal file
View File

@ -0,0 +1,53 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_ITEM_H
#define SYNTAXPARSER_ITEM_H
#include <stdexcept>
#include <Production.h>
// 项
class Item{
// 对应的产生式
const Production* const production;
// 点的位置
int dot_index = 0;
const int terminator = 0;
public:
const bool generated = false;
explicit Item(const Production *p_pdt, int m_terminator, bool m_generated = false)
: production(p_pdt), terminator(m_terminator), generated(m_generated) {}
void set_dot_index(int m_dot_index);
[[nodiscard]] int get_dot_index() const {
return dot_index;
}
[[nodiscard]] size_t get_right_size() {
return production->right.size();
}
int get_dot_next_symbol() const;
int get_dot_next_i_symbol(int i) const;
[[nodiscard]] int get_terminator() const {
return terminator;
}
[[nodiscard]] const Production *get_production() const {
return production;
}
};
#endif //SYNTAXPARSER_ITEM_H

64
include/ItemCollection.h Normal file
View File

@ -0,0 +1,64 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_ITEMCOLLECTION_H
#define SYNTAXPARSER_ITEMCOLLECTION_H
#include <fstream>
#include <iostream>
#include <algorithm>
#include <functional>
#include <Item.h>
#include <GrammarResourcePool.h>
class ItemCollectionManager;
class ItemCollection{
int index = 0;
std::map<size_t, Item *> items;
std::vector<Item *> cache;
GrammarResourcePool *pool;
friend ItemCollectionManager;
template <class T>
inline void hash_combine(std::size_t& seed, const T& v) const
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
static bool compare_item_ptr(const Item* lhs, const Item* rhs);
public:
explicit ItemCollection(GrammarResourcePool *pool) : pool(pool) {
}
[[nodiscard]] const std::vector<Item *> &getItems() const {
return cache;
}
[[nodiscard]] int getIndex() const {
return index;
}
bool addItem(const Production *p_pdt, int dot_index, int terminator, bool generated = false);
void CLOSURE();
void print(std::wofstream &output) const;
[[nodiscard]] size_t getHash() const;
};
#endif //SYNTAXPARSER_ITEMCOLLECTION_H

View File

@ -0,0 +1,73 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_ITEMCOLLECTIONMANAGER_H
#define SYNTAXPARSER_ITEMCOLLECTIONMANAGER_H
#include <fstream>
#include <codecvt>
#include <ItemCollection.h>
class ItemCollectionManager{
std::wofstream output;
int index = 0;
std::map<size_t, ItemCollection *> ic_map;
std::map<size_t, ItemCollection *> ic_content_map;
std::vector<const ItemCollection *> ics;
GrammarResourcePool *pool;
const Production *start_pdt{};
template <class T>
inline void hash_combine(std::size_t& seed, const T& v) const
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
public:
explicit ItemCollectionManager(GrammarResourcePool *resource_pool) :
pool(resource_pool),
output("LR1Automata.txt", std::ios::binary) {
auto* codeCvtToUTF8= new std::codecvt_utf8<wchar_t>;
output.imbue(std::locale(output.getloc(), codeCvtToUTF8));
}
~ItemCollectionManager(){
output.close();
}
void buildItems();
[[nodiscard]] const Production *getStartProduction() const {
return start_pdt;
}
[[nodiscard]] const std::vector<const ItemCollection *> &getItemCollections() const{
return ics;
}
ItemCollection *getItemCollectionByHash(size_t hash);
bool addItemCollection(int idx, int symbol, ItemCollection *p_ic);
[[nodiscard]] const ItemCollection* getGOTO(int idx, int symbol) const;
bool GOTO(const ItemCollection *p_ic, int symbol);
};
#endif //SYNTAXPARSER_ITEMCOLLECTIONMANAGER_H

60
include/LR1Generator.h Normal file
View File

@ -0,0 +1,60 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_LR1GENERATOR_H
#define SYNTAXPARSER_LR1GENERATOR_H
#include <codecvt>
#include <GrammarResourcePool.h>
#include <ItemCollectionManager.h>
#include <AnalyseTableGenerator.h>
class LR1Generator{
// 文件输入
std::wifstream input;
GrammarResourcePool *pool;
ItemCollectionManager *icm;
AnalyseTableGenerator *atg;
public:
LR1Generator(): input("syntaxInput.txt", std::ios::binary),
pool(new GrammarResourcePool()),
icm(new ItemCollectionManager(pool)),
atg(new AnalyseTableGenerator(pool, icm)){
auto* codeCvtToUTF8= new std::codecvt_utf8<wchar_t>;
input.imbue(std::locale(input.getloc(), codeCvtToUTF8));
}
~LR1Generator() {
input.close();
}
void run() {
pool->FOLLOW();
icm->buildItems();
atg->generate();
atg->print();
}
// 得到所有的产生式
void getProductions();
void output(const GrammarResourcePool *&m_pool, const AnalyseTableGenerator *&m_atg) {
m_pool = this->pool;
m_atg = this->atg;
}
};
#endif //SYNTAXPARSER_LR1GENERATOR_H

22
include/Production.h Normal file
View File

@ -0,0 +1,22 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_PRODUCTION_H
#define SYNTAXPARSER_PRODUCTION_H
#include <vector>
// ²úÉúʽ
struct Production {
const int index;
const int left;
const std::vector<int> right;
Production(int index, int left, std::vector<int> right): index(index), left(left), right(std::move(right)) {}
};
#endif //SYNTAXPARSER_PRODUCTION_H

27
include/Symbol.h Normal file
View File

@ -0,0 +1,27 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_SYMBOL_H
#define SYNTAXPARSER_SYMBOL_H
#include <string>
struct Symbol {
const int index;
std::wstring name;
bool terminator;
bool start;
Symbol(int index, std::wstring name, bool terminator, bool start):
index(index),
name(std::move(name)),
terminator(terminator),
start(start)
{}
};
#endif //SYNTAXPARSER_SYMBOL_H

47
include/SymbolTable.h Normal file
View File

@ -0,0 +1,47 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_SYMBOLTABLE_H
#define SYNTAXPARSER_SYMBOLTABLE_H
#include <map>
#include <vector>
#include <string>
#include <stdexcept>
#include <Symbol.h>
class SymbolTable {
int index = 1;
std::map<std::wstring, Symbol *> table;
std::map<int, Symbol *> cache;
std::vector<const Symbol *> line;
public:
SymbolTable();
[[nodiscard]] const std::vector<const Symbol *> &getAllSymbols() const {
return line;
}
int addSymbol(const std::wstring& name, bool terminator);
[[nodiscard]] const Symbol *getSymbol(int symbol_index) const;
[[nodiscard]] int getSymbolIndex(const std::wstring &name) const;
void modifySymbol(int idx, const std::wstring &name, bool terminator, bool start);
[[nodiscard]] const Symbol *getStartSymbol() const;
};
#endif //SYNTAXPARSER_SYMBOLTABLE_H

78
include/SyntaxParser.h Normal file
View File

@ -0,0 +1,78 @@
//
// Created by Administrator on 2021/4/30.
//
#ifndef SYNTAXPARSER_SYNTAXPARSER_H
#define SYNTAXPARSER_SYNTAXPARSER_H
#include <queue>
#include <stack>
#include <regex>
#include <codecvt>
#include <GrammarResourcePool.h>
#include <AnalyseTableGenerator.h>
class SyntaxParser {
// 文件输入
std::wifstream input;
std::wofstream output;
const GrammarResourcePool *pool;
const AnalyseTableGenerator *atg;
std::queue<int> tokens_queue;
std::stack<int> analyse_stack;
std::stack<int> status_stack;
std::vector<size_t> lines_index;
std::wstringstream string_buffer;
size_t now_line = 1;
static std::vector<std::wstring> ws_split(const std::wstring& in, const std::wstring& delim);
static std::pair<std::wstring, std::wstring> get_token_info(const std::wstring &token);
public:
SyntaxParser(const GrammarResourcePool *pool, const AnalyseTableGenerator *atg):
input("tokenOut.txt", std::ios::binary),
pool(pool),
atg(atg),
output("SyntaxOut.txt", std::ios::binary){
auto* codeCvtToUTF8= new std::codecvt_utf8<wchar_t>;
input.imbue(std::locale(input.getloc(), codeCvtToUTF8));
output.imbue(std::locale(output.getloc(), codeCvtToUTF8));
}
~SyntaxParser() {
output.close();
}
// 得到所有的产生式
void getToken();
void printSymbol(int symbol_index);
void printProduction(const Production *p_pdt);
// 自底向上语法分析
void parse();
void printError();
void printDone();
};
#endif //SYNTAXPARSER_SYNTAXPARSER_H

1235
main.cpp

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,194 @@
//
// Created by Administrator on 2021/4/30.
//
#include "AnalyseTableGenerator.h"
void AnalyseTableGenerator::add_action(int index, int terminator_symbol, Action action, const Production *target_pdt) {
size_t seed = 0;
hash_combine(seed, index);
hash_combine(seed, terminator_symbol);
auto it = ACTION.find(seed);
if(it == ACTION.end()) {
auto step = new Step(action, target_pdt);
ACTION.insert(std::pair<size_t, Step *>(seed, step));
} else {
if(it->second->action != action || it->second->target.production != target_pdt)
throw std::runtime_error("Conflict Occurred, Syntax NOT LR(1)");
}
}
void AnalyseTableGenerator::add_action(int index, int terminator_symbol, Action action, int target_index) {
size_t seed = 0;
hash_combine(seed, index);
hash_combine(seed, terminator_symbol);
auto it = ACTION.find(seed);
if(it == ACTION.end()) {
auto step = new Step(action, target_index);
ACTION.insert(std::pair<size_t, Step *>(seed, step));
} else {
if(it->second->action != action || it->second->target.index != target_index)
throw std::runtime_error("Conflict Occurred, Syntax NOT LR(1)");
}
}
void AnalyseTableGenerator::add_goto(int index, int non_terminator_symbol, int target_index) {
size_t seed = 0;
hash_combine(seed, index);
hash_combine(seed, non_terminator_symbol);
auto it = GOTO.find(seed);
if(it == GOTO.end()) {
auto step = new Step(STEP_GOTO, target_index);
GOTO.insert(std::pair<size_t, Step *>(seed, step));
} else {
if(it->second->target.index != target_index)
throw std::runtime_error("Conflict Occurred, Syntax NOT LR(1)");
}
}
void AnalyseTableGenerator::generate() {
const auto &ics = icm->getItemCollections();
for(const auto *ic : ics) {
for(const auto *item : ic->getItems()) {
if(item->get_production() == icm->getStartProduction()
&& item->get_dot_next_symbol() == 0
&& item->get_terminator() == -1) {
this->add_action(ic->getIndex(), -1, ACC, 0);
}
int next_symbol = item->get_dot_next_symbol();
if(next_symbol != 0) {
const auto *p_ic = icm->getGOTO(ic->getIndex(), next_symbol);
if(pool->getSymbol(next_symbol)->terminator) {
if (p_ic != nullptr) {
this->add_action(ic->getIndex(), next_symbol, MOVE, p_ic->getIndex());
}
} else {
if (p_ic != nullptr) {
this->add_goto(ic->getIndex(), next_symbol, p_ic->getIndex());
}
}
} else {
if(pool->getSymbol(next_symbol)->terminator) {
if (item->get_production()->left != pool->getStartSymbol()->index) {
this->add_action(ic->getIndex(), item->get_terminator(), REDUCE, item->get_production());
}
}
}
}
}
}
const AnalyseTableGenerator::Step *AnalyseTableGenerator::findActionStep(int index, int terminator_symbol) const {
size_t seed = 0;
hash_combine(seed, index);
hash_combine(seed, terminator_symbol);
auto it = ACTION.find(seed);
if(it != ACTION.end()) {
return it->second;
} else {
return nullptr;
}
}
const AnalyseTableGenerator::Step *AnalyseTableGenerator::findGotoStep(int index, int non_terminator_symbol) const {
size_t seed = 0;
hash_combine(seed, index);
hash_combine(seed, non_terminator_symbol);
auto it = GOTO.find(seed);
if (it != GOTO.end()) {
return it->second;
} else {
return nullptr;
}
}
void AnalyseTableGenerator::print() const {
std::wofstream output("tables.txt");
size_t space = 4;
output << L"ACTION" << std::endl;
std::vector<int> symbols;
for(const auto *symbol : pool->getAllSymbols()) {
if(symbol->index == 0) continue;
if(symbol->terminator) {
space = std::max(space, symbol->name.size() + 2);
symbols.push_back(symbol->index);
}
}
output << std::left << std::setw(space) << " ";
for(const auto symbol_index : symbols) {
output << std::left << std::setw(space) << pool->getSymbol(symbol_index)->name;
}
output << std::endl;
for(int i = 0; i < icm->getItemCollections().size(); i++){
output << std::left << std::setw(space) << i;
for(int symbol : symbols) {
auto p_step = this->findActionStep(i, symbol);
if(p_step == nullptr) {
output << std::left << std::setw(space) << " ";
} else {
if(p_step->action == MOVE)
output << std::left << std::setw(space)
<< std::wstring(L"s") + std::to_wstring(p_step->target.index);
else if(p_step->action == ACC)
output << std::left << std::setw(space) << L"acc";
else if(p_step->action == REDUCE)
output << std::left << std::setw(space)
<< L"r" + std::to_wstring(p_step->target.production->index);
}
}
output << std::endl;
}
output << std::endl;
space = 4;
output << "GOTO" << std::endl;
symbols.clear();
for(const auto *symbol : pool->getAllSymbols()) {
if(symbol->index == 0) continue;
if(!symbol->terminator && !symbol->start) {
space = std::max(space, symbol->name.size() + 2);
symbols.push_back(symbol->index);
}
}
output << std::left << std::setw(space) << " ";
for(const auto symbol_index : symbols) {
output << std::left << std::setw(space) << pool->getSymbol(symbol_index)->name;
}
output <<std::endl;
for(int k = 0; k < icm->getItemCollections().size(); k++) {
output << std::left << std::setw(space) << k;
for (int symbol : symbols) {
auto p_step = this->findGotoStep(k, symbol);
if(p_step == nullptr) {
output << std::left << std::setw(space) << " ";
} else {
output << std::left << std::setw(space) << std::to_wstring(p_step->target.index);
}
}
output << std::endl;
}
output << std::endl << std::endl;
output.close();
}

276
src/GrammarResourcePool.cpp Normal file
View File

@ -0,0 +1,276 @@
//
// Created by Administrator on 2021/4/30.
//
#include "GrammarResourcePool.h"
const std::set<int> *GrammarResourcePool::FIRST(const std::vector<int> &symbols, int start_index) {
// 生成集合
auto *non_terminator_symbols = new std::set<int>();
for(int i = start_index; i < symbols.size(); i++) {
const auto p_non_term_set = FIRST(symbols[i]);
non_terminator_symbols->insert(p_non_term_set->begin(), p_non_term_set->end());
const auto sec_it = p_non_term_set->find(0);
if(sec_it != p_non_term_set->end()) {
continue;
} else {
break;
}
}
return non_terminator_symbols;
}
const std::set<int> *GrammarResourcePool::FIRST(int symbol) {
// 查找缓存
const auto it = firsts.find(symbol);
if(it != firsts.end()) {
return it->second;
}
// 生成集合
auto *non_terminator_symbols = new std::set<int>();
// 如果是终结符
if(symbolTable.getSymbol(symbol)->terminator) {
non_terminator_symbols->insert(symbol);
} else {
bool production_found = false;
// 遍历每一产生式
for (const auto &production : productions) {
const Production *p_pdt = production;
if (p_pdt->left != symbol) continue;
production_found = true;
for (const auto &right_symbol : p_pdt->right) {
const auto p_non_term_set = FIRST(right_symbol);
non_terminator_symbols->insert(p_non_term_set->begin(), p_non_term_set->end());
const auto sec_it = p_non_term_set->find(0);
if(sec_it != p_non_term_set->end()) {
continue;
} else {
break;
}
}
}
if (!production_found) non_terminator_symbols->insert(0);
}
this->firsts.insert(std::pair<int, const std::set<int> *>(symbol, non_terminator_symbols));
return non_terminator_symbols;
}
const std::set<int> *GrammarResourcePool::FOLLOW(int symbol) {
if(follows.empty()) {
FOLLOW();
}
const auto it = follows.find(symbol);
if(it != follows.end()) {
return it->second;
} else {
throw std::runtime_error("symbol NOT Found");
}
}
void GrammarResourcePool::FOLLOW() {
for (const auto &symbol : symbolTable.getAllSymbols()) {
if (!symbol->terminator) {
if (symbol->start) {
std::set<int> *non_terminator_symbols = get_follow_set(symbol->index);
non_terminator_symbols->insert(-1);
}
}
}
// 指导没有新的符号被添加到任意FOLLOW集合
bool ifAdded = true;
while(ifAdded) {
ifAdded = false;
std::set<int> *non_terminator_symbols = nullptr;
for (const auto &production : productions) {
const auto &right_symbols = production->right;
std::set<int> equal_left_non_terminators;
for (int i = 0; i < right_symbols.size() - 1; i++) {
// 非终结符
if (!symbolTable.getSymbol(right_symbols[i])->terminator) {
const auto p_non_term_set = FIRST(right_symbols, i + 1);
// 获得FOLLOW集
non_terminator_symbols = get_follow_set(right_symbols[i]);
const size_t set_size = non_terminator_symbols->size();
non_terminator_symbols->insert(p_non_term_set->begin(), p_non_term_set->end());
// 在集合中发现空字符
if(non_terminator_symbols->find(0) != non_terminator_symbols->end()) {
non_terminator_symbols->erase(0);
equal_left_non_terminators.insert(right_symbols[i]);
}
// 检查是否有新的终结符号被添加
if(set_size < non_terminator_symbols->size()) {
ifAdded = true;
}
}
}
if(!right_symbols.empty()) {
if (!symbolTable.getSymbol(right_symbols[right_symbols.size() - 1])->terminator) {
equal_left_non_terminators.insert(right_symbols[right_symbols.size() - 1]);
}
}
for(const auto symbol : equal_left_non_terminators) {
// 获得左边非终结符的FOLLOW集
const auto left_non_terminator_symbols = get_follow_set(production->left);
// 获得FOLLOW集
non_terminator_symbols = get_follow_set(symbol);
const size_t set_size = non_terminator_symbols->size();
non_terminator_symbols->insert(
left_non_terminator_symbols->begin(),
left_non_terminator_symbols->end());
if(non_terminator_symbols->find(0) != non_terminator_symbols->end()) {
non_terminator_symbols->erase(0);
}
// 检查是否有新的终结符号被添加
if(set_size < non_terminator_symbols->size()) {
ifAdded = true;
}
}
}
}
}
std::set<int> *GrammarResourcePool::get_follow_set(int symbol) {
std::set<int> *non_terminator_symbols = nullptr;
// 查找缓存
auto it = follows.find(symbol);
if(it != follows.end()) {
non_terminator_symbols = it->second;
} else {
non_terminator_symbols = new std::set<int>();
this->follows.insert(std::pair<int, std::set<int> *>(symbol, non_terminator_symbols));
}
return non_terminator_symbols;
}
void GrammarResourcePool::print_symbols(const std::set<int> &symbols_index) {
std::wcout << L"{ ";
for(const auto & symbol_index : symbols_index) {
auto *p_sym = symbolTable.getSymbol(symbol_index);
if(p_sym->terminator) {
if (p_sym->name == L"ε") {
std::wcout << L" [Epsilon] ";
}
else std::wcout << L" \"" << p_sym->name << L"\" ";
} else {
std::wcout << L" " << p_sym->name << L" ";
}
}
std::wcout << L"}" << std::endl;
}
void GrammarResourcePool::parse_production_string_line(const std::wstring &temp_line) {
auto middle_index = temp_line.find(L"->", 0);
if(middle_index == std::wstring::npos) {
throw std::runtime_error("-> NOT FOUND");
}
std::wstring front = trim(temp_line.substr(0, middle_index));
int left = symbolTable.addSymbol(front, false);
std::wstring back = trim(temp_line.substr(middle_index + 2, temp_line.size() - middle_index - 2));
std::wstringstream terminator, non_terminator;
std::vector<int> symbols;
bool is_terminator = false;
for(const auto &c : back) {
if (c == L'\"') {
if(is_terminator) {
symbols.push_back(symbolTable.addSymbol(trim(terminator.str()), true));
terminator.str(L"");
terminator.clear();
}
is_terminator = !is_terminator;
continue;
}
if(c == L' ' || c == L'\r') {
std::wstring temp_symbol = trim(non_terminator.str());
if(!temp_symbol.empty()) {
symbols.push_back(symbolTable.addSymbol(trim(non_terminator.str()), false));
non_terminator.str(L"");
non_terminator.clear();
}
continue;
}
if(is_terminator) {
terminator << c;
} else {
non_terminator << c;
}
}
std::wstring temp_symbol = trim(non_terminator.str());
if(!temp_symbol.empty()) {
symbols.push_back(symbolTable.addSymbol(trim(non_terminator.str()), false));
}
auto p_pdt = new Production(pdt_index++, left, symbols);
productions.push_back(p_pdt);
}
const Production *GrammarResourcePool::addProduction(int left, std::initializer_list<int> right) {
std::vector<int> right_vector;
for(int symbol : right) {
right_vector.push_back(symbol);
}
auto p_pdt = new Production(pdt_index++, left, right_vector);
productions.push_back(p_pdt);
return p_pdt;
}

28
src/Item.cpp Normal file
View File

@ -0,0 +1,28 @@
//
// Created by Administrator on 2021/4/30.
//
#include "Item.h"
void Item::set_dot_index(int m_dot_index) {
if(m_dot_index > production->right.size()) {
throw std::runtime_error("DOT_INDEX out of range");
}
this->dot_index = m_dot_index;
}
int Item::get_dot_next_symbol() const {
if(get_dot_index() == production->right.size()) {
return 0;
} else {
return production->right[dot_index];
}
}
int Item::get_dot_next_i_symbol(int i) const {
if(get_dot_index() + i >= production->right.size()) {
return 0;
} else {
return production->right[dot_index + i];
}
}

124
src/ItemCollection.cpp Normal file
View File

@ -0,0 +1,124 @@
//
// Created by Administrator on 2021/4/30.
//
#include "ItemCollection.h"
size_t ItemCollection::getHash() const {
size_t seed = 0;
std::vector<Item *> cache_sorted(cache.begin(), cache.end());
std::sort(cache_sorted.begin(), cache_sorted.end(), compare_item_ptr);
for(const auto item : cache_sorted) {
if(item->generated) {
continue;
}
hash_combine(seed, item->get_production());
hash_combine(seed, item->get_dot_index());
hash_combine(seed, item->get_terminator());
}
return seed;
}
void ItemCollection::print(std::wofstream &output) const {
output << L"I" << index << L": ";
for(const auto item : cache) {
const auto *p_pdt = item->get_production();
int dot_index = item->get_dot_index();
output << pool->getSymbol(p_pdt->left)->name << L" -> ";
int i = 0;
for(const auto &symbol_index : p_pdt->right) {
if(i > 0) output << " ";
if(i++ == dot_index) output << "*";
auto *symbol = pool->getSymbol(symbol_index);
if(!symbol->index) {
output << L"[Epsilon]";
continue;
}
if(!symbol->terminator)
output << pool->getSymbol(symbol_index)->name;
else
output << L'"' << pool->getSymbol(symbol_index)->name << L'"';
}
if(i++ == dot_index) output << "*";
output << L", \"" << pool->getSymbol(item->get_terminator())->name << "\"" << std::endl;
}
output << std::endl;
}
void ItemCollection::CLOSURE() {
bool ifAdd = true;
while(ifAdd) {
ifAdd = false;
for(const auto & item : items) {
int next_symbol = item.second->get_dot_next_symbol();
if(next_symbol == 0
|| pool->getSymbol(next_symbol)->terminator) {
continue;
}
for(auto *production : pool->get_productions()) {
if(production->left == next_symbol) {
std::vector<int> first_args;
auto p_ic = item.second;
const auto last_right_symbol_count = p_ic->get_right_size() - p_ic->get_dot_index();
for(int i = 1; i <= last_right_symbol_count; i++)
first_args.push_back(p_ic->get_dot_next_i_symbol(i));
first_args.push_back(p_ic->get_terminator());
const auto first_set = pool->FIRST(first_args, 0);
for(auto terminator : *first_set) {
if(terminator == 0) continue;
if(this->addItem(production, 0, terminator, true)) {
ifAdd = true;
}
}
}
}
}
}
}
bool ItemCollection::addItem(const Production *p_pdt, int dot_index, int terminator, bool generated) {
auto hasher = std::hash<int>();
size_t seed = hasher(reinterpret_cast<const int>(p_pdt));
hash_combine(seed, dot_index);
hash_combine(seed, terminator);
auto it = items.find(seed);
if(it != items.end()) {
return false;
}
auto *p_item = new Item(p_pdt, terminator, generated);
p_item->set_dot_index(dot_index);
items.insert(std::pair<size_t, Item *>(seed, p_item));
cache.push_back(p_item);
return true;
}
bool ItemCollection::compare_item_ptr(const Item *lhs, const Item *rhs) {
if(lhs->get_production() != rhs->get_production())
return lhs->get_production() < rhs->get_production();
else if(lhs->get_dot_index() != rhs->get_dot_index())
return lhs->get_dot_index() < rhs->get_dot_index();
else
return lhs->get_terminator() < rhs->get_terminator();
}

View File

@ -0,0 +1,131 @@
//
// Created by Administrator on 2021/4/30.
//
#include "ItemCollectionManager.h"
void ItemCollectionManager::buildItems() {
const auto startSymbol = pool->getStartSymbol();
std::wstring new_symbol_name = startSymbol->name + L"'";
int new_symbol_index = pool->addSymbol(new_symbol_name, startSymbol->terminator);
pool->modifySymbol(startSymbol->index, startSymbol->name.substr(1), false, false);
const auto *p_pdt = pool->addProduction(new_symbol_index, {startSymbol->index});
this->start_pdt = p_pdt;
auto *pi_ic = new ItemCollection(pool);
// -1 ´ú±í $
pi_ic->addItem(p_pdt, 0, -1);
pi_ic->CLOSURE();
addItemCollection(0, 0, pi_ic);
bool ifAdd = true;
while(ifAdd) {
ifAdd = false;
const auto &r_ics = getItemCollections();
std::vector<const ItemCollection *> temp_ics(r_ics.begin(), r_ics.end());
for(const auto ic : temp_ics) {
for(const auto symbol : pool->getAllSymbols()) {
if(symbol->index <= 0) {
continue;
}
if(GOTO(ic, symbol->index)) {
ifAdd = true;
}
}
}
}
}
ItemCollection *ItemCollectionManager::getItemCollectionByHash(size_t hash) {
ItemCollection *p_ic = nullptr;
auto it = ic_content_map.find(hash);
if(it != ic_content_map.end()) {
p_ic = it->second;
}
return p_ic;
}
bool ItemCollectionManager::addItemCollection(int idx, int symbol, ItemCollection *p_ic) {
size_t ic_hash = p_ic->getHash();
auto it = ic_content_map.find(ic_hash);
if (it != ic_content_map.end()) {
p_ic = it->second;
} else {
p_ic->index = this->index++;
ic_content_map.insert(std::pair<size_t, ItemCollection *>(ic_hash, p_ic));
ics.push_back(p_ic);
}
auto hasher = std::hash<int>();
size_t seed = hasher(idx);
hash_combine(seed, symbol);
auto it2 = ic_map.find(seed);
if(it2 != ic_map.end()) {
return false;
}
if(symbol != 0) {
auto p_symbol = pool->getSymbol(symbol);
if(p_symbol->terminator)
output << L"GOTO(" << idx << L", \"" << p_symbol->name << L"\")" << std::endl;
else
output << L"GOTO(" << idx << L", " << p_symbol->name << L")" << std::endl;
} else {
output << L"GOTO(" << idx << L", [Epsilon])" << std::endl;
}
ic_map.insert(std::pair<size_t, ItemCollection *>(seed, p_ic));
p_ic->print(output);
return true;
}
const ItemCollection *ItemCollectionManager::getGOTO(int idx, int symbol) const {
auto hasher = std::hash<int>();
size_t seed = hasher(idx);
hash_combine(seed, symbol);
auto it = ic_map.find(seed);
if(it != ic_map.end()) {
return it->second;
} else {
return nullptr;
}
}
bool ItemCollectionManager::GOTO(const ItemCollection *p_ic, int symbol) {
auto *pt_ic = new ItemCollection(pool);
for(const auto &item : p_ic->cache) {
if(item->get_dot_next_symbol() == symbol) {
pt_ic->addItem(item->get_production(), item->get_dot_index() + 1, item->get_terminator());
}
}
auto p_temp_ic = this->getItemCollectionByHash(pt_ic->getHash());
if(p_temp_ic == nullptr)
pt_ic->CLOSURE();
else pt_ic = p_temp_ic;
if(!pt_ic->items.empty()) {
return this->addItemCollection(p_ic->index, symbol, pt_ic);
} else {
return false;
}
}

17
src/LR1Generator.cpp Normal file
View File

@ -0,0 +1,17 @@
//
// Created by Administrator on 2021/4/30.
//
#include "LR1Generator.h"
void LR1Generator::getProductions() {
// 读入文法文件
std::wstring temp_line;
while (getline(input, temp_line)) {
if(temp_line.size() > 2 && temp_line[0] != '#') {
pool->parse_production_string_line(temp_line);
}
}
}

5
src/Production.cpp Normal file
View File

@ -0,0 +1,5 @@
//
// Created by Administrator on 2021/4/30.
//
#include "Production.h"

5
src/Symbol.cpp Normal file
View File

@ -0,0 +1,5 @@
//
// Created by Administrator on 2021/4/30.
//
#include "Symbol.h"

81
src/SymbolTable.cpp Normal file
View File

@ -0,0 +1,81 @@
//
// Created by Administrator on 2021/4/30.
//
#include "SymbolTable.h"
SymbolTable::SymbolTable() {
auto symbol = new Symbol(0, L"¦Å", true, false);
table.insert(std::pair<std::wstring, Symbol *>(L"¦Å", symbol));
cache.insert(std::pair<int, Symbol *>(0, symbol));
line.push_back(symbol);
symbol = new Symbol(-1, L"$", true, false);
table.insert(std::pair<std::wstring, Symbol *>(L"$", symbol));
cache.insert(std::pair<int, Symbol *>(-1, symbol));
line.push_back(symbol);
}
int SymbolTable::addSymbol(const std::wstring &name, bool terminator) {
Symbol *symbol = nullptr;
if(name == L"¦Å") {
return 0;
} else if (name[0] == L'@') {
symbol = new Symbol(index, name, terminator, true);
} else {
symbol = new Symbol(index, name, terminator, false);
}
const auto &it = table.find(name);
if (it != table.end()) {
return it->second->index;
}
table.insert(std::pair<std::wstring, Symbol *>(symbol->name, symbol));
cache.insert(std::pair<int, Symbol *>(symbol->index, symbol));
line.push_back(symbol);
index++;
return symbol->index;
}
const Symbol *SymbolTable::getSymbol(int symbol_index) const {
const auto &it = cache.find(symbol_index);
if(it != cache.end()) {
return it->second;
} else {
throw std::runtime_error("symbol " + std::to_string(symbol_index) + " NOT Found");
}
}
int SymbolTable::getSymbolIndex(const std::wstring &name) const {
const auto &it = table.find(name);
if(it != table.end()) {
return it->second->index;
} else {
throw std::runtime_error("symbol NOT Found");
}
}
void SymbolTable::modifySymbol(int idx, const std::wstring &name, bool terminator, bool start) {
auto it = cache.find(idx);
if(it != cache.end()) {
auto p_sym = it->second;
p_sym->name = name;
p_sym->terminator = terminator;
p_sym->start = start;
}
}
const Symbol *SymbolTable::getStartSymbol() const {
for(const auto & symbol : getAllSymbols()) {
if(symbol->start) {
return symbol;
}
}
throw std::runtime_error("start symbol NOT Found");
}

173
src/SyntaxParser.cpp Normal file
View File

@ -0,0 +1,173 @@
//
// Created by Administrator on 2021/4/30.
//
#include "SyntaxParser.h"
void SyntaxParser::parse() {
status_stack.push(0);
now_line = 1;
size_t _line_index = 0, max_line_index = lines_index[now_line-1];
while(!tokens_queue.empty()) {
auto *p_step = atg->findActionStep(status_stack.top(), tokens_queue.front());
if(p_step == nullptr) {
printError();
return;
}
if(p_step->action == MOVE) {
output << "MOVE IN" << "(AUTOMATA STATUS " << status_stack.top() <<"): ";
printSymbol(tokens_queue.front());
status_stack.push(p_step->target.index);
analyse_stack.push(tokens_queue.front());
if(_line_index > max_line_index) {
string_buffer.str(L"");
string_buffer.clear();
max_line_index = lines_index[now_line++];
}
string_buffer << pool->getSymbol(tokens_queue.front())->name << " ";
tokens_queue.pop();
_line_index++;
}
else if(p_step->action == REDUCE) {
auto *p_pdt = p_step->target.production;
output << "REDUCE BY" << "(AUTOMATA STATUS " << status_stack.top() <<"): [";
printProduction(p_pdt);
output << "]";
for(int i : p_pdt->right) {
if(i == 0)
continue;
analyse_stack.pop();
status_stack.pop();
}
auto *p_goto_step =
atg->findGotoStep(status_stack.top(), p_pdt->left);
if(p_goto_step == nullptr) {
printError();
return;
}
analyse_stack.push(p_pdt->left);
status_stack.push(p_goto_step->target.index);
} else if (p_step->action == ACC) {
output << "ACC";
printDone();
return;
} else {
printError();
return;
}
output << std::endl;
}
}
void SyntaxParser::printProduction(const Production *p_pdt) {
output << pool->getSymbol(p_pdt->left)->name << L" -> " ;
int i = 0;
for(const auto &symbol_index : p_pdt->right) {
if(i++ > 0) output << " ";
printSymbol(symbol_index);
}
}
void SyntaxParser::printSymbol(int symbol_index) {
auto *symbol = pool->getSymbol(symbol_index);
if(!symbol->index) {
output << L"[Epsilon]";
return;
}
if(!symbol->terminator)
output << pool->getSymbol(symbol_index)->name;
else
output << L'"' << pool->getSymbol(symbol_index)->name << L'"';
}
void SyntaxParser::getToken() {
// 读入文法文件
std::wstring temp_line;
size_t _line_index = 0;
while (getline(input, temp_line)) {
if(temp_line.size() > 2 && temp_line[0] != '#') {
std::vector<std::wstring> tokens = ws_split(temp_line, L" ");
for(int i = 1; i < tokens.size(); i++) {
if(tokens[i] == L"\r") continue;;
auto token_info = get_token_info(tokens[i]);
int symbol_index;
if(token_info.first == L"ID"
|| token_info.first == L"EOF"
|| token_info.first == L"INTEGER"
|| token_info.first == L"STRING")
symbol_index = pool->getSymbolIndex(token_info.first);
else
symbol_index = pool->getSymbolIndex(token_info.second);
tokens_queue.push(symbol_index);
_line_index++;
}
lines_index.push_back(_line_index - 1);
}
}
// 加入终结符$
tokens_queue.push(-1);
}
std::vector<std::wstring> SyntaxParser::ws_split(const std::wstring &in, const std::wstring &delim) {
std::wregex re{ delim };
return std::vector<std::wstring> {
std::wsregex_token_iterator(in.begin(), in.end(), re, -1),
std::wsregex_token_iterator()
};
}
std::pair<std::wstring, std::wstring> SyntaxParser::get_token_info(const std::wstring &token) {
auto pre_index = token.find(L'(');
auto back_index = token.find(L')');
std::wstring name = token.substr(0, pre_index);
std::wstring value = token.substr(pre_index + 1, back_index - pre_index - 1);
return std::pair<std::wstring, std::wstring>(name, value);
}
void SyntaxParser::printDone() {
output << std::endl;
output << "------------------------------------------------------" << std::endl;
output << "Syntax Parser Work Done, No Error Found." << std::endl << std::endl;
}
void SyntaxParser::printError() {
std::wstring temp_line = string_buffer.str();
output << std::endl;
output << "------------------------------------------------------" << std::endl;
output.fill('-');
output.width(24);
output << "Syntax Parser Found Error: " << std::endl
<< "At [Line " << now_line << "]: " << temp_line
<< "<- Next Token{" << pool->getSymbol(tokens_queue.front())->name << "}" << std::endl;
output << "AUTOMATA STATUS " << status_stack.top() << std::endl;
}