├── Compiler41.vcxproj ├── Compiler41.vcxproj.filters ├── Defination.h ├── LoadFile.h ├── README.md ├── Sentence.h ├── grammar.h ├── main.cpp ├── test.cpp └── 文法.md /Compiler41.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {27B81907-180F-47C0-A6B7-685AA986163C} 23 | Win32Proj 24 | Compiler41 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | true 92 | 93 | 94 | Console 95 | true 96 | 97 | 98 | 99 | 100 | 101 | 102 | Level3 103 | Disabled 104 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 105 | true 106 | 107 | 108 | Console 109 | true 110 | 111 | 112 | 113 | 114 | Level3 115 | 116 | 117 | MaxSpeed 118 | true 119 | true 120 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 121 | true 122 | 123 | 124 | Console 125 | true 126 | true 127 | true 128 | 129 | 130 | 131 | 132 | Level3 133 | 134 | 135 | MaxSpeed 136 | true 137 | true 138 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 139 | true 140 | 141 | 142 | Console 143 | true 144 | true 145 | true 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /Compiler41.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 头文件 26 | 27 | 28 | 29 | 30 | 源文件 31 | 32 | 33 | -------------------------------------------------------------------------------- /Defination.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* ******************************************************* */ 3 | /* *******************用于存放全局宏定义******************** */ 4 | /* ******************************************************** */ 5 | 6 | #define ERROR 0 7 | #define INT 1 8 | #define LONG_INT 2 9 | #define FLOAT 3 10 | #define DOUBLE 4 11 | #define VOID 5 12 | #define CHAR 31 13 | /* 类型 */ 14 | 15 | #define ADD 6 16 | #define MINUS 7 17 | #define MULT 8 18 | #define DIV 9 19 | /* 算术运算符 */ 20 | 21 | #define AND 10 22 | #define OR 11 23 | #define NOT 12 24 | #define LESS 13 25 | #define MORE 14 26 | #define LESS_EQU 15 27 | #define MORE_EQU 16 28 | #define DOUBLE_EQU 17 29 | /* 逻辑运算符 */ 30 | 31 | #define SYNX 18 32 | #define NUMBER 19 33 | #define USE_FUNCTION 20 34 | #define CHAR_CONST 34//字符型常量 35 | /* 变量名 常数 函数调用 */ 36 | 37 | #define EQUAL 21 38 | #define LINGER 22//逗号 39 | #define LEFT 23 40 | #define RIGHT 24 41 | #define LEFT_BRACE 25 42 | #define RIGHT_BRACE 26 43 | #define SINGLE_QOUTE 32//单引号 44 | #define DOUBLE_QOUTE 33//双引号 45 | #define SINGLE_SYB 35//单字符标志,比如'$' 46 | /* 其他符号 */ 47 | 48 | #define IF 27 49 | #define ELSE 28 50 | #define WHILE 29 51 | #define RETURN 30 52 | /* 其他关键字 */ 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /LoadFile.h: -------------------------------------------------------------------------------- 1 | /* ********************************************** */ 2 | /* *******************实现文件读写相关功能*********** */ 3 | /* *************************************************** */ 4 | #pragma once 5 | #include "fstream" 6 | #include "string" 7 | #include "iostream" 8 | using namespace std; 9 | 10 | #include "Sentence.h" 11 | 12 | void readFile(string *filename, string* fileContent) 13 | //功能:读取一个文件 14 | //filename是调用函数中保存该文件名的string 15 | //fileContent是调用函数中保存文本内容的string 16 | { 17 | cout << "请输入文件名:" << endl; 18 | cin >> *filename; 19 | 20 | ifstream in; 21 | in.open(*filename); 22 | char temp[524288] = { 0 }; 23 | in.getline(temp, 524288, 0); 24 | (*fileContent).append(temp); 25 | (*fileContent).append("\n"); 26 | } 27 | 28 | void partLine(vector* file, string filename, string fileContent) 29 | //将一个文本按照换行符分行 30 | //file是调用函数中的保存每一行文本的Sentence数组 31 | //filename是用于初始化Setence类对象的文件名 32 | //fileContent是文本原始内容 33 | { 34 | int front = 0, back = 0, line = 1; 35 | while(fileContent.size() > back) 36 | { 37 | if(fileContent.at(back) == '\n') 38 | { 39 | char temp[100] = { 0 }; 40 | for(int i = front; i < back; i ++) 41 | { 42 | temp[i - front] = fileContent.at(i); 43 | // cout << temp[i]; 44 | } 45 | Sentence tempS(line, filename, temp); 46 | //cout << temp << endl; 47 | (*file).push_back(tempS); 48 | line ++; 49 | back ++; 50 | if(back == fileContent.size() - 1 || back == fileContent.size()) 51 | { 52 | return; 53 | } 54 | /* 溢出边界检查 */ 55 | while(fileContent.at(back) == '\n') 56 | { 57 | line ++; 58 | back ++; 59 | } 60 | /* 为了解决多个换行符相邻的情况 */ 61 | front = back; 62 | } 63 | else 64 | { 65 | back ++; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Compiler41 2 | 东北大学(中国)计算机系编译原理课程设计 3 | Compiler41 Project 4 | 5 | 创建于2017年11月5日,辽宁沈阳; 6 | 7 | 该项目为东北大学计算机系编译原理课设,将实现以下功能: 8 | 1. C语言核心词法分析器; 9 | 2. C语言核心语法分析器; 10 | 3. 支持函数调用和#include头文件; 11 | 4. 支持的数据类型为整形、浮点、长整型和双精度型; 12 | 5. 暂不支持指针和数组数据类型; 13 | 6. 实现一个模拟的内存分配和管理功能; 14 | 15 | 创建者:温冬 16 | 17 | 参与开发者: 18 | 温冬 19 | 20 | 罗艺博 21 | 22 | 王新东 23 | 24 | 朱强 25 | 26 | 马占晓 27 | -------------------------------------------------------------------------------- /Sentence.h: -------------------------------------------------------------------------------- 1 | /* ************************************************* */ 2 | /* Sentence类用于保存每一行语句以及对应的token串和词法单元 */ 3 | /* ************************************************** */ 4 | #pragma once 5 | 6 | #include "iostream" 7 | #include "vector" 8 | #include "string" 9 | #include"regex" 10 | using namespace std; 11 | 12 | #include "Defination.h" 13 | //partition的所用变量 14 | //判断是否是括号 15 | bool isBracket(char a); 16 | int isLogic(char a);// 0是(){} 1是- 2是算符 3不是算符 17 | int isNumber(char a); 18 | //判断字母 下划线 19 | bool isLetter(char a); 20 | //开头是否是数字 21 | int isPrefixNumber(char head); 22 | 23 | //前缀符 11 15 24 | string prefix[] = { "-", "+","*","/","=",">","<","&","|", "," ,"!" , "(" ,")" ,"{","}" ,"'","#","@","$","%","\\" , "?" , ":","_" };//11后是括号 25 | //数字符 26 | string numberPrefix[] = { "-","0","1","2","3","4","5","6","7","8","9" }; 27 | class Sentence 28 | { 29 | public: 30 | string fileName;//所在文件 31 | int line;//所在行数 32 | string thisLine; 33 | vector sentencePart; 34 | vector partType; 35 | 36 | 37 | Sentence() 38 | /* 默认构造函数 */ 39 | { 40 | ; 41 | } 42 | 43 | Sentence(int l, string f, string s) 44 | /* 初始化行数和内容 */ 45 | { 46 | line = l; 47 | thisLine = s; 48 | fileName = f; 49 | } 50 | 51 | void partition();//分隔一行句子中的所有词法成分 52 | void showThisLine();//输出thisLine 53 | void showSentencePart();//输出sentencePart 54 | void showPartType();//输出token类型 55 | 56 | 57 | int anaPartFirstTime() 58 | { 59 | int i,k,state; 60 | for (i = 0; i < sentencePart.size(); i++) 61 | { 62 | state=1; 63 | string str=sentencePart[i]; 64 | if (sentencePart[i] == "int") 65 | partType.push_back(INT); 66 | else if (sentencePart[i] == "long") 67 | partType.push_back(LONG_INT); 68 | else if (sentencePart[i] == "float") 69 | partType.push_back(FLOAT); 70 | else if (sentencePart[i] == "double") 71 | partType.push_back(DOUBLE); 72 | else if (sentencePart[i] == "void") 73 | partType.push_back(VOID); 74 | else if (sentencePart[i] == "char") 75 | partType.push_back(CHAR); 76 | else if (sentencePart[i] == "+") 77 | partType.push_back(ADD); 78 | else if (sentencePart[i] == "-") 79 | partType.push_back(MINUS); 80 | else if (sentencePart[i] == "*") 81 | partType.push_back(MULT); 82 | else if (sentencePart[i] == "/") 83 | partType.push_back(DIV); 84 | else if (sentencePart[i] == "&") 85 | partType.push_back(AND); 86 | else if (sentencePart[i] == "|") 87 | partType.push_back(OR); 88 | else if (sentencePart[i] == "!") 89 | partType.push_back(NOT); 90 | else if (sentencePart[i] == "<") 91 | partType.push_back(LESS); 92 | else if (sentencePart[i] == ">") 93 | partType.push_back(MORE); 94 | else if (sentencePart[i] == "<=") 95 | partType.push_back(LESS_EQU); 96 | else if (sentencePart[i] == ">=") 97 | partType.push_back(MORE_EQU); 98 | else if (sentencePart[i] == "==") 99 | partType.push_back(DOUBLE_EQU); 100 | else if (sentencePart[i] == "=") 101 | partType.push_back(EQUAL); 102 | else if (sentencePart[i] == ",") 103 | partType.push_back(LINGER); 104 | 105 | else if ((sentencePart[i][0] >= '0' &&sentencePart[i][0] <= '9' )|| sentencePart[i][0] == '.' || sentencePart[i][0] == '-') 106 | { 107 | partType.push_back(NUMBER); 108 | regex REGEX("^-?[1-9]\\d+(\.\\d+)?(e-?\\d+)?$"); 109 | if (!regex_match(sentencePart[i], REGEX)) 110 | return(ERROR); 111 | } 112 | 113 | 114 | //如果是单独的括号 隔开后2个元素是非右括号算符 115 | else if (sentencePart[i] == "(" && sentencePart[i+2]!=")" ) 116 | { 117 | partType.push_back(LEFT); 118 | } 119 | //如果是一起的算到数字里面 隔开后2个元素是括号算符 120 | else if (sentencePart[i] == "(" && sentencePart[i+2]==")" ) 121 | { 122 | //判断括号的内容 123 | if(isNumber(sentencePart[i+1][0]))//开头是数字 124 | partType.push_back(NUMBER); 125 | else//是变量 126 | partType.push_back(SYNX); 127 | 128 | i=i+2; 129 | } 130 | //单独的括号 前2个的元素不是括号 131 | else if (sentencePart[i] == ")" && sentencePart[i-2]!= "(" ) 132 | { 133 | partType.push_back(RIGHT); 134 | } 135 | else if (sentencePart[i] == ")" && sentencePart[i-2]== "(" ) 136 | { 137 | ; 138 | } 139 | else if (sentencePart[i] == "{") 140 | partType.push_back(LEFT_BRACE); 141 | else if (sentencePart[i] == "}") 142 | partType.push_back(RIGHT_BRACE); 143 | else if (sentencePart[i] == "if") 144 | partType.push_back(IF); 145 | else if (sentencePart[i] == "else") 146 | partType.push_back(ELSE); 147 | else if (sentencePart[i] == "while") 148 | partType.push_back(WHILE); 149 | else if (sentencePart[i] == "return") 150 | partType.push_back(RETURN); 151 | else if (sentencePart[i] == "\'") 152 | //判断字符常量类型 153 | { 154 | partType.push_back(SINGLE_QOUTE); 155 | if (sentencePart[i + 1].size() == 1 && sentencePart[i + 2] == "\'") 156 | { 157 | sentencePart[i].append(sentencePart[i + 1]); 158 | sentencePart[i].append(sentencePart[i + 2]); //融合 159 | sentencePart.erase(sentencePart.begin() + i + 1); 160 | sentencePart.erase(sentencePart.begin() + i + 1); //抹除后面两个单元 161 | partType.pop_back(); 162 | partType.push_back(CHAR_CONST); 163 | } 164 | else 165 | { 166 | return ERROR; 167 | } 168 | } 169 | else if (sentencePart[i] == "\"") 170 | partType.push_back(DOUBLE_QOUTE); 171 | else 172 | { //识别用户定义标识符 173 | for (k = 0; k < str.length(); k++) 174 | { 175 | if ((!isLetter)&& isNumber(str[k]) == 3) 176 | break; 177 | if (state == 1 && (isLetter || isNumber(str[k]) == 3)) 178 | state = 2; 179 | if (state == 1 && isNumber(str[k]) ==2) 180 | break; 181 | if (state == 2 && (isLetter|| isNumber(str[k]) == 2)) 182 | state = 2; 183 | } 184 | 185 | if (k == str.length()) 186 | { 187 | partType.push_back(SYNX); 188 | } 189 | //判断关键字,运算符 190 | else 191 | { 192 | partType.push_back(ERROR); 193 | } 194 | } 195 | 196 | } 197 | return 1; 198 | /* 如果产生词法错误则在此函数中报错 */ 199 | /* 东哥写的 */ 200 | } 201 | 202 | 203 | }; 204 | 205 | void Sentence:: showPartType() 206 | { 207 | for(int i = 0; i < partType.size(); i ++) 208 | { 209 | cout << partType.at(i) << " "; 210 | } 211 | } 212 | 213 | void Sentence:: partition() 214 | { 215 | int i = 0, j = 0;//2个指针 216 | while (i < thisLine.size()) 217 | { 218 | string s = ""; 219 | //处理空格 220 | 221 | while (thisLine[i] == ' ') 222 | { 223 | i++; 224 | j++; 225 | } 226 | //数字类型: 开头就是数字 科学记数法:a=12e-12 开头是- 前面没有 227 | if (isNumber(thisLine[j]) == 2 ) 228 | { 229 | //开头是数字 中间有 e-|e 数字 数字 小数点 e e- 230 | while (thisLine[j] != '\n'&& thisLine[j] != ' ' && ((isNumber(thisLine[j]) == 2) || thisLine[j] == '.' || (thisLine[j]=='e') || (thisLine[j]=='e'&&thisLine[j+1]=='-')))//之后是数字 或者小数点 231 | { 232 | //检测到e-就一起压入 233 | if(thisLine[j]=='e'&&thisLine[j+1]=='-') 234 | { s += thisLine[j++]; 235 | s += thisLine[j++];} 236 | else 237 | { 238 | s += thisLine[j++]; 239 | } 240 | } 241 | sentencePart.push_back(s); 242 | i = j; 243 | s = ""; 244 | } 245 | //变量 关键字 246 | else if (isLetter(thisLine[j])) 247 | { 248 | while (thisLine[j] != '\n'&&thisLine[j] != ' ' && isLetter(thisLine[j])) 249 | { 250 | s += thisLine[j++]; 251 | } 252 | sentencePart.push_back(s); 253 | i = j; 254 | s = ""; 255 | } 256 | 257 | // 算符 减号 括号 258 | else if (isLogic(thisLine[j]) == 2 || isLogic(thisLine[j]) == 1 || isLogic(thisLine[j]) == 0) 259 | { 260 | //减号 前面是数字 261 | if ( isLogic(thisLine[j]) == 1 && ( isNumber(thisLine[j-1])==2 ) ) 262 | { 263 | s = +thisLine[j++]; 264 | } 265 | //减号前面是算数符号 266 | else if( isLogic(thisLine[j]) == 1 && isLogic(thisLine[j-1]==2 )) 267 | { 268 | //处理负数 - [0-9] e- . e 269 | while (thisLine[j] != '\n'&& thisLine[j] != ' ' && ( isLogic(thisLine[j]) == 1 ||(isNumber(thisLine[j]) == 2) || thisLine[j] == '.' || (thisLine[j]=='e') || (thisLine[j]=='e'&&thisLine[j+1]=='-')))//之后是数字 或者小数点 270 | { 271 | //检测到e-就一起压入 272 | if(thisLine[j]=='e'&&thisLine[j+1]=='-') 273 | { s += thisLine[j++]; 274 | s += thisLine[j++];} 275 | else 276 | { 277 | s += thisLine[j++]; 278 | } 279 | } 280 | } 281 | //是括号 282 | else if (isLogic(thisLine[j]) == 0) 283 | { 284 | s = +thisLine[j++]; 285 | 286 | } 287 | 288 | //普通算符 289 | else { 290 | if (thisLine[j] != '\n' && thisLine[j] != ' ' && isLogic(thisLine[j]) == 2 && thisLine[j+1]!='=' && thisLine[j+1]!='|'&& thisLine[j+1]!='&' ) 291 | { 292 | s += thisLine[j++]; 293 | } 294 | else if (thisLine[j] != '\n' && thisLine[j] != ' ' && isLogic(thisLine[j]) == 2 && ( thisLine[j+1]=='=' || thisLine[j+1]=='&'|| thisLine[j+1]=='|') ) 295 | { 296 | s += thisLine[j++]; 297 | s += thisLine[j++]; 298 | } 299 | } 300 | 301 | sentencePart.push_back(s);//核心 302 | i = j; 303 | s = ""; 304 | } 305 | } 306 | } 307 | 308 | void Sentence:: showSentencePart() 309 | { 310 | for(int i = 0; i < sentencePart.size(); i++) 311 | { 312 | cout << sentencePart.at(i) << endl; 313 | } 314 | } 315 | 316 | 317 | 318 | void Sentence:: showThisLine() 319 | { 320 | cout << thisLine << endl; 321 | } 322 | 323 | 324 | void mergeString(vector* str1, vector* type, vector array) 325 | /* 将文本中所有行的词法单元和种类都合并到一起 */ 326 | { 327 | for(int i = 0; i < array.size(); i++) 328 | { 329 | //外层循环遍历所有的Sentence元素 330 | for(int j = 0; j < array.at(i).sentencePart.size(); j++) 331 | { 332 | //内层循环遍历一个Sentence元素中的所有成员 333 | (*str1).push_back(array.at(i).sentencePart.at(j)); 334 | (*type).push_back(array.at(i).partType.at(j)); 335 | } 336 | } 337 | } 338 | 339 | 340 | //判断是否是括号 341 | bool isBracket(char a) 342 | { 343 | string s = ""; 344 | s = +a; 345 | for (int i = 11; i<15; i++) 346 | { 347 | if (s.compare(prefix[i])) 348 | return(true); 349 | } 350 | return(false); 351 | } 352 | 353 | int isLogic(char a)// 0是(){} 1是- 2是算符 3不是算符 354 | { 355 | //属于标识符和逗号是false 356 | string s = ""; 357 | s = +a; 358 | if (s.compare(prefix[0]) == 0) return(1);//负号 359 | for (int i = 11; i<24; i++) 360 | { 361 | if (s.compare(prefix[i])==0) 362 | { 363 | return(2); 364 | } 365 | } 366 | for (int i = 1; i<11; i++)//正常算符 367 | { 368 | if (s.compare(prefix[i]) == 0) 369 | { 370 | return(2); 371 | } 372 | } 373 | 374 | for (int i = 11; i < 15; i++)//判断括号 375 | { 376 | if (s.compare(prefix[i]) == 0) 377 | return(0); 378 | } 379 | return(3);//不是算符 380 | } 381 | 382 | //判断开头是不是数字 -号返回1 其他返回2 不是返回三 383 | int isNumber(char a) 384 | { 385 | string s = ""; 386 | s = +a; 387 | if (s.compare(numberPrefix[0]) == 0)return(1); 388 | for (int i = 1; i<11; i++) 389 | { 390 | if (s.compare(numberPrefix[i]) == 0) 391 | { 392 | return(2); 393 | } 394 | } 395 | return(3); 396 | } 397 | 398 | //判断字母 下划线 399 | bool isLetter(char a) 400 | { 401 | if ((a >= 'a'&&a <= 'z') || (a >= 'A'&&a <= 'Z') || a == '_') 402 | return(true); 403 | else 404 | return(false); 405 | } 406 | //判断开头是数字 407 | int isPrefixNumber(char head) 408 | { 409 | if(head<='9'&&head>='0') 410 | return(1); 411 | else return(0); 412 | } -------------------------------------------------------------------------------- /grammar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "iostream" 2 | #include "string" 3 | using namespace std; 4 | 5 | #include "Sentence.h" 6 | #include "Defination.h" 7 | #include "LoadFile.h" 8 | 9 | int main() 10 | { 11 | string filename, fileContent; 12 | readFile(&filename, &fileContent);//读取文件 13 | vector originFile;//主Sentence数组 14 | partLine(&originFile, filename, fileContent);//对文本进行分行 15 | for(int i = 0; i < originFile.size(); i++) 16 | { 17 | originFile.at(i).partition(); 18 | originFile.at(i).anaPartFirstTime(); 19 | } 20 | 21 | for (int i = 0; i < originFile.size(); i++) 22 | { 23 | originFile.at(i).showSentencePart(); 24 | } 25 | 26 | 27 | system("pause"); 28 | return 0; 29 | } -------------------------------------------------------------------------------- /test.cpp: -------------------------------------------------------------------------------- 1 | 'a' 2 | char abc = 'f' 3 | 4 | float ba = (-a)*(12+c) 5 | 6 | float c = -12.34 7 | 8 | void main(argc, argv) 9 | 10 | if(a && b) 11 | if((a+b) || (a/b)) -------------------------------------------------------------------------------- /文法.md: -------------------------------------------------------------------------------- 1 | 大写的均为文法符号 小写字符均代表该文法的具体实例 2 | 3 | E 初始产生式 4 | DECLARE_F 函数声明产生式(declaraton of function) 5 | FUNCTION 函数定义加函数体表达式 6 | NULL 空产生式 7 | NUMBER 常数产生式 8 | NUMBER1 9 | NUMBER2 10 | VALUE 赋值产生式 11 | VALUE1 12 | ARITH 算数表达式产生式 13 | SYNX 变量名产生式 14 | LEFT 左括号 15 | RIGHT 右括号 16 | LEFT_BRACE左花括号 17 | RIGHT_BRACE右花括号 18 | USE_FUNCTION函数调用产生式 19 | DECLARE_V 变量定义表达式 20 | DECLARE_V1 21 | INNER_E 泛用表达式 22 | JUDGE 选择分支表达式 23 | JUDGE1 24 | LOGIC 逻辑表达式 25 | LOGIC1 26 | LOGIC2 27 | LOGIC3 28 | LOGIC4 29 | COMPARE 比较运算符 30 | WLOOP while循环表达式 31 | LINGER 逗号 32 | TYPE 指代各种变量类型 33 | RETURN return语句产生式 34 | EPSILON 空 35 | 36 | 37 | 38 | E -> DECLARE_F FUNCTION E | NULL | FUNCTION E 39 | 40 | void func(int a); 41 | int main() 42 | {...} 43 | void func(int a) 44 | {...} 45 | 46 | FUNCTION -> TYPE SYNX LEFT AILX3 AILX2 RIGHT LEFT_BRACE INNER_E RIGHT_BRACE 47 | int func(int a, int b){...} 48 | 49 | INNER_E -> VALUE INNER_E | DECLARE_V INNER_E | JUDGE INNER_E | WLOOP INNER_E | RETURN INNER_E | NULL | USE_FUNCTION INNER_E 50 | a = 2 ... | int a ... | if(...) ... | while(...){...} ... | return ... ... | func(...) ... 51 | 52 | 53 | 54 | 55 | NUMBER -> N{N}NUMBER1 | -N{N}NUMBER1 | (NUMBER) 56 | NUMBER1 -> .N{N} | *eNUMBER2 | EPSILON 57 | NUMBER2 -> N{N} | -N{N} 58 | 20.12 20*e12 123 -152.2 -78*e123 -78 78*e-12 | (-12) 59 | N->0|1|2|3|4|5|6|7|8|9 60 | 61 | 62 | 63 | 64 | ARITH-> T | A1 ADD_MINUS T 65 | T -> F | T MULT_DIV F 66 | F -> SYNX | NUMBER | USE_FUNCTION | LEFT A1 RIGHT 67 | 68 | VALUE -> SYNX EQUAL VALUE1 69 | VALUE1 -> ARITH | SYNX | NUMBER | USE_FUNCTION | CHAR_CONST 70 | a = a + b | a = b | a = 2 | a = valueOf(b) 71 | a = 'f' 72 | 73 | 74 | CHAR_CONST —> SINGLE_QOUTE SINGLE_SYB SINGLE_QOUTE 75 | 'f' 76 | 77 | 78 | SINGLE_SYB -> 0-9 | a-z | A-Z | _ | - | = | + | ; | : | | | " | ' | , | < | . | > | \ | ? | / | { | } | [ | ] | ` | ~ | 79 | -> ! | @ | # | $ | % | ^ | & | * | ( | ) 80 | 单个字符 用于初始化char类型的变量 81 | 82 | 83 | DECLARE_V -> TYPE DECLARE_V1 84 | DECLARE_V1 -> VALUE | SYNX AILX1 85 | int a = b | int a, b, c / int a 86 | 87 | AILX1 -> LINGER SYNX AILX1 | NULL 88 | , a, b 89 | 90 | AILX2 -> LINGER TYPE SYNX AILX2 | NULL 91 | , int a, float b 92 | 93 | AILX3 -> TYPE SYNX | NULL 94 | int a 95 | 96 | JUDGE -> IF LEFT LOGIC RIGHT LEFT_BRACE INNER_E RIGHT_BRACE JUDGE1 97 | JUDGE1 -> ELSE LEFT_BRACE INNER_E RIGHT_BRACE | EPSILON 98 | if(a == b) {...} 99 | if(a == b){...} else {...} 100 | 101 | LOGIC -> SYNX LOGIC1 | NUMBER LOGIC2 | NOT SYNX | LEFT LOGIC RIGHT COMPARE LEFT LOGIC RIGHT LOGIC 102 | 103 | LOGIC1 -> COMPARE LOGIC3 | EPSILON 104 | LOGIC2 -> COMPARE LOGIC4 | EPSILON 105 | LOGIC3 -> SYNX | NUMBER | ARITH 106 | LOGIC4 -> SYNX | NUMBER 107 | a < b | a == 2.3 | a == b * 1.2 | if(a) | if(1) | if(!a) | if(2 == a) | if(2 < 3) 108 | (a == b) && (b == c) 109 | 110 | COMPARE -> DOUBLE_EQU | LESS | MORE | LESS_EQU | MORE_EQU | AND | OR | NOT EUQAL 111 | == | < | > | <= | >= | && | || | != 112 | 113 | WLOOP -> WHILE LEFT LOGIC RIGHT LEFT_BRACE INNER_E RIGHT_BRACE 114 | while(logic){...} 115 | 116 | USE_FUNCTION -> SYNX LEFT SYNX AILX4 RIGHT 117 | func(a) | func(a,b,c) 118 | 119 | AILX4 -> LINGER SYNX | NULL 120 | ,a ,b 121 | 122 | RETURN -> return ARITH | return NUMBER | return SYNX | return USE_FUNCTION 123 | return a + b return 1 return a return func(a) 124 | 125 | --------------------------------------------------------------------------------