├── .gitattributes ├── LexAnalyse.cpp ├── LexAnalyse.h ├── README.md ├── SynAnalyse.cpp ├── SynAnalyse.h └── main.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | *.h linguist-language=C++ 2 | *.cpp linguist-language=C++ 3 | -------------------------------------------------------------------------------- /LexAnalyse.cpp: -------------------------------------------------------------------------------- 1 | #include "LexAnalyse.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | //初始化保留字字典 12 | void initKeyMap() 13 | { 14 | keyMap.clear(); 15 | keyMap["main"] = MAIN; 16 | keyMap["int"] = INT; 17 | keyMap["return"] = RETURN; 18 | keyMap["if"] = IF; 19 | keyMap["else"] = ELSE; 20 | } 21 | 22 | //初始化运算符字典 23 | void initOperMap() 24 | { 25 | operMap.clear(); 26 | operMap["+"] = ADD; 27 | operMap["-"] = SUB; 28 | operMap["*"] = MUL; 29 | operMap["/"] = DIV; 30 | operMap[">"] = GRT_THAN; 31 | operMap[">="] = GRT_EQUAL; 32 | operMap["<"] = LESS_THAN; 33 | operMap["<="] = LESS_EQUAL; 34 | operMap["!="] = NOT_EQUAL; 35 | operMap["=="] = EQUAL; 36 | operMap["="] = ASSIGN; 37 | } 38 | 39 | //初始化限制符字典 40 | void initLimitMap() 41 | { 42 | limitMap["{"] = LEFT_BOUNDER; 43 | limitMap["}"] = RIGHT_BOUNDER; 44 | limitMap["("] = LEFT_BRACKET; 45 | limitMap[")"] = RIGHT_BRACKET; 46 | limitMap[";"] = SEMICOLON; 47 | } 48 | 49 | //初始化结点 50 | void initNode() 51 | { 52 | normalHead = new NormalNode(); 53 | normalHead->content = ""; 54 | normalHead->describe = ""; 55 | normalHead->type = -1; 56 | normalHead->iden_type = ""; 57 | normalHead->line = -1; 58 | normalHead->next = NULL; 59 | 60 | errorHead = new ErrorNode(); 61 | errorHead->content = ""; 62 | errorHead->describe = ""; 63 | errorHead->line = -1; 64 | errorHead->next = NULL; 65 | 66 | cout << "初始化单词结点、错误结点完毕" << endl; 67 | } 68 | 69 | //插入一个结点 70 | void createNewNode(string content, string descirbe, int type, int line) 71 | { 72 | NormalNode *p = normalHead; 73 | NormalNode *temp = new NormalNode(); 74 | 75 | while (p->next) 76 | { 77 | p = p->next; 78 | } 79 | 80 | temp->content = content; 81 | temp->describe = descirbe; 82 | temp->type = type; 83 | temp->iden_type = ""; 84 | temp->line = line; 85 | temp->next = NULL; 86 | 87 | p->next = temp; 88 | } 89 | 90 | //插入一个错误结点 91 | void createNewError(string content, string descirbe, int type, int line) 92 | { 93 | ErrorNode *p = errorHead; 94 | ErrorNode *temp = new ErrorNode(); 95 | 96 | temp->content = content; 97 | temp->describe = descirbe; 98 | temp->type = type; 99 | temp->line = line; 100 | temp->next = NULL; 101 | while (p->next) 102 | { 103 | p = p->next; 104 | } 105 | p->next = temp; 106 | } 107 | 108 | //输出结点信息 109 | void printNodeLink() 110 | { 111 | cout << "*****************************分析表******************************" << endl 112 | << endl; 113 | cout << setw(15) << "内容" 114 | << setw(15) << "描述" 115 | << "\t" 116 | << setw(3) << "种别码" 117 | << "\t" 118 | << setw(8) << "标识符类型" 119 | << "\t" 120 | << "行号" << endl; 121 | NormalNode *p = normalHead; 122 | p = p->next; 123 | while (p) 124 | { 125 | cout << setw(15) << p->content 126 | << setw(15) << p->describe << "\t" 127 | << setw(3) << p->type << "\t" 128 | << setw(8) << p->iden_type << "\t" 129 | << p->line << endl; 130 | 131 | p = p->next; 132 | } 133 | cout << endl; 134 | } 135 | 136 | //导出结点信息 137 | void outputNodeLink() 138 | { 139 | ofstream fout("words.txt"); 140 | if (!fout) 141 | { 142 | cout << "words.txt打开失败!" << endl; 143 | return; 144 | } 145 | fout << "*****************************分析表******************************" << endl 146 | << endl; 147 | fout << "内容" 148 | << "\t" 149 | << setw(10) << "描述" 150 | << "\t" 151 | << setw(3) << "种别码" 152 | << "\t" 153 | << setw(8) << "标识符类型" 154 | << "\t" 155 | << "行号" << endl; 156 | NormalNode *p = normalHead; 157 | p = p->next; 158 | while (p) 159 | { 160 | fout << p->content << "\t" 161 | << setw(10) << p->describe << "\t" 162 | << setw(3) << p->type << "\t" 163 | << setw(8) << p->iden_type << "\t\t" 164 | << p->line << endl; 165 | 166 | p = p->next; 167 | } 168 | fout << endl; 169 | 170 | cout << "words.txt更新完成!" << endl; 171 | fout.close(); 172 | } 173 | 174 | //输出错误结点信息 175 | void printErrorLink() 176 | { 177 | cout << "*****************************错误表******************************" << endl 178 | << endl; 179 | cout << setw(15) << "内容" << setw(15) << "描述" 180 | << "\t" 181 | << "类型" 182 | << "\t" 183 | << "行号" << endl; 184 | ErrorNode *p = errorHead; 185 | p = p->next; 186 | while (p) 187 | { 188 | cout << setw(15) << p->content << setw(15) << p->describe << "\t" << p->type << "\t" << p->line << endl; 189 | p = p->next; 190 | } 191 | cout << endl 192 | << endl; 193 | } 194 | 195 | //单词扫描 196 | void scanner() 197 | { 198 | string filename; 199 | string word; 200 | int i; 201 | int line = 1; //行数 202 | 203 | fstream fin("test.txt", ios::in); 204 | if (!fin) 205 | { 206 | cout << "打开文件失败!" << endl; 207 | return; 208 | } 209 | else 210 | { 211 | cout << "打开文件成功!" << endl; 212 | } 213 | 214 | char ch; 215 | fin.get(ch); 216 | while (!fin.eof() && ch != '$') 217 | { 218 | i = 0; 219 | word.clear(); 220 | //以字母开头, 处理关键字或者标识符 221 | if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) 222 | { 223 | while ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) 224 | { 225 | word += ch; 226 | fin.get(ch); 227 | } 228 | 229 | //如果是保留字 230 | map::iterator it = keyMap.find(word); 231 | if (it != keyMap.end()) 232 | { 233 | createNewNode(word, KEY_DESC, it->second, line); 234 | } 235 | //如果是标识符 236 | else 237 | { 238 | // int addr_tmp = createNewIden(word, IDENTIFIER_DESC, IDENTIFIER, -1, line); 239 | createNewNode(word, IDENTIFIER_DESC, IDENTIFIER, line); 240 | } 241 | fin.seekg(-1, ios::cur); 242 | } 243 | //以数字开头 244 | else if (ch >= '0' && ch <= '9') 245 | { 246 | while (ch >= '0' && ch <= '9') 247 | { 248 | word += ch; 249 | fin.get(ch); 250 | } 251 | createNewNode(word, CONSTANT_DESC, CONSTANT, line); 252 | fin.seekg(-1, ios::cur); 253 | } 254 | else if (ch == '+') 255 | { 256 | createNewNode("+", OPE_DESC, ADD, line); 257 | } 258 | else if (ch == '-') 259 | { 260 | createNewNode("-", OPE_DESC, SUB, line); 261 | } 262 | else if (ch == '*') 263 | { 264 | createNewNode("*", OPE_DESC, MUL, line); 265 | } 266 | else if (ch == '/') 267 | { 268 | createNewNode("/", OPE_DESC, DIV, line); 269 | } 270 | else if (ch == '<') 271 | { 272 | fin.get(ch); 273 | if (ch == '=') 274 | { 275 | createNewNode("<=", OPE_DESC, LESS_EQUAL, line); 276 | } 277 | else 278 | { 279 | createNewNode("<", OPE_DESC, LESS_THAN, line); 280 | fin.seekg(-1, ios::cur); 281 | } 282 | } 283 | else if (ch == '>') 284 | { 285 | fin.get(ch); 286 | if (ch == '=') 287 | { 288 | createNewNode(">=", OPE_DESC, GRT_EQUAL, line); 289 | } 290 | else 291 | { 292 | createNewNode(">", OPE_DESC, GRT_THAN, line); 293 | fin.seekg(-1, ios::cur); 294 | } 295 | } 296 | else if (ch == '!') 297 | { 298 | fin.get(ch); 299 | if (ch == '=') 300 | { 301 | createNewNode("!=", OPE_DESC, NOT_EQUAL, line); 302 | } 303 | else 304 | { 305 | createNewError("!", EXCLAMATION_ERROR, EXCLAMATION_ERROR_NUM, line); 306 | fin.seekg(-1, ios::cur); 307 | } 308 | } 309 | else if (ch == '=') 310 | { 311 | fin.get(ch); 312 | if (ch == '=') 313 | { 314 | createNewNode("==", OPE_DESC, EQUAL, line); 315 | } 316 | else 317 | { 318 | createNewNode("=", OPE_DESC, ASSIGN, line); 319 | fin.seekg(-1, ios::cur); 320 | } 321 | } 322 | else if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') 323 | { 324 | if (ch == '\n') 325 | { 326 | line++; 327 | } 328 | } 329 | else if (ch == '(') 330 | { 331 | createNewNode("(", CLE_OPE_DESC, LEFT_BRACKET, line); 332 | } 333 | else if (ch == ')') 334 | { 335 | createNewNode(")", CLE_OPE_DESC, RIGHT_BRACKET, line); 336 | } 337 | else if (ch == '{') 338 | { 339 | createNewNode("{", CLE_OPE_DESC, LEFT_BOUNDER, line); 340 | } 341 | else if (ch == '}') 342 | { 343 | createNewNode("}", CLE_OPE_DESC, RIGHT_BOUNDER, line); 344 | } 345 | else if (ch == ';') 346 | { 347 | createNewNode(";", CLE_OPE_DESC, SEMICOLON, line); 348 | } 349 | else if (ch == '$') 350 | { 351 | createNewNode(";", CLE_OPE_DESC, DOLLAR, line); 352 | } 353 | else 354 | { 355 | createNewError(word, SYMBOL_ERROR, SYMBOL_ERROR_NUM, line); 356 | } 357 | 358 | fin.get(ch); 359 | } 360 | if (ch == '$') 361 | { 362 | word.clear(); 363 | word += ch; 364 | createNewNode(word, CLE_OPE_DESC, DOLLAR, line); 365 | } 366 | 367 | fin.close(); 368 | } 369 | 370 | //回收结点链与错误链 371 | void clear() 372 | { 373 | while (normalHead) 374 | { 375 | NormalNode *next = normalHead->next; 376 | delete normalHead; 377 | normalHead = next; 378 | } 379 | while (errorHead) 380 | { 381 | ErrorNode *next = errorHead->next; 382 | delete errorHead; 383 | errorHead = next; 384 | } 385 | } 386 | -------------------------------------------------------------------------------- /LexAnalyse.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | // 保留字 8 | #define MAIN 0 // main 9 | #define INT 1 // int 10 | #define RETURN 2 // return 11 | #define IF 3 // if 12 | #define ELSE 4 // else 13 | #define KEY_DESC "保留字" 14 | 15 | // 标识符 16 | #define IDENTIFIER 5 17 | #define IDENTIFIER_DESC "标识符" 18 | 19 | // 运算符 20 | #define ADD 6 // + 21 | #define SUB 7 // - 22 | #define MUL 8 // * 23 | #define DIV 9 // / 24 | #define EQUAL 10 // == 25 | #define LESS_THAN 11 // < 26 | #define LESS_EQUAL 12 // <= 27 | #define GRT_THAN 13 // > 28 | #define GRT_EQUAL 14 // >= 29 | #define NOT_EQUAL 15 // != 30 | #define ASSIGN 16 // = 31 | #define OPE_DESC "运算符" 32 | 33 | // 限界符 34 | #define LEFT_BRACKET 17 // ( 35 | #define RIGHT_BRACKET 18 // ) 36 | #define LEFT_BOUNDER 19 // { 37 | #define RIGHT_BOUNDER 20 // } 38 | #define SEMICOLON 21 // ; 39 | #define DOLLAR 22 // $ 40 | #define CLE_OPE_DESC "限界符" 41 | 42 | // 常量 43 | #define CONSTANT 23 // 无正负号整形常量 44 | #define CONSTANT_DESC "常数" 45 | 46 | // 错误类型 47 | #define INT_ERROR "不是常数" 48 | #define INT_ERROR_NUM 1 49 | #define EXCLAMATION_ERROR "!符号不合法" 50 | #define EXCLAMATION_ERROR_NUM 2 51 | #define SYMBOL_ERROR "符号不合法" 52 | #define SYMBOL_ERROR_NUM 3 53 | #define LEFT_BRACKET_ERROR "'('没有对应项" 54 | #define LEFT_BRACKET_ERROR_NUM 4 55 | #define RIGHT_BRACKET_ERROR "')'没有对应项" 56 | #define RIGHT_BRACKET_ERROR_NUM 5 57 | #define LEFT_BOUNDER_ERROR "'{'没有对应项" 58 | #define LEFT_BOUNDER_ERROR_NUM 6 59 | #define RIGHT_BOUNDER_ERROR "'}'没有对应项" 60 | #define RIGHT_BOUNDER_ERROR_NUM 7 61 | #define END_ERROR "未以$结尾" 62 | #define END_ERROR_NUM 8 63 | 64 | #define _NULL "null" 65 | 66 | map keyMap; 67 | map operMap; 68 | map limitMap; 69 | 70 | //保留字 | 标识符 | 运算符 | 常数 71 | struct NormalNode 72 | { 73 | string content; //内容 74 | string describe; //描述是保留字还是标识符 75 | int type; //种别码 76 | string iden_type; //标识符类型 77 | int line; //所在行数 78 | NormalNode *next; //下一个结点 79 | } * normalHead; //首结点 80 | 81 | //错误结点 82 | struct ErrorNode 83 | { 84 | string content; //错误内容 85 | string describe; //错误描述 86 | int type; 87 | int line; //所在行数 88 | ErrorNode *next; //下一个结点 89 | } * errorHead; //首结点 90 | 91 | void initKeyMap(); //初始化保留字字典 92 | void initOperMap(); //初始化运算符字典 93 | void initLimitMap(); //初始化限制符字典 94 | void initNode(); //初始化结点 95 | void createNewNode(string content, string descirbe, int type, int addr, int line); //插入一个结点 96 | void createNewError(string content, string descirbe, int type, int line); //插入一个错误结点 97 | void scanner(); //单词扫描 98 | void printNodeLink(); //输出结点信息 99 | void outputNodeLink(); //导出结点信息 100 | void printErrorLink(); //输出错误结点信息 101 | void clear(); //回收结点链与错误链 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C_Compiler_Project 2 | 3 | ## 简介 4 | 5 | 编译原理课程设计 - 文法设计 & 词法分析 & LL(1)语法分析 & 语义分析(语法制导翻译) 6 | 7 | ## 文法设计Grammar 8 | 9 | ### 终结符 10 | 11 | `main` `int` `if` `else` `return` `+` `-` `*` `/` `=` `equal` `less_than` `less_euqal` `great_than` `great_equal` `not_equal` `(` `)` `{` `}` `id` `digit` `;` `$` 12 | 13 | ### 非终结符 14 | 15 | `<程序>` `` `<返回类型>` `<变量类型>` `<复合语句>` `<语句序列>` `<语句>` `<语句递归>` `<定义语句>` `<赋初值>` `<赋值语句>` `<条件语句>` `<布尔表达式>` `<表达式>` `<项>` `<项递归>` `<因式>` `<因式递归>` `<关系运算符>` `<标识符>` `<无正负号常量>` 16 | 17 | ### 文法产生式 18 | 19 | | 非终结符命名 | 产生式 | 20 | | :------------------: | :------------------------------------------------------------------------------------: | 21 | | program | <程序> ::= $ | 22 | | main_fun | ::= <返回类型> main ( ) <复合语句> | 23 | | return_type | <返回类型> ::= <变量类型> | 24 | | var_type | <变量类型> ::= int | 25 | | struct_statement | <复合语句> ::= { <语句序列> } | 26 | | statements_list | <语句序列> ::= <语句> <语句递归> \| ε | 27 | | statement | <语句> ::= <定义语句> \| <赋值语句> \| <条件语句> \| <复合语句> \| return <表达式> ; | 28 | | statements_recursive | <语句递归> ::= <语句> <语句递归> \| ε | 29 | | define_statement | <定义语句> ::= <变量类型> <标识符> <赋初值> ; | 30 | | assign_default | <赋初值> ::= = <表达式> \| ε | 31 | | assign_statement | <赋值语句> ::= <标识符> = <表达式>; | 32 | | condition_statement | <条件语句> ::= if ( <布尔表达式> ) <复合语句> else <复合语句> | 33 | | bool_expression | <布尔表达式> ::= <表达式> <关系运算符> <表达式> | 34 | | expression | <表达式> ::= <项> <项递归> | 35 | | item | <项> ::= <因式> <因式递归> | 36 | | items_recursive | <项递归> ::= + <项> <项递归> \| - <项> <项递归> \| ε | 37 | | factor_recursive | <因式递归> ::= * <因式> <因式递归> \| / <因式> <因式递归> \| ε | 38 | | factor | <因式> ::= <标识符> \| <无正负号常量> \| ( <表达式> ) | 39 | | relation_operator | <关系运算符> ::= equal \| less \| less_equal \| great_than \| great_equal \| not_equal | 40 | | _identifier | <标识符> ::= id | 41 | | unsigned_const | <无正负号常量> ::= digit | 42 | 43 | **注意:** 44 | 45 | 文法中以显式 `$` 作为结束符号. 46 | 47 | ## 词法分析LexAnalyse 48 | 49 | 词法分析依据以下的DFA进行分析: 50 | 51 | ```mermaid 52 | graph LR; 53 | 0(0)-- "空格或 \n 或\t" -->0; 54 | 0-- "字母" -->1(1); 55 | 1-- "数字/字母" -->1; 56 | 1-- "非字母且非数字" -->2((2)); 57 | 0-- "数字" -->3(3); 58 | 3-- "数字" -->3; 59 | 3-- "非数字" -->4((4)); 60 | 0-- "+" -->5((5)); 61 | 0-- "-" -->6((6)); 62 | 0-- "*" -->7((7)); 63 | 0-- "/" -->8((8)); 64 | 0-- "(" -->9((9)); 65 | 0-- ")" -->10((10)); 66 | 0-- "{" -->11((11)); 67 | 0-- "}" -->12((12)); 68 | 0-- ">" -->13((13)); 69 | 13-- "=" -->14((14)); 70 | 0-- "<" -->15((15)); 71 | 15-- "=" -->16((16)); 72 | 0-- "=" -->17((17)); 73 | 17-- "=" -->18((18)); 74 | 0-- "!" -->19(19); 75 | 19-- "!" -->20((20)); 76 | 0-- ";" -->21((21)); 77 | 0-- "$" -->22((22)); 78 | ``` 79 | 80 | ## 语法分析SynAnalyse 81 | 82 | ### First集 83 | 84 | | 非终结符 | First集合列表 | | | | | | 85 | | :------------: | :-----------: | :-------: | :--------: | :--------: | :---------: | :-------: | 86 | | <程序> | int | 87 | | | int | 88 | | <返回类型> | int | 89 | | <变量类型> | int | 90 | | <复合语句> | { | 91 | | <语句序列> | int | id | if | { | return | ε | 92 | | <语句> | int | id | if | { | return | 93 | | <语句递归> | int | id | if | { | return | ε | 94 | | <定义语句> | int | 95 | | <赋初值> | = | ε | 96 | | <赋值语句> | id | 97 | | <条件语句> | if | 98 | | <布尔表达式> | id | digit | ( | 99 | | <表达式> | id | digit | ( | 100 | | <项递归> | + | - | ε | 101 | | <项> | id | digit | ( | 102 | | <因式递归> | * | / | ε | 103 | | <因式> | id | digit | ( | 104 | | <关系运算符> | equal | less_than | less_equal | great_than | great_equal | not_equal | 105 | | <标识符> | id | 106 | | <无正负号常量> | digit | 107 | 108 | ### Follow集 109 | 110 | | 非终结符 | First集合列表 | | | | | | | | | | | | | 111 | | :------------: | :-----------: | :---: | :-------: | :--------: | :--------: | :---------: | :--------: | :---------: | :--------: | :---------: | :---------: | :-------: | :---: | 112 | | <程序> | 113 | | | $ | 114 | | <返回类型> | main | 115 | | <变量类型> | main | id | 116 | | <复合语句> | $ | 117 | | <语句序列> | } | 118 | | <语句> | int | id | if | { | return | } | 119 | | <语句递归> | } | 120 | | <定义语句> | int | id | if | { | return | } | 121 | | <赋初值> | ; | 122 | | <赋值语句> | int | id | if | { | return | } | 123 | | <条件语句> | int | id | if | { | return | } | 124 | | <布尔表达式> | ) | 125 | | <表达式> | ; | equal | less_than | less_equal | great_than | great_equal | not_equal | ) | 126 | | <项递归> | ; | equal | less_than | less_equal | great_than | great_equal | not_equal | ) | 127 | | <项> | + | - | ; | equal | less_than | less_equal | great_than | great_equal | not_equal | ) | 128 | | <因式递归> | + | - | ; | equal | less_than | less_equal | great_than | great_equal | not_equal | ) | 129 | | <因式> | * | / | + | - | ; | equal | less_than | less_equal | great_than | great_equal | not_equal | ) | 130 | | <关系运算符> | id | digit | ( | | | | 131 | | <标识符> | = | * | / | + | - | ; | equal | less_than | less_equal | great_than | great_equal | not_equal | ) | 132 | | <无正负号常量> | * | / | + | - | ; | equal | less_than | less_equal | great_than | great_equal | not_equal | ) | 133 | 134 | ### LL(1)分析表 135 | 136 | 略(可知本文法无冲突) 137 | 138 | ### 小结 139 | 140 | 受水平所限, First集与Follow集手动生成, 然后根据递归子程序生成语法分析程序. 141 | 142 | 若水平足够, 可考虑由程序生成First集与Follow集, 继而生成LL(1)分析表. 根据符号栈和单词栈进行语法分析. 143 | 144 | 一般来说, 在发现语法错误时无法继续进行下去. 换句话说, 只能识别一个语法错误. 本代码中加入了一些可能产生的语法错误预测, 在不影响后续处理的前提下尽可能发现更多的语法错误, 提高效率. 145 | 146 | ## 语义分析(语法制导翻译) 147 | 148 | 在语法分析的递归子程序基础上插入一系列动作, 由表达式转化成四元式中间代码(不采用三元式有一定考量, 对于 `if...else...` 语句块的跳转语句不明确). 149 | 150 | ### 四元式表现形式 151 | 152 | `(<语句号>) <动作> <第1个输入> <第二个输入> <输出>` 153 | 154 | **注意:** 155 | 156 | 1. 若某一单元格内无内容则使用下划线 `_` 表示; 157 | 158 | 2. 临时变量用 `Ti` 表示, 如第0个产生的临时变量记为 `T0` (代码中有临时变量回收机制). 159 | 160 | 示例如下(语句号为随机, 仅供示例): 161 | 162 | - 定义语句: `(1) assign int _ i` 表示标识符 `i` 定义为 `int` 类型 163 | 164 | - 逻辑运算: `(2) + i + 1 T0` 表示 `T0 = i + 1` 165 | 166 | - 赋值语句: `(3) = 1 _ i` 表示 `i = 1` 167 | 168 | - 条件判断: `(4) < i j T0` 表示 `T0 = i < j` 169 | 170 | - 非真跳转: `jne` 意为 `jump not equal true`, `(5) jne T0 _ (6)` 表示当T0为假时跳转到第6条语句 171 | -------------------------------------------------------------------------------- /SynAnalyse.cpp: -------------------------------------------------------------------------------- 1 | #include "LexAnalyse.h" 2 | #include "SynAnalyse.h" 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int line_bak; //normal结点每次移动前都进行行数备份, 最后1行出错时指明具体行数 9 | 10 | //mid_type结构提取内容提供给gen()生成四元式中间代码 11 | string mid2string(mid_type m) 12 | { 13 | if (m.isT == 1) 14 | { 15 | stringstream ss; 16 | ss << "T" << m.T_num; 17 | return ss.str(); 18 | } 19 | else if (m.isT == 0) 20 | { 21 | return m.node->content; 22 | } 23 | else 24 | { 25 | return _NULL; 26 | } 27 | } 28 | 29 | //创建新的标识符结点 30 | void createNewIden(NormalNode *p) 31 | { 32 | iden_map[p->content] = IdentifierNode(p->content, p->describe, p->type, "int", p->line); 33 | } 34 | 35 | //输出标识符表 36 | void printIdentLink() 37 | { 38 | cout << "****************************标识符表*****************************" << endl 39 | << endl; 40 | cout << setw(15) << "内容" 41 | << setw(15) << "描述" 42 | << "\t" 43 | << setw(3) << "种别码" 44 | << "\t" 45 | << setw(8) << "标识符类型" 46 | << "\t" 47 | << "行号" << endl; 48 | 49 | for (map::iterator it = iden_map.begin(); it != iden_map.end(); it++) 50 | { 51 | cout << setw(15) << it->second.content 52 | << setw(15) << it->second.describe << "\t" 53 | << setw(3) << it->second.type << "\t" 54 | << setw(8) << it->second.iden_type << "\t" 55 | << it->second.line << endl; 56 | } 57 | cout << endl 58 | << endl; 59 | } 60 | 61 | //导出标识符表 62 | void outputIdenLink() 63 | { 64 | ofstream fout("identifiers.txt"); 65 | if (!fout) 66 | { 67 | cout << "identifiers.txt打开失败!" << endl; 68 | return; 69 | } 70 | fout << "*****************************标识符表******************************" << endl 71 | << endl; 72 | fout << "内容" 73 | << "\t" 74 | << setw(10) << "描述" 75 | << "\t" 76 | << setw(3) << "种别码" 77 | << "\t" 78 | << setw(8) << "标识符类型" 79 | << "\t" 80 | << "行号" << endl; 81 | 82 | for (map::iterator p = iden_map.begin(); p != iden_map.end(); p++) 83 | { 84 | fout << p->second.content << "\t" 85 | << setw(10) << p->second.describe << "\t" 86 | << setw(3) << p->second.type << "\t" 87 | << setw(8) << p->second.iden_type << "\t\t" 88 | << p->second.line << endl; 89 | } 90 | fout << endl; 91 | 92 | cout << "identifiers.txt更新完成!" << endl; 93 | fout.close(); 94 | } 95 | 96 | /*以下为各个非终结符的递归子程序*/ 97 | //<程序> 98 | void program(NormalNode *&p) 99 | { 100 | if (p) 101 | { 102 | //符合first 103 | if (p->content == "int") 104 | { 105 | main_fun(p); 106 | if (p) 107 | { 108 | if (p->content == "$") 109 | { 110 | line_bak = p->line; 111 | p = p->next; 112 | cout << "语法分析完成!" << endl; 113 | return; 114 | } 115 | } 116 | else 117 | { 118 | cout << "第" << line_bak << "行错误: 程序应以$结束" << endl; 119 | } 120 | } 121 | else 122 | { 123 | cout << "第" << p->line << "行错误: 程序应以int开始" << endl; 124 | } 125 | } 126 | else 127 | { 128 | cout << "程序不能为空" << endl; 129 | } 130 | } 131 | 132 | // 133 | void main_fun(NormalNode *&p) 134 | { 135 | if (p) 136 | { 137 | if (p->content == "int") 138 | { 139 | return_type(p); 140 | if (p) 141 | { 142 | //符合first 143 | if (p->content == "main") 144 | { 145 | main_fun2: 146 | line_bak = p->line; 147 | p = p->next; 148 | if (p) 149 | { 150 | if (p->content == "(") 151 | { 152 | main_fun1: 153 | line_bak = p->line; 154 | p = p->next; 155 | if (p) 156 | { 157 | if (p->content == ")") 158 | { 159 | line_bak = p->line; 160 | p = p->next; 161 | struct_statement(p); 162 | } 163 | else 164 | { 165 | cout << "第" << p->line << "行错误: " << p->content << "应为\")\"" << endl; 166 | } 167 | } 168 | else 169 | { 170 | cout << "第" << line_bak << "行错误: (后需要)配对" << endl; 171 | } 172 | } 173 | else 174 | { 175 | cout << "第" << p->line << "行错误: main函数后应为\"(\"" << endl; 176 | } 177 | } 178 | else 179 | { 180 | cout << "第" << line_bak << "行错误: main函数后需要(" << endl; 181 | } 182 | } 183 | //出现跳过main函数名的错误 184 | else if (p->content == "(") 185 | { 186 | cout << "第" << p->line << "行错误: main函数应有函数名main" << endl; 187 | goto main_fun1; 188 | } 189 | //出现main函数名写错的错误 190 | else if (p->next && p->next->content == "(") 191 | { 192 | cout << "第" << p->line << "行错误: main函数应以main为函数名" << endl; 193 | goto main_fun2; 194 | } 195 | else 196 | { 197 | cout << "第" << p->line << "行错误: main函数应以main为函数名" << endl; 198 | } 199 | } 200 | else 201 | { 202 | cout << "第" << line_bak << "行错误: main函数需要函数名" << endl; 203 | } 204 | } 205 | else 206 | { 207 | cout << "第" << p->line << "行错误: main函数应以int为返回类型" << endl; 208 | } 209 | } 210 | else 211 | { 212 | cout << "第" << line_bak << "行错误: main函数需要返回类型" << endl; 213 | } 214 | } 215 | 216 | //<返回类型> 217 | void return_type(NormalNode *&p) 218 | { 219 | if (p) 220 | { 221 | if (p->content == "int") 222 | { 223 | var_type(p); 224 | } 225 | else 226 | { 227 | cout << "第" << p->line << "行错误: 返回类型应为int" << endl; 228 | } 229 | } 230 | else 231 | { 232 | cout << "第" << line_bak << "行错误: 函数需要返回类型" << endl; 233 | } 234 | } 235 | 236 | //<变量类型> 237 | void var_type(NormalNode *&p) 238 | { 239 | if (p) 240 | { 241 | if (p->content == "int") 242 | { 243 | line_bak = p->line; 244 | p = p->next; 245 | return; 246 | } 247 | else 248 | { 249 | cout << "第" << p->line << "行错误: 变量类型应为int" << endl; 250 | } 251 | } 252 | else 253 | { 254 | cout << "第" << line_bak << "行错误: 此时需要变量类型" << endl; 255 | } 256 | } 257 | 258 | //<复合语句> 259 | void struct_statement(NormalNode *&p) 260 | { 261 | if (p) 262 | { 263 | if (p->content == "{") 264 | { 265 | line_bak = p->line; 266 | p = p->next; 267 | statements_list(p); 268 | if (p) 269 | { 270 | if (p->content == "}") 271 | { 272 | line_bak = p->line; 273 | p = p->next; 274 | return; 275 | } 276 | else 277 | { 278 | cout << "第" << p->line << "行错误: " << p->content << "应为\"}\"" << endl; 279 | } 280 | } 281 | else 282 | { 283 | cout << "第" << line_bak << "行错误: 此时需要{" << endl; 284 | } 285 | } 286 | else 287 | { 288 | cout << "第" << p->line << "行错误: 复合语句应以{开始" << endl; 289 | } 290 | } 291 | else 292 | { 293 | cout << "第" << line_bak << "行错误: 此时需要{" << endl; 294 | } 295 | } 296 | 297 | //<语句序列> 298 | void statements_list(NormalNode *&p) 299 | { 300 | if (p) 301 | { 302 | if (p->content == "int" || p->content == "if" || p->content == "{" || p->content == "return" || p->describe == IDENTIFIER_DESC) 303 | { 304 | statement(p); 305 | statements_recursive(p); 306 | } 307 | else if (p->content == "}") 308 | { 309 | return; 310 | } 311 | else 312 | { 313 | cout << p->content << endl; 314 | cout << "第" << p->line << "行错误: 语句头不合法" << endl; 315 | } 316 | } 317 | else 318 | { 319 | cout << "第" << line_bak << "行错误: 此时需要语句头" << endl; 320 | } 321 | } 322 | 323 | //<语句> 324 | void statement(NormalNode *&p) 325 | { 326 | if (p) 327 | { 328 | if (p->content == "int") 329 | { 330 | define_statement(p); 331 | } 332 | else if (p->describe == IDENTIFIER_DESC) 333 | { 334 | assign_statement(p); 335 | } 336 | else if (p->content == "if") 337 | { 338 | condition_statement(p); 339 | } 340 | else if (p->content == "{") 341 | { 342 | struct_statement(p); 343 | } 344 | else if (p->content == "return") 345 | { 346 | line_bak = p->line; 347 | p = p->next; 348 | expression(p); 349 | if (p) 350 | { 351 | if (p->content == ";") 352 | { 353 | line_bak = p->line; 354 | p = p->next; 355 | return; 356 | } 357 | else 358 | { 359 | cout << "第" << p->line << "行错误: " << p->content << "应为\";\"" << endl; 360 | } 361 | } 362 | else 363 | { 364 | cout << "第" << line_bak << "行错误: 此时应有\";\"" << endl; 365 | } 366 | } 367 | else 368 | { 369 | cout << "第" << p->line << "行错误: 没有合法语句头" << endl; 370 | } 371 | } 372 | else 373 | { 374 | cout << "第" << line_bak << "行错误: 语句序列里至少应有1条语句" << endl; 375 | } 376 | } 377 | 378 | //<语句递归> 379 | void statements_recursive(NormalNode *&p) 380 | { 381 | if (p) 382 | { 383 | if (p->content == "int" || p->describe == IDENTIFIER_DESC || p->content == "if" || p->content == "{" || p->content == "return" || p->describe == IDENTIFIER_DESC) 384 | { 385 | statement(p); 386 | statements_recursive(p); 387 | } 388 | else if (p->content == "}") 389 | { 390 | return; 391 | } 392 | else 393 | { 394 | cout << "第" << p->line << "行错误: " << p->content << "不合理, 此处应该是语句头或}" << endl; 395 | } 396 | } 397 | else 398 | { 399 | cout << "第" << line_bak << "行错误: 程序不完整" << endl; 400 | } 401 | } 402 | 403 | //<定义语句> 404 | void define_statement(NormalNode *&p) 405 | { 406 | if (p) 407 | { 408 | if (p->content == "int") 409 | { 410 | var_type(p); 411 | 412 | NormalNode *bak = p; //备份标识符位置 413 | _identifier(p); 414 | 415 | if (bak) 416 | { //声明, 标识符类型赋值 417 | if (iden_map.find(bak->content) == iden_map.end()) 418 | { 419 | createNewIden(bak); 420 | bak->iden_type = "int"; 421 | //声明标识符 四元式 422 | gen("assign", "int", "_", bak->content); 423 | } 424 | else 425 | { 426 | cout << "第" << p->line << "行错误: 标识符" << p->content << "已声明" << endl; 427 | } 428 | } 429 | else 430 | { 431 | cout << "第" << line_bak << "行错误: 标识符不存在, 无法声明" << endl; 432 | } 433 | 434 | mid_type _it; 435 | _it.isT = 0; 436 | _it.node = bak; 437 | 438 | mid_type _e = assign_default(p); 439 | if (_e.isT == -1) 440 | return; 441 | if (p) 442 | { 443 | if (p->content == ";") 444 | { 445 | if (_e.isT != 2) //假如返回中间体不为空 446 | { 447 | gen("=", mid2string(_e), "_", mid2string(_it)); 448 | 449 | //回收_e 450 | emit(_e); 451 | } 452 | line_bak = p->line; 453 | p = p->next; 454 | return; 455 | } 456 | else 457 | { 458 | cout << "第" << p->line << "行错误: " << p->content << "应为\";\"" << endl; 459 | } 460 | } 461 | else 462 | { 463 | cout << "第" << line_bak << "行错误: 此时应有\";\"" << endl; 464 | } 465 | } 466 | else 467 | { 468 | cout << "第" << p->line << "行错误: 没有合法语句头" << endl; 469 | } 470 | } 471 | else 472 | { 473 | cout << "第" << line_bak << "行错误: 定义语句应以变量类型开头" << endl; 474 | } 475 | } 476 | 477 | //<赋初值> 478 | mid_type assign_default(NormalNode *&p) 479 | { 480 | if (p) 481 | { 482 | mid_type _e; 483 | if (p->content == "=") 484 | { 485 | line_bak = p->line; 486 | p = p->next; 487 | _e = expression(p); 488 | if (_e.isT == -1) 489 | return error; 490 | else 491 | return _e; 492 | } 493 | else if (p->content == ";") 494 | { 495 | return null; 496 | } 497 | else 498 | { 499 | cout << "第" << p->line << "行错误: 此时需要给标识符赋初值或以;结尾" << endl; 500 | } 501 | } 502 | else 503 | { 504 | cout << "第" << line_bak << "行错误: 程序不完整" << endl; 505 | } 506 | return error; 507 | } 508 | 509 | //<赋值语句> 510 | void assign_statement(NormalNode *&p) 511 | { 512 | if (p) 513 | { 514 | if (p->describe == IDENTIFIER_DESC) 515 | { 516 | //判断标识符是否已声明 517 | if (iden_map.find(p->content) == iden_map.end()) 518 | { 519 | cout << "第" << p->line << "行错误: 标识符" << p->content << "尚未声明" << endl; 520 | } 521 | 522 | string _i = _identifier(p); //标识符参数 523 | if (p) 524 | { 525 | if (p->content == "=") 526 | { 527 | line_bak = p->line; 528 | p = p->next; 529 | mid_type _e = expression(p); //表达式参数 530 | if (_e.isT == -1) 531 | return; 532 | if (p) 533 | { 534 | if (p->content == ";") 535 | { 536 | line_bak = p->line; 537 | p = p->next; 538 | 539 | gen("=", mid2string(_e), "_", _i); 540 | 541 | //回收_e 542 | emit(_e); 543 | 544 | return; 545 | } 546 | else 547 | { 548 | cout << "第" << p->line << "行错误: " << p->content << "应为\";\"" << endl; 549 | } 550 | } 551 | else 552 | { 553 | cout << "第" << line_bak << "行错误: 此时应有\";\"" << endl; 554 | } 555 | } 556 | else 557 | { 558 | cout << "第" << p->line << "行错误: " << p->content << "应为\"=\"" << endl; 559 | } 560 | } 561 | else 562 | { 563 | cout << "第" << line_bak << "行错误: 此时应有\"+\"号" << endl; 564 | } 565 | } 566 | else 567 | { 568 | cout << "第" << p->line << "行错误: 此时应有标识符" << endl; 569 | } 570 | } 571 | else 572 | { 573 | cout << "第" << line_bak << "行错误: 程序不完整" << endl; 574 | } 575 | } 576 | 577 | //<条件语句> 578 | void condition_statement(NormalNode *&p) 579 | { 580 | if (p) 581 | { 582 | if (p->content == "if") 583 | { 584 | line_bak = p->line; 585 | p = p->next; 586 | if (p) 587 | { 588 | if (p->content == "(") 589 | { 590 | line_bak = p->line; 591 | p = p->next; 592 | mid_type _b_e = bool_expression(p); 593 | if (_b_e.isT == -1) 594 | return; 595 | if (p) 596 | { 597 | if (p->content == ")") 598 | { 599 | line_bak = p->line; 600 | p = p->next; 601 | 602 | CodeNode &else_from = gen("jne", mid2string(_b_e), "_", ""); 603 | 604 | //回收_b_e 605 | emit(_b_e); 606 | 607 | struct_statement(p); 608 | CodeNode &if_end_to = gen("j", "_", "_", ""); 609 | if (p) 610 | { 611 | if (p->content == "else") 612 | { 613 | //回填else_from 614 | stringstream ss; 615 | ss << "(" << code.back().line + 1 << ")"; 616 | else_from.result = ss.str(); 617 | 618 | line_bak = p->line; 619 | p = p->next; 620 | struct_statement(p); 621 | 622 | //回填if_end_to 623 | ss.str(""); 624 | ss << "(" << code.back().line + 1 << ")"; 625 | if_end_to.result = ss.str(); 626 | } 627 | else 628 | { 629 | cout << "第" << p->line << "行错误: " << p->content << "应为else" << endl; 630 | } 631 | } 632 | else 633 | { 634 | cout << "第" << line_bak << "行错误: 此时应有else" << endl; 635 | } 636 | } 637 | else 638 | { 639 | cout << "第" << p->line << "行错误: " << p->content << "应为\")\"" << endl; 640 | } 641 | } 642 | else 643 | { 644 | cout << "第" << line_bak << "行错误: 此时应有)" << endl; 645 | } 646 | } 647 | else 648 | { 649 | cout << "第" << p->line << "行错误: " << p->content << "应为\"(\"" << endl; 650 | } 651 | } 652 | else 653 | { 654 | cout << "第" << line_bak << "行错误: 此时应有(" << endl; 655 | } 656 | } 657 | else 658 | { 659 | cout << "第" << p->line << "行错误: " << p->content << "应为if" << endl; 660 | } 661 | } 662 | else 663 | { 664 | cout << "第" << line_bak << "行错误: 此时应有if" << endl; 665 | } 666 | } 667 | 668 | //<布尔表达式> 669 | mid_type bool_expression(NormalNode *&p) 670 | { 671 | if (p) 672 | { 673 | if (p->describe == IDENTIFIER_DESC || p->describe == CONSTANT_DESC || p->content == "(") 674 | { 675 | mid_type _e1 = expression(p); 676 | mid_type _r = relation_operator(p); 677 | mid_type _e2 = expression(p); 678 | if (_e1.isT == -1 || _r.isT == -1 || _e2.isT == -1) 679 | return error; 680 | 681 | mid_type res = newTemp(); 682 | gen(mid2string(_r), mid2string(_e1), mid2string(_e2), mid2string(res)); 683 | return res; 684 | } 685 | else 686 | { 687 | cout << "第" << p->line << "行错误: " << p->content << "应为表达式" << endl; 688 | } 689 | } 690 | else 691 | { 692 | cout << "第" << line_bak << "行错误: 此时应有表达式" << endl; 693 | } 694 | return error; 695 | } 696 | 697 | //<表达式> 698 | mid_type expression(NormalNode *&p) 699 | { 700 | if (p) 701 | { 702 | if (p->describe == IDENTIFIER_DESC || p->describe == CONSTANT_DESC || p->content == "(") 703 | { 704 | mid_type _it = item(p); 705 | if (_it.isT == -1) 706 | return error; 707 | else 708 | return items_recursive(p, _it); 709 | } 710 | else 711 | { 712 | cout << "第" << p->line << "行错误: " << p->content << "应为项" << endl; 713 | } 714 | } 715 | else 716 | { 717 | cout << "第" << line_bak << "行错误: 此时应有项" << endl; 718 | } 719 | return error; 720 | } 721 | 722 | //<项递归> 723 | mid_type items_recursive(NormalNode *&p, mid_type front) 724 | { 725 | if (p) 726 | { 727 | if (p->content == "+" || p->content == "-") 728 | { 729 | string op_bak = p->content; 730 | line_bak = p->line; 731 | p = p->next; 732 | 733 | mid_type back = item(p); 734 | if (back.isT == -1) 735 | return error; 736 | 737 | mid_type res = newTemp(); 738 | //生成四元式 739 | gen(op_bak, mid2string(front), mid2string(back), mid2string(res)); 740 | 741 | //回收front、back 742 | emit(front); 743 | emit(back); 744 | 745 | return items_recursive(p, res); 746 | } 747 | else if (p->content == ";" || p->content == ")" || p->content == "==" || p->content == "<" || p->content == "<=" || p->content == ">" || p->content == ">=" || p->content == "!=") 748 | { 749 | return front; 750 | } 751 | else 752 | { 753 | cout << "第" << p->line << "行错误: 此时应有更多的项或结束" << endl; 754 | } 755 | } 756 | else 757 | { 758 | cout << "第" << line_bak << "行错误: 项不完整" << endl; 759 | } 760 | return error; 761 | } 762 | 763 | //<项> 764 | mid_type item(NormalNode *&p) 765 | { 766 | if (p) 767 | { 768 | if (p->describe == IDENTIFIER_DESC || p->describe == CONSTANT_DESC || p->content == "(") 769 | { 770 | mid_type _it = factor(p); 771 | if (_it.isT == -1) 772 | return error; 773 | else 774 | return factor_recursive(p, _it); 775 | } 776 | else 777 | { 778 | cout << "第" << p->line << "行错误: " << p->content << "应为因式" << endl; 779 | } 780 | } 781 | else 782 | { 783 | cout << "第" << line_bak << "行错误: 此时应有因式" << endl; 784 | } 785 | return error; 786 | } 787 | 788 | //<因式递归> 789 | mid_type factor_recursive(NormalNode *&p, mid_type front) 790 | { 791 | if (p) 792 | { 793 | if (p->content == "*" || p->content == "/") 794 | { 795 | string op_bak = p->content; 796 | line_bak = p->line; 797 | p = p->next; 798 | mid_type back = factor(p); 799 | if (back.isT == -1) 800 | return error; 801 | 802 | mid_type res = newTemp(); 803 | gen(op_bak, mid2string(front), mid2string(back), mid2string(res)); 804 | 805 | //回收front、back 806 | emit(front); 807 | emit(back); 808 | 809 | return factor_recursive(p, res); 810 | } 811 | else if (p->content == "+" || p->content == "-" || p->content == ";" || p->content == ")" || p->content == "==" || p->content == "<" || p->content == "<=" || p->content == ">" || p->content == ">=" || p->content == "!=") 812 | { 813 | return front; 814 | } 815 | else 816 | { 817 | cout << "第" << p->line << "行错误: 此时应有更多的因式或结束多项式(或许是少了;)" << endl; 818 | } 819 | } 820 | else 821 | { 822 | cout << "第" << line_bak << "行错误: 因式不完整" << endl; 823 | } 824 | return error; 825 | } 826 | 827 | //<因式> 828 | mid_type factor(NormalNode *&p) 829 | { 830 | if (p) 831 | { 832 | if (p->describe == IDENTIFIER_DESC) 833 | { 834 | NormalNode *p_bak = p; 835 | 836 | //判断标识符是否已声明 837 | if (iden_map.find(p->content) == iden_map.end()) 838 | { 839 | cout << "第" << p->line << "行错误: 标识符" << p->content << "尚未声明" << endl; 840 | } 841 | 842 | _identifier(p); 843 | 844 | mid_type ans; 845 | ans.node = p_bak; 846 | ans.isT = 0; 847 | return ans; 848 | } 849 | else if (p->describe == CONSTANT_DESC) 850 | { 851 | NormalNode *p_bak = p; 852 | 853 | unsigned_const(p); 854 | 855 | mid_type ans; 856 | ans.node = p_bak; 857 | ans.isT = 0; 858 | return ans; 859 | } 860 | else if (p->content == "(") 861 | { 862 | line_bak = p->line; 863 | p = p->next; 864 | mid_type ans = expression(p); 865 | if (p) 866 | { 867 | if (p->content == ")") 868 | { 869 | line_bak = p->line; 870 | p = p->next; 871 | return ans; 872 | } 873 | else 874 | { 875 | cout << "第" << p->line << "行错误: " << p->content << "应为\")\"" << endl; 876 | } 877 | } 878 | else 879 | { 880 | cout << "第" << line_bak << "行错误: 此时应有)" << endl; 881 | } 882 | } 883 | else 884 | { 885 | cout << "第" << p->line << "行错误: " << p->content << "作为因式不合法" << endl; 886 | } 887 | } 888 | else 889 | { 890 | cout << "第" << line_bak << "行错误: 因式不完整" << endl; 891 | } 892 | return error; 893 | } 894 | 895 | //<关系运算符> 896 | mid_type relation_operator(NormalNode *&p) 897 | { 898 | if (p) 899 | { 900 | if (p->content == "==" || p->content == "<" || p->content == "<=" || p->content == ">" || p->content == ">=" || p->content == "!=") 901 | { 902 | mid_type res; 903 | res.isT = 0; 904 | res.node = p; 905 | 906 | line_bak = p->line; 907 | p = p->next; 908 | 909 | return res; 910 | } 911 | else 912 | { 913 | cout << "第" << p->line << "行错误: " << p->content << "应为关系运算符" << endl; 914 | } 915 | } 916 | else 917 | { 918 | cout << "第" << line_bak << "行错误: 此时应有关系运算符" << endl; 919 | } 920 | return error; 921 | } 922 | 923 | //<标识符> 924 | string _identifier(NormalNode *&p) 925 | { 926 | if (p) 927 | { 928 | if (p->describe == IDENTIFIER_DESC) 929 | { 930 | line_bak = p->line; 931 | NormalNode *p_bak = p; 932 | p = p->next; 933 | return p_bak->content; 934 | } 935 | else 936 | { 937 | cout << "第" << p->line << "行错误: " << p->content << "应为标识符" << endl; 938 | } 939 | } 940 | else 941 | { 942 | cout << "第" << line_bak << "行错误: 此时应有标识符" << endl; 943 | } 944 | return _NULL; 945 | } 946 | 947 | //<无正负号常量> 948 | void unsigned_const(NormalNode *&p) 949 | { 950 | if (p) 951 | { 952 | if (p->describe == CONSTANT_DESC) 953 | { 954 | line_bak = p->line; 955 | p = p->next; 956 | return; 957 | } 958 | else 959 | { 960 | cout << "第" << p->line << "行错误: " << p->content << "应为常量" << endl; 961 | } 962 | } 963 | else 964 | { 965 | cout << "第" << line_bak << "行错误: 此时应有常量" << endl; 966 | } 967 | } 968 | 969 | //获取新的中间变量Ti 970 | mid_type newTemp() 971 | { 972 | for (int i = 0; i < MAXT; i++) 973 | { 974 | if (T[i] == false) 975 | { 976 | T[i] = true; 977 | mid_type ans; 978 | ans.node = NULL; 979 | ans.isT = 1; 980 | ans.T_num = i; 981 | return ans; 982 | } 983 | } 984 | return error; 985 | } 986 | 987 | //回收中间变量Ti 988 | void emit(mid_type m) 989 | { 990 | //如果是中间变量 991 | if (m.isT == 1) 992 | { 993 | T[m.T_num] = false; 994 | } 995 | } 996 | 997 | //生成四元式中间代码 998 | CodeNode &gen(string opt, string arg1, string arg2, string result) 999 | { 1000 | static int static_line = 0; 1001 | code.push_back(CodeNode(++static_line, opt, arg1, arg2, result)); 1002 | return code.back(); 1003 | } 1004 | 1005 | //输出四元式中间代码 1006 | void printCode() 1007 | { 1008 | cout << "中间代码如下: " << endl; 1009 | for (list::iterator it = code.begin(); it != code.end(); ++it) 1010 | { 1011 | cout << "(" << it->line << ")" 1012 | << "\t" << it->opt << "\t" << it->arg1 << "\t" << it->arg2 << "\t" << it->result << endl; 1013 | } 1014 | } 1015 | 1016 | //导出四元式中间代码 1017 | void outputCode() 1018 | { 1019 | ofstream fout("midCode.txt"); 1020 | if (!fout) 1021 | { 1022 | cout << "midCode.txt打开失败!" << endl; 1023 | return; 1024 | } 1025 | for (list::iterator it = code.begin(); it != code.end(); ++it) 1026 | { 1027 | fout << "(" << it->line << ")" 1028 | << "\t" << it->opt << "\t" << it->arg1 << "\t" << it->arg2 << "\t" << it->result << endl; 1029 | } 1030 | 1031 | fout.close(); 1032 | } -------------------------------------------------------------------------------- /SynAnalyse.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "LexAnalyse.h" 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | #define MAXT 100 10 | 11 | //标识符结点 12 | struct IdentifierNode 13 | { 14 | string content; //内容 15 | string describe; //描述 16 | int type; //种别码 17 | string iden_type; //标识符类型 18 | int line; //所在行数 19 | 20 | IdentifierNode() {} 21 | IdentifierNode(string c, string d, int t, string i, int l) : content(c), describe(d), type(t), iden_type(i), line(l) {} 22 | }; 23 | 24 | //标识符表 25 | map iden_map; 26 | 27 | //中间点 28 | struct mid_type 29 | { 30 | NormalNode *node; //如果是标识符或常量, 则指向结点 31 | int T_num; //如果是中间变量, 则代表中间变量序号 32 | int isT; //1: 中间变量; 0: 单词结点(标识符/常量/运算符); -1:error; 2: 空 33 | 34 | } error, null; 35 | 36 | bool T[MAXT]; //中间变量占用 37 | 38 | //四元式中间代码中间代码 39 | struct CodeNode 40 | { 41 | int line; 42 | string opt; 43 | string arg1, arg2; 44 | string result; 45 | CodeNode(int l, string o, string a1, string a2, string r) : line(l), opt(o), arg1(a1), arg2(a2), result(r) {} 46 | }; 47 | 48 | //四元式代码链 49 | list code; 50 | 51 | string mid2string(mid_type m); //mid_type结构提取内容提供给gen()生成四元式中间代码 52 | void createNewIden(NormalNode *p); //创建新的标识符结点 53 | void printIdentLink(); //输出标识符表 54 | void outputIdenLink(); //导出标识符表 55 | 56 | /*以下为各个非终结符的递归子程序*/ 57 | void program(NormalNode *&p); //<程序> 58 | void main_fun(NormalNode *&p); // 59 | void return_type(NormalNode *&p); //<返回类型> 60 | void var_type(NormalNode *&p); //<变量类型> 61 | void struct_statement(NormalNode *&p); //<复合语句> 62 | void statements_list(NormalNode *&p); //<语句序列> 63 | void statement(NormalNode *&p); //<语句> 64 | void statements_recursive(NormalNode *&p); //<语句递归> 65 | void define_statement(NormalNode *&p); //<定义语句> 66 | mid_type assign_default(NormalNode *&p); //<赋初值> 67 | void assign_statement(NormalNode *&p); //<赋值语句> 68 | void condition_statement(NormalNode *&p); //<条件语句> 69 | mid_type bool_expression(NormalNode *&p); //<布尔表达式> 70 | mid_type expression(NormalNode *&p); //<表达式> 71 | mid_type items_recursive(NormalNode *&p, mid_type front); //<项递归> 72 | mid_type item(NormalNode *&p); //<项> 73 | mid_type factor_recursive(NormalNode *&p, mid_type front); //<因式递归> 74 | mid_type factor(NormalNode *&p); //<因式> 75 | mid_type relation_operator(NormalNode *&p); //<关系运算符> 76 | string _identifier(NormalNode *&p); //<标识符> 77 | void unsigned_const(NormalNode *&p); //<无正负号常量> 78 | 79 | mid_type newTemp(); //获取新的中间变量Ti 80 | void emit(mid_type m); //回收中间变量Ti 81 | CodeNode &gen(string opt, string arg1, string arg2, string result); //生成四元式中间代码 82 | void printCode(); //输出四元式中间代码 83 | void outputCode(); //导出四元式中间代码 84 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "LexAnalyse.cpp" 2 | #include "SynAnalyse.cpp" 3 | #include 4 | 5 | int main() 6 | { 7 | //词法分析部分 8 | initKeyMap(); 9 | initOperMap(); 10 | initLimitMap(); 11 | initNode(); 12 | 13 | cout << "词法分析结果如下: " << endl; 14 | scanner(); 15 | 16 | printNodeLink(); 17 | outputNodeLink(); 18 | printErrorLink(); 19 | 20 | //单词连指向第一个单词 21 | NormalNode *p = normalHead->next; 22 | //刷新中间变量占用 23 | memset(T, 0, sizeof(T)); 24 | //定义中间点特殊情况 25 | error.isT = -1; 26 | null.isT = 2; 27 | 28 | //语法分析部分 29 | cout << "语法(制导翻译)分析结果如下: " << endl; 30 | program(p); 31 | 32 | //输出并导出标识符表 33 | printIdentLink(); 34 | outputIdenLink(); 35 | 36 | //输出并导出更新后的单词分析表 37 | printNodeLink(); 38 | outputNodeLink(); 39 | 40 | //输出并导出四元式代码 41 | printCode(); 42 | outputCode(); 43 | 44 | clear(); 45 | return 0; 46 | } --------------------------------------------------------------------------------