├── testSamples ├── test19.txt ├── test11.txt ├── test22.txt ├── test21.txt ├── test2.txt ├── test20.txt ├── test12.txt ├── test16.txt ├── test9.txt ├── test3.txt ├── test18.txt ├── test14.txt ├── test17.txt ├── test4.txt ├── test1.txt ├── test13.txt ├── test5.txt ├── test6.txt ├── test10.txt ├── test7.txt ├── test15.txt └── test8.txt ├── X0-Compiler ├── global.cpp ├── global.h ├── Interpret.cpp ├── lexAnaly │ ├── ReadSymbol.cpp │ ├── backup.cpp │ └── recover.cpp ├── x0-grammar │ ├── x0-grammar.pdf │ └── x0-grammar.ebnf ├── synAnaly │ ├── GenINTCode.cpp │ ├── ExpressionStat.cpp │ ├── CompoundStat.cpp │ ├── ReturnStat.cpp │ ├── BreakStat.cpp │ ├── type.cpp │ ├── WriteStat.cpp │ ├── term.cpp │ ├── ContinueStat.cpp │ ├── ValueExpr.cpp │ ├── EnterTable.cpp │ ├── AdditiveExpr.cpp │ ├── FunctionCall.cpp │ ├── ExitStat.cpp │ ├── SimpleValue.cpp │ ├── expression.cpp │ ├── FindPosition.cpp │ ├── IfStat.cpp │ ├── variable.cpp │ ├── ReadStat.cpp │ ├── WhileStat.cpp │ ├── StatementList.cpp │ ├── SimpleVariable.cpp │ ├── RepeatStat.cpp │ ├── DoWhileStat.cpp │ ├── factor.cpp │ ├── SwitchStat.cpp │ ├── VarDeclarationList.cpp │ ├── ConstDeclarationList.cpp │ ├── ForStat.cpp │ ├── FunctionList.cpp │ └── ErrorHandler.cpp ├── X0-Compiler.cpp ├── X0-Compiler.vcxproj.filters ├── stackobj.h └── X0-Compiler.vcxproj ├── .editorconfig ├── X0-Compiler.sln ├── .gitattributes ├── README.md └── .gitignore /testSamples/test19.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | char c; 4 | c = 97; 5 | write 1 + c; 6 | } 7 | -------------------------------------------------------------------------------- /testSamples/test11.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | const double a = 1.5; 4 | read a; 5 | write a; 6 | } -------------------------------------------------------------------------------- /X0-Compiler/global.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serend1p1ty/X0-Compiler/HEAD/X0-Compiler/global.cpp -------------------------------------------------------------------------------- /X0-Compiler/global.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serend1p1ty/X0-Compiler/HEAD/X0-Compiler/global.h -------------------------------------------------------------------------------- /testSamples/test22.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int a; 4 | int b; 5 | a = 1; 6 | b = !a; 7 | write b; 8 | } 9 | -------------------------------------------------------------------------------- /X0-Compiler/Interpret.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serend1p1ty/X0-Compiler/HEAD/X0-Compiler/Interpret.cpp -------------------------------------------------------------------------------- /testSamples/test21.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | double a[3]; 4 | a[0] = 3.3; 5 | a[1] = 2.2; 6 | write a[0] + a[1]; 7 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | # all files 5 | [*] 6 | indent_style = tab 7 | indent_size = 4 -------------------------------------------------------------------------------- /X0-Compiler/lexAnaly/ReadSymbol.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serend1p1ty/X0-Compiler/HEAD/X0-Compiler/lexAnaly/ReadSymbol.cpp -------------------------------------------------------------------------------- /X0-Compiler/x0-grammar/x0-grammar.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serend1p1ty/X0-Compiler/HEAD/X0-Compiler/x0-grammar/x0-grammar.pdf -------------------------------------------------------------------------------- /testSamples/test2.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int i; 4 | int sum; 5 | sum = 0; 6 | for (i = 1; i <= 10; i++) 7 | sum = sum + i; 8 | write sum; 9 | } -------------------------------------------------------------------------------- /testSamples/test20.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int x; 4 | int y; 5 | int m[3]; 6 | read x; 7 | read y; 8 | m[0] = y - x; 9 | write m[0]; 10 | } -------------------------------------------------------------------------------- /testSamples/test12.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int i; 4 | int ans; 5 | ans = 0; 6 | i = 1; 7 | do 8 | { 9 | ans = ans + i++; 10 | } while (i <= 10); 11 | write ans; 12 | } -------------------------------------------------------------------------------- /testSamples/test16.txt: -------------------------------------------------------------------------------- 1 | int add(int n) 2 | { 3 | if (n == 0) 4 | { 5 | return 0; 6 | } 7 | return n + add(n - 1); 8 | } 9 | 10 | main() 11 | { 12 | write add(10); 13 | } -------------------------------------------------------------------------------- /testSamples/test9.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | bool a; 4 | bool b; 5 | bool c; 6 | a = b = 1; 7 | c = 0; 8 | write a && b; 9 | write a && c; 10 | write a || c; 11 | write a xor c; 12 | } -------------------------------------------------------------------------------- /testSamples/test3.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | char c; 4 | int x; 5 | int y; 6 | int m; 7 | read x; 8 | read y; 9 | m = (x * x + y * y) / 2; 10 | c = 97; 11 | write m; 12 | write c; 13 | write (c + 1); 14 | } -------------------------------------------------------------------------------- /testSamples/test18.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int i; 4 | int ans; 5 | ans = 0; 6 | i = 1; 7 | repeat 8 | { 9 | ans = ans + ++i; 10 | if (i == 4) 11 | { 12 | break; 13 | } 14 | } until (i > 10); 15 | write ans; 16 | } -------------------------------------------------------------------------------- /testSamples/test14.txt: -------------------------------------------------------------------------------- 1 | double add(double a, double b, int c) 2 | { 3 | int i; 4 | double ret; 5 | ret = 0; 6 | for (i = 1; i <= c; i++) 7 | { 8 | ret = ret + a; 9 | a = a + b; 10 | } 11 | return ret; 12 | } 13 | 14 | main() 15 | { 16 | 17 | write add(1, 0.1, 3); 18 | } -------------------------------------------------------------------------------- /testSamples/test17.txt: -------------------------------------------------------------------------------- 1 | int GCD(int x, int y) 2 | { 3 | if (x % y == 0) 4 | { 5 | return y; 6 | } 7 | else 8 | { 9 | return GCD(y, x % y); 10 | } 11 | } 12 | 13 | main() 14 | { 15 | int a; 16 | int b; 17 | a = 12; 18 | b = 18; 19 | write GCD(a, b); 20 | } -------------------------------------------------------------------------------- /testSamples/test4.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int i; 4 | int p[20]; 5 | int now; 6 | i = 1; 7 | now = 1; 8 | p[0] = 1; 9 | while(i <= 10) 10 | { 11 | now = now * i; 12 | p[i] = now; 13 | i = i + 1; 14 | } 15 | while(i > 0) 16 | { 17 | i = i - 1; 18 | write p[i]; 19 | } 20 | } -------------------------------------------------------------------------------- /testSamples/test1.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int x; 4 | int y; 5 | int m[3]; 6 | read x; 7 | read y; 8 | if(x > y) 9 | { 10 | m[0] = x - y; 11 | } 12 | else 13 | { 14 | m[0] = y - x; 15 | } 16 | m[1] = x + y; 17 | m[2] = x * y; 18 | write m[0]; 19 | write m[1]; 20 | write m[2]; 21 | } -------------------------------------------------------------------------------- /testSamples/test13.txt: -------------------------------------------------------------------------------- 1 | int sub(int a, int b) 2 | { 3 | return a - b; 4 | } 5 | 6 | int add(int a, int b) 7 | { 8 | int c; 9 | int d; 10 | c = 3; 11 | d = 10; 12 | write sub(c * d, c - d); 13 | return a + b; 14 | } 15 | 16 | main() 17 | { 18 | int a; 19 | int b; 20 | a = 3; 21 | b = 2; 22 | write add(a * b, a + b); 23 | } -------------------------------------------------------------------------------- /testSamples/test5.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int i; 4 | int j; 5 | char c; 6 | c = 97; 7 | for(i = 0; i < 10; i++) 8 | { 9 | for(j = 0; j < 10;) 10 | { 11 | if(j>i) 12 | { 13 | write(10 * i + j); 14 | } 15 | else 16 | { 17 | write(j); 18 | } 19 | j++; 20 | } 21 | } 22 | write(c); 23 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/GenINTCode.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * function: generate an intermidiate code. 5 | */ 6 | void GenINTCode (FctCode fct, int opr1, double opr2) 7 | { 8 | if (codeNum >= MAX_NUM_CODE) /* the program is too long */ 9 | { 10 | ErrorHandler (26); 11 | } 12 | 13 | code[codeNum].fct = fct; 14 | code[codeNum].opr1 = opr1; 15 | code[codeNum++].opr2 = opr2; 16 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/ExpressionStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * ExpressionStat syntactical analyzer 5 | */ 6 | void ExpressionStat () 7 | { 8 | if (sym != semic) 9 | { 10 | expression (); 11 | if (sym == semic) 12 | { 13 | ReadSymbol (); 14 | } 15 | else /* the lack of ';' */ 16 | { 17 | ErrorHandler (10); 18 | } 19 | } 20 | else 21 | { 22 | ReadSymbol (); 23 | } 24 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/CompoundStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * CompoundStat syntactical analyzer 5 | */ 6 | void CompoundStat () 7 | { 8 | if (sym == lbrace) 9 | { 10 | ReadSymbol (); 11 | StatementList (); 12 | if (sym == rbrace) 13 | { 14 | ReadSymbol (); 15 | } 16 | else /* the lack of '}' */ 17 | { 18 | ErrorHandler (4); 19 | } 20 | } 21 | else /* the lack of '{' */ 22 | { 23 | ErrorHandler (5); 24 | } 25 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/ReturnStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * ReturnStat syntactical analyzer 5 | */ 6 | void ReturnStat () 7 | { 8 | if (sym == retsym) 9 | { 10 | ReadSymbol (); 11 | 12 | if (sym != semic) 13 | { 14 | ValueExpr (); 15 | } 16 | 17 | if (sym == semic) 18 | { 19 | ReadSymbol (); 20 | GenINTCode (opr, 0, fctNum - 1); 21 | } 22 | else /* the lack of ';' */ 23 | { 24 | ErrorHandler (10); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /testSamples/test6.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int a; 4 | int b; 5 | read a; 6 | if(a < 0) 7 | { 8 | b = 1; 9 | } 10 | else 11 | { 12 | if(a < 100) 13 | { 14 | b = a % 3; 15 | } 16 | else 17 | { 18 | b = a % 4; 19 | } 20 | } 21 | switch(b) 22 | { 23 | case 1: 24 | write 1; 25 | break; 26 | case 2: 27 | write 2; 28 | break; 29 | case 3: 30 | write 3; 31 | break; 32 | default: 33 | write 0; 34 | break; 35 | } 36 | } -------------------------------------------------------------------------------- /testSamples/test10.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int i; 4 | int ans; 5 | ans = 0; 6 | for (i = 1; i <= 6; i++) 7 | { 8 | if (i % 2) 9 | { 10 | continue; 11 | } 12 | ans = ans + i; 13 | } 14 | write ans; 15 | 16 | ans = 0; 17 | for (i = 1; i <= 10; i++) 18 | { 19 | if (i % 2) 20 | { 21 | break; 22 | } 23 | ans = ans + i; 24 | } 25 | write ans; 26 | 27 | for (i = 1; i <= 10; i++) 28 | { 29 | write i; 30 | if (i % 2) 31 | { 32 | exit(0); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/BreakStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * BreakStat syntactical analyzer 5 | */ 6 | void BreakStat () 7 | { 8 | if (sym == brksym) 9 | { 10 | ReadSymbol (); 11 | if (sym == semic) 12 | { 13 | ReadSymbol (); 14 | GenINTCode (jmp, 0, 0); 15 | breakList[brkNum++] = codeNum - 1; 16 | } 17 | else /* the lack of ';' */ 18 | { 19 | ErrorHandler (10); 20 | } 21 | } 22 | else /* the lack of 'break' */ 23 | { 24 | ErrorHandler (33); 25 | } 26 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/type.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * type syntactical analyzer 5 | */ 6 | DataType type () 7 | { 8 | switch (sym) 9 | { 10 | case intsym: 11 | ReadSymbol (); 12 | return Int; 13 | case dblsym: 14 | ReadSymbol (); 15 | return Double; 16 | case charsym: 17 | ReadSymbol (); 18 | return Char; 19 | case bolsym: 20 | ReadSymbol (); 21 | return Bool; 22 | default: /* illegal data type */ 23 | ErrorHandler (19); 24 | } 25 | return Int; 26 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/WriteStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * WriteStat syntactical analyzer 5 | */ 6 | void WriteStat () 7 | { 8 | if (sym == writesym) 9 | { 10 | ReadSymbol (); 11 | expression (); 12 | if (sym == semic) 13 | { 14 | ReadSymbol (); 15 | } 16 | else /* the lack of ';' */ 17 | { 18 | ErrorHandler (10); 19 | } 20 | GenINTCode (opr, 15, 0); /* output the top element */ 21 | } 22 | else /* the lack of 'write' */ 23 | { 24 | ErrorHandler (21); 25 | } 26 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/term.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * term syntactical analyzer 5 | */ 6 | void term () 7 | { 8 | factor (); 9 | while (sym == times || sym == slash || sym == modsym) 10 | { 11 | enum symbol tempSym = sym; /* save current value of sym */ 12 | ReadSymbol (); 13 | factor (); 14 | switch (tempSym) 15 | { 16 | case times: 17 | GenINTCode (opr, 4, 0); 18 | break; 19 | case slash: 20 | GenINTCode (opr, 5, 0); 21 | break; 22 | case modsym: 23 | GenINTCode (opr, 6, 0); 24 | break; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/ContinueStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * ContinueStat syntactical analyzer 5 | */ 6 | void ContinueStat () 7 | { 8 | if (sym == ctnsym) 9 | { 10 | ReadSymbol (); 11 | if (sym == semic) 12 | { 13 | ReadSymbol (); 14 | GenINTCode (jmp, 0, 0); 15 | 16 | /* save the position of 'continue' statement for backfilling later */ 17 | continueList[ctnNum++] = codeNum - 1; 18 | } 19 | else /* the lack of ';' */ 20 | { 21 | ErrorHandler (10); 22 | } 23 | } 24 | else /* the lack of 'continue' */ 25 | { 26 | ErrorHandler (35); 27 | } 28 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/ValueExpr.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * ValueExpr syntactical analyzer 5 | */ 6 | void ValueExpr () 7 | { 8 | SimpleValue (); 9 | while (sym == andsym || sym == orsym || sym == xorsym) 10 | { 11 | enum symbol tempSym = sym; /* save current value of sym */ 12 | ReadSymbol (); 13 | SimpleValue (); 14 | switch (tempSym) 15 | { 16 | case andsym: 17 | GenINTCode (opr, 16, 0); 18 | break; 19 | case orsym: 20 | GenINTCode (opr, 17, 0); 21 | break; 22 | case xorsym: 23 | GenINTCode (opr, 19, 0); 24 | break; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /testSamples/test7.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int i; 4 | int j; 5 | int k; 6 | int tmp; 7 | int a[3][4]; 8 | 9 | for (i = 0; i < 3; i++) 10 | { 11 | for (j = 0; j < 4; j++) 12 | { 13 | a[i][j] = 4 - j; 14 | } 15 | } 16 | 17 | for (k = 0; k < 3; k++) 18 | { 19 | for (i = 0; i < 4; i++) 20 | { 21 | for (j = i + 1; j < 4; j++) 22 | { 23 | if (a[k][i] > a[k][j]) 24 | { 25 | tmp = a[k][i]; 26 | a[k][i] = a[k][j]; 27 | a[k][j] = tmp; 28 | } 29 | } 30 | } 31 | } 32 | 33 | for (i = 0; i < 3; i++) 34 | { 35 | for (j = 0; j < 4; j++) 36 | { 37 | write a[i][j]; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/EnterTable.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * function: add a new entry to symbol table 5 | */ 6 | void EnterTable (ObjectKind k, int offset, int* size, int d, double value) 7 | { 8 | int& tableSize = fctInfo[fctNum - 1].tableSize; 9 | TableObject (&table)[MAX_SIZE_TABLE] = fctInfo[fctNum - 1].symTable; 10 | 11 | strcpy (table[tableSize].name, id); 12 | table[tableSize].kind = k; 13 | table[tableSize].offset = offset; 14 | for (int i = 0; i < d; i++) 15 | { 16 | table[tableSize].size[i] = size[i]; 17 | } 18 | table[tableSize].d = d; 19 | table[tableSize].value = value; 20 | 21 | tableSize++; 22 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/AdditiveExpr.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * AdditiveExpr syntactical analyzer 5 | */ 6 | void AdditiveExpr () 7 | { 8 | if (sym == minus) /* here see '-' as negtive sign */ 9 | { 10 | ReadSymbol (); 11 | term (); 12 | GenINTCode (opr, 1, 0); 13 | } 14 | else 15 | { 16 | term (); 17 | } 18 | 19 | while (sym == plus || sym == minus) 20 | { 21 | Symbol tempSym = sym; /* save current symbol */ 22 | ReadSymbol (); 23 | term (); 24 | 25 | switch (tempSym) 26 | { 27 | case plus: 28 | GenINTCode (opr, 2, 0); 29 | break; 30 | case minus: 31 | GenINTCode (opr, 3, 0); 32 | break; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /testSamples/test15.txt: -------------------------------------------------------------------------------- 1 | void FindPrime(int n) 2 | { 3 | int prime[100]; 4 | int check[100]; 5 | int i; 6 | int j; 7 | int tot; 8 | 9 | for (i = 0; i <= n; i++) 10 | { 11 | prime[i] = 0; 12 | check[i] = 0; 13 | } 14 | tot = 0; 15 | 16 | for (i = 2; i <= n; i++) 17 | { 18 | if (check[i] == 0) 19 | { 20 | prime[tot++] = i; 21 | write i; 22 | } 23 | for (j = 0; j < tot; ++j) 24 | { 25 | if (i * prime[j] > n) 26 | { 27 | break; 28 | } 29 | check[i*prime[j]] = 1; 30 | 31 | if (i % prime[j] == 0) 32 | { 33 | break; 34 | } 35 | } 36 | } 37 | } 38 | 39 | main() 40 | { 41 | int n; 42 | read n; 43 | FindPrime(n); 44 | } -------------------------------------------------------------------------------- /X0-Compiler/lexAnaly/backup.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * backup the status of lexical analysing 5 | */ 6 | void backup () 7 | { 8 | backups[backUpNum].backupFin = fin; 9 | backups[backUpNum].backupSym = sym; 10 | backups[backUpNum].backupCh = ch; 11 | backups[backUpNum].backupPosCh = posCh; 12 | backups[backUpNum].backupChNum = chNum; 13 | backups[backUpNum].backupDoubleNum = doubleNum; 14 | backups[backUpNum].backupIntNum = intNum; 15 | backups[backUpNum].backupIterCode = codeNum; 16 | strcpy (backups[backUpNum].backupId, id); 17 | 18 | for (int i = 0; i < MAX_NUM_LINE; i++) 19 | { 20 | backups[backUpNum].backupLineCache[i] = lineCache[i]; 21 | } 22 | 23 | backUpNum++; 24 | } -------------------------------------------------------------------------------- /X0-Compiler/lexAnaly/recover.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * recover the status of lexical analysing from backups 5 | */ 6 | void recover () 7 | { 8 | backUpNum--; 9 | fin = backups[backUpNum].backupFin; 10 | sym = backups[backUpNum].backupSym; 11 | ch = backups[backUpNum].backupCh; 12 | posCh = backups[backUpNum].backupPosCh; 13 | chNum = backups[backUpNum].backupChNum; 14 | doubleNum = backups[backUpNum].backupDoubleNum; 15 | intNum = backups[backUpNum].backupIntNum; 16 | codeNum = backups[backUpNum].backupIterCode; 17 | strcpy (id, backups[backUpNum].backupId); 18 | 19 | for (int i = 0; i < MAX_NUM_LINE; i++) 20 | { 21 | lineCache[i] = backups[backUpNum].backupLineCache[i]; 22 | } 23 | } -------------------------------------------------------------------------------- /testSamples/test8.txt: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | int a[2][3][4]; 4 | int i; 5 | int j; 6 | int k; 7 | int p; 8 | int tmp; 9 | 10 | for (p = 0; p < 2; p++) 11 | { 12 | for (i = 0; i < 3; i++) 13 | { 14 | for (j = 0; j < 4; j++) 15 | { 16 | a[p][i][j] = 4 - j; 17 | } 18 | } 19 | } 20 | 21 | for (p = 0; p < 2; p++) 22 | { 23 | for (k = 0; k < 3; k++) 24 | { 25 | for (i = 0; i < 4; i++) 26 | { 27 | for (j = i + 1; j < 4; j++) 28 | { 29 | if (a[p][k][i] > a[p][k][j]) 30 | { 31 | tmp = a[p][k][i]; 32 | a[p][k][i] = a[p][k][j]; 33 | a[p][k][j] = tmp; 34 | } 35 | } 36 | } 37 | } 38 | } 39 | 40 | for (p = 0; p < 2; p++) 41 | { 42 | for (i = 0; i < 3; i++) 43 | { 44 | for (j = 0; j < 4; j++) 45 | { 46 | write a[p][i][j]; 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/FunctionCall.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * FunctionCall syntactical analyzer 5 | */ 6 | void FunctionCall () 7 | { 8 | if (sym == ident) 9 | { 10 | int pos = FindPosition (id); 11 | 12 | if (pos == -1) /* the function hasn't been declared */ 13 | { 14 | ErrorHandler (55); 15 | } 16 | 17 | ReadSymbol (); 18 | if (sym == lparen) 19 | { 20 | ReadSymbol (); 21 | 22 | /* the function has a parameter at least if sym != rparen */ 23 | if (sym != rparen) 24 | { 25 | expression (); 26 | while (sym == comma) 27 | { 28 | ReadSymbol (); 29 | expression (); 30 | } 31 | } 32 | 33 | if (sym == rparen) 34 | { 35 | ReadSymbol (); 36 | 37 | /* function call */ 38 | GenINTCode (cal, fctInfo[pos].startINTCode, 0); 39 | } 40 | else /* the lack of ')' */ 41 | { 42 | ErrorHandler (14); 43 | } 44 | } 45 | else /* the lack of '(' */ 46 | { 47 | ErrorHandler (16); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/ExitStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * ExitStat syntactical analyzer 5 | */ 6 | void ExitStat () 7 | { 8 | if (sym == exitsym) 9 | { 10 | ReadSymbol (); 11 | if (sym == lparen) 12 | { 13 | ReadSymbol (); 14 | if (sym == intnum) 15 | { 16 | ReadSymbol (); 17 | GenINTCode (lit, intNum, 0); 18 | if (sym == rparen) 19 | { 20 | ReadSymbol (); 21 | if (sym == semic) 22 | { 23 | ReadSymbol (); 24 | GenINTCode (opr, 7, 0); /* execute 'exit' function */ 25 | } 26 | else /* the lack of ';' */ 27 | { 28 | ErrorHandler (10); 29 | } 30 | } 31 | else /* the lack of ')' */ 32 | { 33 | ErrorHandler (14); 34 | } 35 | } 36 | else /* the lack of integer */ 37 | { 38 | ErrorHandler (8); 39 | } 40 | } 41 | else /* the lack of '(' */ 42 | { 43 | ErrorHandler (16); 44 | } 45 | } 46 | else /* the lack of 'exit' */ 47 | { 48 | ErrorHandler (34); 49 | } 50 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/SimpleValue.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * SimpleValue syntactical analyzer 5 | */ 6 | void SimpleValue () 7 | { 8 | if (sym == oddsym) 9 | { 10 | ReadSymbol (); 11 | AdditiveExpr (); 12 | GenINTCode (opr, 20, 0); /* ODD operation */ 13 | } 14 | else 15 | { 16 | AdditiveExpr (); 17 | 18 | if (sym == great || sym == less || sym == greateql 19 | || sym == lesseql || sym == eqleql || sym == neql) 20 | { 21 | enum symbol tempSym = sym; /* save current value of sym */ 22 | ReadSymbol (); 23 | AdditiveExpr (); 24 | 25 | /* >, <, >=, <=, ==, != */ 26 | switch (tempSym) 27 | { 28 | case great: 29 | GenINTCode (opr, 12, 0); 30 | break; 31 | case less: 32 | GenINTCode (opr, 10, 0); 33 | break; 34 | case greateql: 35 | GenINTCode (opr, 11, 0); 36 | break; 37 | case lesseql: 38 | GenINTCode (opr, 13, 0); 39 | break; 40 | case eqleql: 41 | GenINTCode (opr, 8, 0); 42 | break; 43 | case neql: 44 | GenINTCode (opr, 9, 0); 45 | break; 46 | default: /* illegal operator */ 47 | ErrorHandler (30); 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/expression.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * expression syntactical analyzer 5 | */ 6 | void expression () 7 | { 8 | if (sym == ident) /* need to read more symbols to determine whether current statement is assignment statement */ 9 | { 10 | if (FindPosition (id, fctNum - 1) != -1) 11 | { 12 | backup (); /* backup the status of lexical analysis */ 13 | int offset; 14 | ObjectKind kind; 15 | SimpleVariable (&kind, &offset); 16 | if (sym == eql) /* current statement is assignment statement */ 17 | { 18 | /* constant can't be modified */ 19 | if (kind == constIntVar || kind == constCharVar 20 | || kind == constBoolVar || kind == constDoubleVar) 21 | { 22 | ErrorHandler (31); 23 | } 24 | 25 | ReadSymbol (); 26 | expression (); 27 | GenINTCode (sto, offset, fctNum - 1); /* store the top element in the specfic variable */ 28 | } 29 | else /* current statement is ValueExpr */ 30 | { 31 | recover (); /* recover the status of lexical analysis from backups */ 32 | ValueExpr (); 33 | } 34 | } 35 | else /* we are sure current statement is ValueExpr if the identifier a function */ 36 | { 37 | ValueExpr (); 38 | } 39 | } 40 | else 41 | { 42 | ValueExpr (); 43 | } 44 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/FindPosition.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * input: 5 | * identName: the name of identifier which we want to search 6 | * pos: index of the function in fctInfo 7 | * output: 8 | * the position of this identifier in the symbol table of the function 9 | */ 10 | int FindPosition (char* identName, int pos) 11 | { 12 | for (int i = 0; i < fctInfo[pos].tableSize; i++) 13 | { 14 | if (strcmp (fctInfo[pos].symTable[i].name, identName) == 0) 15 | { 16 | return i; 17 | } 18 | } 19 | return -1; 20 | } 21 | 22 | /* 23 | * input: 24 | * offset: the offset of this identifier which we want to search 25 | * pos: index of the function in fctInfo 26 | * output: 27 | * the position of this identifier in the symbol table of the function 28 | */ 29 | int FindPosition (int offset, int pos) 30 | { 31 | for (int i = 0; i < fctInfo[pos].tableSize; i++) 32 | { 33 | if (fctInfo[pos].symTable[i].offset == offset) 34 | { 35 | return i; 36 | } 37 | } 38 | return -1; 39 | } 40 | 41 | /* 42 | * input: function name 43 | * output: position of the function in fctInfo 44 | */ 45 | int FindPosition (char* fctName) 46 | { 47 | for (int i = 0; i < fctNum; i++) 48 | { 49 | if (strcmp (fctInfo[i].name, fctName) == 0) 50 | { 51 | return i; 52 | } 53 | } 54 | return -1; 55 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/IfStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * IfStat syntactical analyzer 5 | */ 6 | void IfStat () 7 | { 8 | if (sym == ifsym) 9 | { 10 | ReadSymbol (); 11 | if (sym == lparen) 12 | { 13 | ReadSymbol (); 14 | expression (); 15 | int pos1 = codeNum; /* save current value of codeNum for backfilling */ 16 | 17 | /* the position where program jump to hasn't been determined. we'll backfill it later. */ 18 | GenINTCode (jpc, 0, 0); 19 | 20 | if (sym == rparen) 21 | { 22 | ReadSymbol (); 23 | statement (); 24 | 25 | if (sym == elsesym) 26 | { 27 | int pos2 = codeNum; /* save current value of codeNum for backfilling */ 28 | 29 | /* the position where program jump to hasn't been determined. we'll backfill it later. */ 30 | GenINTCode (jmp, 0, 0); 31 | 32 | code[pos1].opr1 = codeNum; /* backfill */ 33 | ReadSymbol (); 34 | statement (); 35 | code[pos2].opr1 = codeNum; /* backfill */ 36 | } 37 | else 38 | { 39 | code[pos1].opr1 = codeNum; /* backfill */ 40 | } 41 | } 42 | else /* the lack of ')' */ 43 | { 44 | ErrorHandler (14); 45 | } 46 | } 47 | else /* the lack of '(' */ 48 | { 49 | ErrorHandler (16); 50 | } 51 | } 52 | else /* the lack of 'if' */ 53 | { 54 | ErrorHandler (17); 55 | } 56 | } -------------------------------------------------------------------------------- /X0-Compiler.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27428.2027 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "X0-Compiler", "X0-Compiler\X0-Compiler.vcxproj", "{2A4EE78C-7A45-4553-A296-78D8FE45A070}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {2A4EE78C-7A45-4553-A296-78D8FE45A070}.Debug|x64.ActiveCfg = Debug|x64 17 | {2A4EE78C-7A45-4553-A296-78D8FE45A070}.Debug|x64.Build.0 = Debug|x64 18 | {2A4EE78C-7A45-4553-A296-78D8FE45A070}.Debug|x86.ActiveCfg = Debug|Win32 19 | {2A4EE78C-7A45-4553-A296-78D8FE45A070}.Debug|x86.Build.0 = Debug|Win32 20 | {2A4EE78C-7A45-4553-A296-78D8FE45A070}.Release|x64.ActiveCfg = Release|x64 21 | {2A4EE78C-7A45-4553-A296-78D8FE45A070}.Release|x64.Build.0 = Release|x64 22 | {2A4EE78C-7A45-4553-A296-78D8FE45A070}.Release|x86.ActiveCfg = Release|Win32 23 | {2A4EE78C-7A45-4553-A296-78D8FE45A070}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {807A48C7-E1EE-4DE3-A855-E38BD5C5D61A} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/variable.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * variable syntactical analyzer 5 | */ 6 | void variable (ObjectKind* ptr_kind, int* ptr_offset, int* ptr_IncOrDec) 7 | { 8 | if (sym == ident) 9 | { 10 | SimpleVariable (ptr_kind, ptr_offset); 11 | if (sym == incsym) 12 | { 13 | /* Increasing or decreasing variable must be int or char */ 14 | if (*ptr_kind != intVar && *ptr_kind != intArray 15 | && *ptr_kind != charVar && *ptr_kind != charArray) 16 | { 17 | ErrorHandler (49); 18 | } 19 | 20 | *ptr_IncOrDec = 1; 21 | ReadSymbol (); 22 | } 23 | else if (sym == decsym) 24 | { 25 | /* Increasing or decreasing variable must be int or char */ 26 | if (*ptr_kind != intVar && *ptr_kind != intArray 27 | && *ptr_kind != charVar && *ptr_kind != charArray) 28 | { 29 | ErrorHandler (49); 30 | } 31 | 32 | *ptr_IncOrDec = 2; 33 | ReadSymbol (); 34 | } 35 | else 36 | { 37 | *ptr_IncOrDec = 5; 38 | } 39 | } 40 | else if (sym == incsym || sym == decsym) 41 | { 42 | if (sym == incsym) 43 | { 44 | *ptr_IncOrDec = 3; 45 | } 46 | else 47 | { 48 | *ptr_IncOrDec = 4; 49 | } 50 | ReadSymbol (); 51 | SimpleVariable (ptr_kind, ptr_offset); 52 | 53 | /* Increasing or decreasing variable must be int or char */ 54 | if (*ptr_kind != intVar && *ptr_kind != intArray 55 | && *ptr_kind != charVar && *ptr_kind != charArray) 56 | { 57 | ErrorHandler (49); 58 | } 59 | } 60 | else /* the lack of identifier */ 61 | { 62 | ErrorHandler (6); 63 | } 64 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/ReadStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * ReadStat syntactical analyzer 5 | */ 6 | void ReadStat () 7 | { 8 | if (sym == readsym) 9 | { 10 | ReadSymbol (); 11 | 12 | ObjectKind kind; 13 | int offset; 14 | int IncOrDec; /* 1: Increase after variable 2: decrease after variable 15 | * 3: Increase before variable 4: decrease before variable 16 | * 5: without Increase or decrease */ 17 | variable (&kind, &offset, &IncOrDec); 18 | 19 | /* 'read' function can't read Increasing or decreasing variable */ 20 | if (IncOrDec != 5) 21 | { 22 | ErrorHandler (32); 23 | } 24 | 25 | /* constant can't be read */ 26 | if (kind == constIntVar || kind == constCharVar 27 | || kind == constBoolVar || kind == constDoubleVar) 28 | { 29 | ErrorHandler (52); 30 | } 31 | 32 | /* read a variable using scanf function */ 33 | switch (kind) 34 | { 35 | case intVar: 36 | case intArray: 37 | GenINTCode (opr, 14, Int); 38 | break; 39 | case doubleVar: 40 | case doubleArray: 41 | GenINTCode (opr, 14, Double); 42 | break; 43 | case charVar: 44 | case charArray: 45 | GenINTCode (opr, 14, Char); 46 | break; 47 | case boolVar: 48 | case boolArray: 49 | GenINTCode (opr, 14, Bool); 50 | break; 51 | } 52 | 53 | GenINTCode (sto, offset, fctNum - 1); /* store the value of top element in the specific variable */ 54 | 55 | if (sym == semic) 56 | { 57 | ReadSymbol (); 58 | } 59 | else /* the lack of ';' */ 60 | { 61 | ErrorHandler (10); 62 | } 63 | } 64 | else /* the lack of 'read' */ 65 | { 66 | ErrorHandler (18); 67 | } 68 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/WhileStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * WhileStat syntactical analyzer 5 | */ 6 | void WhileStat () 7 | { 8 | int startBreakNum = brkNum; /* save the number of 'break' statement to be backfilled before analyzing WhileStat */ 9 | int startContinueNum = ctnNum; /* save the number of 'continue' statement to be backfilled before analyzing WhileStat */ 10 | 11 | if (sym == whilesym) 12 | { 13 | ReadSymbol (); 14 | if (sym == lparen) 15 | { 16 | int pos1 = codeNum; /* save current value of codeNum */ 17 | ReadSymbol (); 18 | expression (); 19 | if (sym == rparen) 20 | { 21 | int pos2 = codeNum; /* save current value of codeNum for backfilling */ 22 | 23 | /* the position where program jump to hasn't been determined. we'll backfill it later. */ 24 | GenINTCode (jpc, 0, 0); 25 | 26 | ReadSymbol (); 27 | statement (); 28 | 29 | /* backfill 'continue' statement */ 30 | for (int i = startContinueNum; i < ctnNum; i++) 31 | { 32 | int pos = continueList[i]; 33 | code[pos].opr1 = codeNum; 34 | } 35 | ctnNum = startContinueNum; /* set the value of ctnNum to the value 36 | * that is before analyzing WhileStat */ 37 | 38 | GenINTCode (jmp, pos1, 0); 39 | code[pos2].opr1 = codeNum; /* backfill */ 40 | } 41 | else /* the lack of ')' */ 42 | { 43 | ErrorHandler (14); 44 | } 45 | } 46 | else /* the lack of '(' */ 47 | { 48 | ErrorHandler (16); 49 | } 50 | } 51 | else /* the lack of 'while' */ 52 | { 53 | ErrorHandler (20); 54 | } 55 | 56 | /* backfill 'break' statement */ 57 | for (int i = startBreakNum; i < brkNum; i++) 58 | { 59 | int pos = breakList[i]; 60 | code[pos].opr1 = codeNum; 61 | } 62 | brkNum = startBreakNum; /* set the value of brkNum to the value 63 | * that is before analyzing WhileStat */ 64 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/StatementList.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * statement syntactical analyzer 5 | */ 6 | void statement () 7 | { 8 | if (sym == ifsym) /* 'if' statement */ 9 | { 10 | IfStat (); 11 | } 12 | else if (sym == whilesym) /* 'while' statement */ 13 | { 14 | WhileStat (); 15 | } 16 | else if (sym == readsym) /* 'read' statement */ 17 | { 18 | ReadStat (); 19 | } 20 | else if (sym == writesym) /* 'write' statement */ 21 | { 22 | WriteStat (); 23 | } 24 | else if (sym == lbrace) /* 'compound' statement */ 25 | { 26 | CompoundStat (); 27 | } 28 | else if (sym == forsym) /* 'for' statement */ 29 | { 30 | ForStat (); 31 | } 32 | else if (sym == brksym) /* 'break' statement */ 33 | { 34 | BreakStat (); 35 | } 36 | else if (sym == exitsym) /* 'exit' statement */ 37 | { 38 | ExitStat (); 39 | } 40 | else if (sym == ctnsym) /* 'continue' statement */ 41 | { 42 | ContinueStat (); 43 | } 44 | else if (sym == swtcsym) /* 'switch' statement */ 45 | { 46 | SwitchStat (); 47 | } 48 | else if (sym == dosym) /* do-while statement */ 49 | { 50 | DoWhileStat (); 51 | } 52 | else if (sym == retsym) /* 'return' statement */ 53 | { 54 | ReturnStat (); 55 | } 56 | else if (sym == reptsym) /* repeat-until statement */ 57 | { 58 | RepeatStat (); 59 | } 60 | else /* 'expression' statement */ 61 | { 62 | ExpressionStat (); 63 | } 64 | } 65 | 66 | /* 67 | * StatementList syntactical analyzer 68 | */ 69 | void StatementList () 70 | { 71 | /* execute 'statement' syntactical analyzer if sym belong to first('statement') */ 72 | while (sym == ifsym || sym == whilesym || sym == readsym 73 | || sym == writesym || sym == lbrace || sym == semic 74 | || sym == ident || sym == lparen || sym == intnum 75 | || sym == doublenum || sym == minus || sym == forsym 76 | || sym == incsym || sym == decsym || sym == oddsym 77 | || sym == notsym || sym == brksym || sym == exitsym 78 | || sym == ctnsym || sym == swtcsym || sym == dosym 79 | || sym == reptsym || sym == truesym || sym == falsesym || sym == retsym) 80 | { 81 | statement (); 82 | } 83 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/SimpleVariable.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * SimpleVariable syntactical analyzer 5 | * store information of SimpleVariable in ptr_kind, ptr_offset 6 | */ 7 | void SimpleVariable (ObjectKind* ptr_kind, int* ptr_offset) 8 | { 9 | if (sym == ident) 10 | { 11 | int pos = FindPosition (id, fctNum - 1); 12 | 13 | if (pos == -1) /* the identifier hasn't been declared */ 14 | { 15 | ErrorHandler (23); 16 | } 17 | 18 | *ptr_kind = fctInfo[fctNum - 1].symTable[pos].kind; 19 | *ptr_offset = fctInfo[fctNum - 1].symTable[pos].offset; 20 | ReadSymbol (); 21 | if (sym == lbracket) 22 | { 23 | /* identifier isn't array */ 24 | if (*ptr_kind != intArray && *ptr_kind != charArray 25 | && *ptr_kind != boolArray && *ptr_kind != doubleArray) 26 | { 27 | ErrorHandler (25); 28 | } 29 | 30 | /* check whether array subscript is out of bound if subscript is a number */ 31 | backup (); 32 | int currentDimension = 0; 33 | while (sym == lbracket) 34 | { 35 | ReadSymbol (); 36 | if (sym == intnum) 37 | { 38 | int tempNum = intNum; 39 | ReadSymbol (); 40 | if (sym == rbracket) 41 | { 42 | /* array subscript is out of bound */ 43 | if (tempNum >= fctInfo[fctNum - 1].symTable[pos].size[currentDimension++]) 44 | { 45 | ErrorHandler (50); 46 | } 47 | ReadSymbol (); 48 | } 49 | else 50 | { 51 | break; 52 | } 53 | } 54 | else 55 | { 56 | break; 57 | } 58 | } 59 | recover (); 60 | 61 | while (sym == lbracket) 62 | { 63 | ReadSymbol (); 64 | expression (); 65 | if (sym == rbracket) 66 | { 67 | ReadSymbol (); 68 | } 69 | else /* the lack of ']' */ 70 | { 71 | ErrorHandler (9); 72 | } 73 | } 74 | } 75 | else 76 | { 77 | /* identifier isn't {const} variable */ 78 | if (*ptr_kind != intVar && *ptr_kind != charVar 79 | && *ptr_kind != boolVar && *ptr_kind != doubleVar 80 | && *ptr_kind != constIntVar && *ptr_kind != constCharVar 81 | && *ptr_kind != constBoolVar && *ptr_kind != constDoubleVar) 82 | { 83 | ErrorHandler (24); 84 | } 85 | } 86 | } 87 | else /* the lack of identifier */ 88 | { 89 | ErrorHandler (6); 90 | } 91 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/RepeatStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * RepeatStat syntactical analyzer 5 | */ 6 | void RepeatStat () 7 | { 8 | int startBreakNum = brkNum; /* save the number of 'break' statement to be backfilled before analyzing RepeatStat */ 9 | int startContinueNum = ctnNum; /* save the number of 'continue' statement to be backfilled before analyzing RepeatStat */ 10 | 11 | if (sym == reptsym) 12 | { 13 | ReadSymbol (); 14 | if (sym == lbrace) 15 | { 16 | ReadSymbol (); 17 | int pos = codeNum; /* save the position of StatementList's first code */ 18 | StatementList (); 19 | 20 | /* backfill 'continue' statement */ 21 | for (int i = startContinueNum; i < ctnNum; i++) 22 | { 23 | int pos = continueList[i]; 24 | code[pos].opr1 = codeNum; 25 | } 26 | ctnNum = startContinueNum; /* set the value of ctnNum to the value 27 | * that is before analyzing RepeatStat */ 28 | 29 | if (sym == rbrace) 30 | { 31 | ReadSymbol (); 32 | if (sym == untlsym) 33 | { 34 | ReadSymbol (); 35 | if (sym == lparen) 36 | { 37 | ReadSymbol (); 38 | expression (); 39 | GenINTCode (jpc, pos, 0); 40 | if (sym == rparen) 41 | { 42 | ReadSymbol (); 43 | if (sym == semic) 44 | { 45 | ReadSymbol (); 46 | } 47 | else /* the lack of ';' */ 48 | { 49 | ErrorHandler (10); 50 | } 51 | } 52 | else /* the lack of ')' */ 53 | { 54 | ErrorHandler (14); 55 | } 56 | } 57 | else /* the lack of '(' */ 58 | { 59 | ErrorHandler (16); 60 | } 61 | } 62 | else /* the lack of 'while' */ 63 | { 64 | ErrorHandler (20); 65 | } 66 | } 67 | else /* the lack of '}' */ 68 | { 69 | ErrorHandler (4); 70 | } 71 | } 72 | else /* the lack of '{' */ 73 | { 74 | ErrorHandler (5); 75 | } 76 | } 77 | else /* the lack of 'do' */ 78 | { 79 | ErrorHandler (38); 80 | } 81 | 82 | /* backfill 'break' statement */ 83 | for (int i = startBreakNum; i < brkNum; i++) 84 | { 85 | int pos = breakList[i]; 86 | code[pos].opr1 = codeNum; 87 | } 88 | brkNum = startBreakNum; /* set the value of brkNum to the value 89 | * that is before analyzing RepeatStat */ 90 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/DoWhileStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * DoWhileStat syntactical analyzer 5 | */ 6 | void DoWhileStat () 7 | { 8 | int startBreakNum = brkNum; /* save the number of 'break' statement to be backfilled before analyzing DoWhileStat */ 9 | int startContinueNum = ctnNum; /* save the number of 'continue' statement to be backfilled before analyzing DoWhileStat */ 10 | 11 | if (sym == dosym) 12 | { 13 | ReadSymbol (); 14 | if (sym == lbrace) 15 | { 16 | ReadSymbol (); 17 | int pos = codeNum; /* save the position of fist code of StatementList */ 18 | StatementList (); 19 | 20 | /* backfill 'continue' statement */ 21 | for (int i = startContinueNum; i < ctnNum; i++) 22 | { 23 | int pos = continueList[i]; 24 | code[pos].opr1 = codeNum; 25 | } 26 | ctnNum = startContinueNum; /* set the value of ctnNum to the value 27 | * that is before analyzing DoWhileStat */ 28 | 29 | if (sym == rbrace) 30 | { 31 | ReadSymbol (); 32 | if (sym == whilesym) 33 | { 34 | ReadSymbol (); 35 | if (sym == lparen) 36 | { 37 | ReadSymbol (); 38 | expression (); 39 | GenINTCode (jpc, codeNum + 2, 0); 40 | GenINTCode (jmp, pos, 0); 41 | if (sym == rparen) 42 | { 43 | ReadSymbol (); 44 | if (sym == semic) 45 | { 46 | ReadSymbol (); 47 | } 48 | else /* the lack of ';' */ 49 | { 50 | ErrorHandler (10); 51 | } 52 | } 53 | else /* the lack of '}' */ 54 | { 55 | ErrorHandler (14); 56 | } 57 | } 58 | else /* the lack of '(' */ 59 | { 60 | ErrorHandler (16); 61 | } 62 | } 63 | else /* the lack of 'while' */ 64 | { 65 | ErrorHandler (20); 66 | } 67 | } 68 | else /* the lack of '}' */ 69 | { 70 | ErrorHandler (4); 71 | } 72 | } 73 | else /* the lack of '{' */ 74 | { 75 | ErrorHandler (5); 76 | } 77 | } 78 | else /* the lack of 'do' */ 79 | { 80 | ErrorHandler (38); 81 | } 82 | 83 | /* backfill 'break' statement */ 84 | for (int i = startBreakNum; i < brkNum; i++) 85 | { 86 | int pos = breakList[i]; 87 | code[pos].opr1 = codeNum; 88 | } 89 | brkNum = startBreakNum; /* set the value of brkNum to the value 90 | * that is before analyzing DoWhileStat */ 91 | } -------------------------------------------------------------------------------- /X0-Compiler/x0-grammar/x0-grammar.ebnf: -------------------------------------------------------------------------------- 1 | program = FunctionList "main" "(" ")" "{" ConstDeclarationList VarDeclarationList StatementList "}". 2 | FunctionList = [function FunctionList]. 3 | function = (type | "void") ID "(" ParameterList ")" "{" ConstDeclarationList VarDeclarationList StatementList "}". 4 | ParameterList = [parameter {"," parameter}]. 5 | parameter = type ID. 6 | ConstDeclarationList = [ConstDeclarationStat ConstDeclarationList]. 7 | ConstDeclarationStat = "const" type ID "=" ("intNumber" | "doubleNumber" | "true" | "false") ";". 8 | VarDeclarationList = [VarDeclarationStat VarDeclarationList]. 9 | VarDeclarationStat = type ID {["[" intNumber "]"} ";". 10 | type = "int" | "char" | "bool" | "double". 11 | StatementList = [statement StatementList]. 12 | statement = IfStat | WhileStat | ReadStat | WriteStat | CompoundStat | ExpressionStat | ForStat | SwitchStat | BreakStat | ExitStat | ContinueStat | DoWhileStat | RepeatStat | ReturnStat. 13 | ReturnStat = "return" [ValueExpr] ";". 14 | IfStat = "if" "(" expression ")" statement [ "else" statement]. 15 | WhileStat = "while" "(" expression ")" statement. 16 | ReadStat = "read" variable ";". 17 | WriteStat = "write" expression ";" . 18 | CompoundStat = "{" StatementList "}". 19 | ExpressionStat = expression ";" | ";". 20 | ForStat = "for" "(" expression ";" expression ";" expression ")" statement. 21 | SwitchStat = "switch" "(" expression ")" "{" {"case" intNumber ":" StatementList} ["default" ":" StatementList] "}". 22 | BreakStat = "break" ";". 23 | ExitStat = "exit" "(" intNumber ")" ";". 24 | ContinueStat = "continue" ";". 25 | DoWhileStat = "do" "{" StatementList "}" "while" "(" expression ")" ";". 26 | RepeatStat = "repeat" "{" StatementList "}" "until" "(" expression ")" ";". 27 | expression = SimpleVariable "=" expression | ValueExpr. 28 | variable = SimpleVariable ["++" | "--"] | ("++" | "--") SimpleVariable. 29 | SimpleVariable = ID {"[" expression "]"}. 30 | ValueExpr = SimpleValue {("&&" | "||" | "XOR") SimpleValue}. 31 | SimpleValue = odd AdditiveExpr | AdditiveExpr [(">" | "<" | ">=" | "<=" | "==" | "!=") AdditiveExpr]. 32 | AdditiveExpr = ["-"] term {("+"|"-") term}. 33 | term = factor {("*"|"/"|"%") factor}. 34 | factor = ["!"] ("(" expression ")"| variable | intNumber | doubleNumber | "true" | "false" | FunctionCall). 35 | FunctionCall = ID "(" [expression {"," expression}] ")". 36 | -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/factor.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * factor syntactical analyzer 5 | */ 6 | void factor () 7 | { 8 | int flag = 0; /* flag = 1 means logical inversion operator has appeared */ 9 | 10 | if (sym == notsym) 11 | { 12 | flag = 1; 13 | ReadSymbol (); 14 | } 15 | 16 | if (sym == lparen) 17 | { 18 | ReadSymbol (); 19 | expression (); 20 | if (sym == rparen) 21 | { 22 | ReadSymbol (); 23 | } 24 | else /* the lack of ')' */ 25 | { 26 | ErrorHandler (14); 27 | } 28 | } 29 | /* current statement is FunctionCall if the identifier has been declared in symbol table */ 30 | else if (sym == ident && FindPosition (id, fctNum - 1) == -1) 31 | { 32 | FunctionCall (); 33 | } 34 | else if ((sym == ident && FindPosition (id, fctNum - 1) != -1) 35 | || sym == incsym || sym == decsym) 36 | { 37 | ObjectKind kind; 38 | int offset; 39 | int IncOrDec; /* 1: Increase after variable 2: decrease after variable 40 | * 3: Increase before variable 4: decrease before variable 41 | * 5: without Increase or decrease */ 42 | variable (&kind, &offset, &IncOrDec); 43 | 44 | switch (IncOrDec) 45 | { 46 | case 1: 47 | GenINTCode (add, offset, fctNum - 1); 48 | GenINTCode (lod, offset, fctNum - 1); 49 | GenINTCode (tad, -1, 0); 50 | break; 51 | case 2: 52 | GenINTCode (sub, offset, fctNum - 1); 53 | GenINTCode (lod, offset, fctNum - 1); 54 | GenINTCode (tad, 1, 0); 55 | break; 56 | case 3: 57 | GenINTCode (add, offset, fctNum - 1); 58 | GenINTCode (lod, offset, fctNum - 1); 59 | break; 60 | case 4: 61 | GenINTCode (sub, offset, fctNum - 1); 62 | GenINTCode (lod, offset, fctNum - 1); 63 | break; 64 | case 5: 65 | GenINTCode (lod, offset, fctNum - 1); 66 | break; 67 | } 68 | } 69 | else if (sym == intnum) 70 | { 71 | GenINTCode (lit, intNum, 0); 72 | ReadSymbol (); 73 | } 74 | else if (sym == doublenum) 75 | { 76 | GenINTCode (lit, 0, doubleNum); 77 | ReadSymbol (); 78 | } 79 | else if (sym == truesym || sym == falsesym) 80 | { 81 | GenINTCode (lit, sym == truesym, 0); /* the value of 'true' is 1, value of 'false' is 0 */ 82 | ReadSymbol (); 83 | } 84 | else /* syntax error of 'factor' */ 85 | { 86 | ErrorHandler (15); 87 | } 88 | 89 | /* logic inversion operator has appeared */ 90 | if (flag) 91 | { 92 | GenINTCode (opr, 18, 0); /* logic inversion */ 93 | } 94 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /X0-Compiler/X0-Compiler.cpp: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | 3 | /* 4 | * function: check whether the syntax is correct, and generate intermediate code 5 | */ 6 | void compile () 7 | { 8 | /* we are not sure where the program should jump to, so backfill it later */ 9 | GenINTCode (jmp, 0, 0); 10 | ReadSymbol (); 11 | FunctionList (); 12 | code[0].opr1 = codeNum; /* backfill */ 13 | 14 | if (sym == mainsym) 15 | { 16 | fctNum++; 17 | strcpy (fctInfo[fctNum - 1].name, id); 18 | fctInfo[fctNum - 1].startINTCode = codeNum; 19 | fctInfo[fctNum - 1].paraNum = 0; 20 | fctInfo[fctNum - 1].tableSize = 0; 21 | fctInfo[fctNum - 1].retType = retVoid; 22 | 23 | ReadSymbol (); 24 | if (sym == lparen) 25 | { 26 | ReadSymbol (); 27 | if (sym == rparen) 28 | { 29 | ReadSymbol (); 30 | if (sym == lbrace) 31 | { 32 | ReadSymbol (); 33 | 34 | /* offset of local variable relative to the base address of current activity record */ 35 | int offset = 3; 36 | 37 | /* offset is increasing when analysing ConstDeclarationList */ 38 | ConstDeclarationList (&offset); 39 | 40 | /* offset is increasing when analysing VarDeclarationList */ 41 | VarDeclarationList (&offset); 42 | 43 | /* initialize a space in the stack for current activity record */ 44 | GenINTCode (ini, fctNum - 1, 0); 45 | 46 | StatementList (); 47 | 48 | if (sym == rbrace) 49 | { 50 | /* return to the location where current function is called */ 51 | GenINTCode (opr, 0, fctNum - 1); 52 | printf ("\nCompile successfully!\n"); 53 | } 54 | else /* the lack of '}' */ 55 | { 56 | ErrorHandler (4); 57 | } 58 | } 59 | else /* the lack of '{' */ 60 | { 61 | ErrorHandler (5); 62 | } 63 | } 64 | else /* the lack of ')' */ 65 | { 66 | ErrorHandler (14); 67 | } 68 | } 69 | else /* the lack of '(' */ 70 | { 71 | ErrorHandler (16); 72 | } 73 | } 74 | else /* the lack of 'main' */ 75 | { 76 | ErrorHandler (22); 77 | } 78 | } 79 | 80 | int main () 81 | { 82 | /*printf ("Input file path: "); 83 | scanf ("%s", fileName);*/ 84 | strcpy (fileName, "../../X0-Compiler-GUI/data/input.txt"); 85 | 86 | if ((fin = fopen (fileName, "r")) == NULL) /* can't open this file */ 87 | { 88 | printf ("can't open this file !\n"); 89 | return 1; 90 | } 91 | 92 | char temp = fgetc (fin); 93 | if (feof(fin)) /* input file is empty */ 94 | { 95 | printf ("input file is empty !\n"); 96 | fclose (fin); 97 | return 1; 98 | } 99 | rewind (fin); 100 | 101 | compile (); 102 | 103 | Interpret (); 104 | 105 | /*FILE* fout = fopen ("./data/code.bin", "wb"); 106 | fwrite (code, sizeof (code[0]), codeNum, fout); 107 | fclose (fout); 108 | 109 | fout = fopen ("./data/fctInfo.bin", "wb"); 110 | fwrite (fctInfo, sizeof (fctInfo[0]), fctNum, fout); 111 | fclose (fout);*/ 112 | 113 | return 0; 114 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # X0-Compiler 2 | This is a compiler written by c++ for x0-language which is a kind of programming language like c. You can also use its GUI in [X0-Compiler-GUI](https://github.com/GooCoder/X0-Compiler-GUI) . 3 | 4 | ## Installation 5 | 6 | Clone the repository to your computer and open the `X0-Compiler.sln` with **visual studio 2017**. 7 | 8 | ## Grammar 9 | 10 | The grammar of x0-language is defined in [x0-grammar.ebnf](https://github.com/GooCoder/X0-Compiler/blob/master/X0-Compiler/x0-grammar/x0-grammar.ebnf) which is described with EBNF. You can also see the syntax diagram in [x0-grammar.pdf](https://github.com/GooCoder/X0-Compiler/blob/master/X0-Compiler/x0-grammar/x0-grammar.pdf). 11 | 12 | ## Supports 13 | 14 | | Module | Status | 15 | | :--------------------------------------------: | :----: | 16 | | if-else | Y | 17 | | for | Y | 18 | | switch-case | Y | 19 | | do-while | Y | 20 | | repeat-until | Y | 21 | | while | Y | 22 | | break, continue, exit | Y | 23 | | data type: int, double, char, bool | Y | 24 | | constant | Y | 25 | | all operators | Y | 26 | | n-dimension array | Y | 27 | | function call with return value and parameters | Y | 28 | | function call with address parameter | N | 29 | 30 | ## Examples 31 | 32 | Calculate the GCD(greatest common divisor) between two numbers. 33 | 34 | ```c++ 35 | int GCD(int x, int y) 36 | { 37 | if (x % y == 0) 38 | { 39 | return y; 40 | } 41 | else 42 | { 43 | return GCD(y, x % y); 44 | } 45 | } 46 | 47 | main() 48 | { 49 | int a; 50 | int b; 51 | read a; 52 | read b; 53 | write GCD(a, b); 54 | } 55 | ``` 56 | 57 | Calculate 1 + 2 + ... + 10. 58 | 59 | ```c++ 60 | main() 61 | { 62 | int i; 63 | int sum; 64 | sum = 0; 65 | for (i = 1; i <= 10; i++) 66 | { 67 | sum = sum + i; 68 | } 69 | write sum; 70 | } 71 | ``` 72 | 73 | Find primes between 1 and n with sieve method. 74 | 75 | ```c++ 76 | void FindPrime(int n) 77 | { 78 | int isPrime[100]; 79 | int i; 80 | int j; 81 | for (i = 2; i <= n; i++) 82 | { 83 | isPrime[i] = 0; 84 | } 85 | for (i = 2; i <= n; ++i) 86 | { 87 | if (!isPrime[i]) 88 | { 89 | write i; 90 | } 91 | for (j = 2 * i; j <= n; j = j + i) 92 | { 93 | isPrime[j] = 1; 94 | } 95 | } 96 | } 97 | 98 | main() 99 | { 100 | int n; 101 | read n; 102 | FindPrime(n); 103 | } 104 | ``` 105 | ## Help 106 | 107 | If you have some problems can't be solved, please contact the author by email: **zjli1997@qq.com**. 108 | -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/SwitchStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * SwitchStat syntactical analyzer 5 | */ 6 | void SwitchStat () 7 | { 8 | int startBreakNum = brkNum; /* save the number of 'break' statement to be backfilled before analyzing SwitchStat */ 9 | 10 | if (sym == swtcsym) 11 | { 12 | ReadSymbol (); 13 | if (sym == lparen) 14 | { 15 | ReadSymbol (); 16 | expression (); 17 | if (sym == rparen) 18 | { 19 | ReadSymbol (); 20 | if (sym == lbrace) 21 | { 22 | ReadSymbol (); 23 | int pos1 = -1; /* the position of jpc in previous 'case' statement */ 24 | int pos2 = -1; /* the position of jmp in previous 'case' statement */ 25 | while (sym == cassym) 26 | { 27 | if (pos1 != -1) 28 | { 29 | code[pos1].opr1 = codeNum; /* backfill */ 30 | } 31 | ReadSymbol (); 32 | if (sym == intnum) 33 | { 34 | GenINTCode (lit, intNum, 0); 35 | GenINTCode (opr, 21, 0); /* '==' operation */ 36 | GenINTCode (jpc, 0, 0); 37 | pos1 = codeNum - 1; 38 | ReadSymbol (); 39 | if (sym == colonsym) 40 | { 41 | ReadSymbol (); 42 | if (pos2 != -1) 43 | { 44 | code[pos2].opr1 = codeNum; /* backfill */ 45 | } 46 | StatementList (); 47 | GenINTCode (jmp, 0, 0); 48 | pos2 = codeNum - 1; 49 | } 50 | else /* the lack of ':' */ 51 | { 52 | ErrorHandler (37); 53 | } 54 | } 55 | else /* the lack of integer */ 56 | { 57 | ErrorHandler (8); 58 | } 59 | } 60 | 61 | if (pos1 != -1) 62 | { 63 | code[pos1].opr1 = codeNum; /* backfill */ 64 | } 65 | 66 | if (pos2 != -1) 67 | { 68 | code[pos2].opr1 = codeNum; /* backfill */ 69 | } 70 | 71 | if (sym == defausym) 72 | { 73 | ReadSymbol (); 74 | if (sym == colonsym) 75 | { 76 | ReadSymbol (); 77 | StatementList (); 78 | } 79 | else /* the lack of ':' */ 80 | { 81 | ErrorHandler (37); 82 | } 83 | } 84 | 85 | if (sym == rbrace) 86 | { 87 | ReadSymbol (); 88 | } 89 | else /* the lack of '}' */ 90 | { 91 | ErrorHandler (4); 92 | } 93 | } 94 | else /* the lack of '{' */ 95 | { 96 | ErrorHandler (5); 97 | } 98 | } 99 | else /* the lack of ')' */ 100 | { 101 | ErrorHandler (14); 102 | } 103 | } 104 | else /* the lack of '(' */ 105 | { 106 | ErrorHandler (16); 107 | } 108 | } 109 | else /* the lack of 'switch' */ 110 | { 111 | ErrorHandler (36); 112 | } 113 | 114 | /* backfill 'break' statement */ 115 | for (int i = startBreakNum; i < brkNum; i++) 116 | { 117 | int pos = breakList[i]; 118 | code[pos].opr1 = codeNum; 119 | } 120 | brkNum = startBreakNum; /* set the value of brkNum to the value 121 | * that is before analyzing SwitchStat */ 122 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/VarDeclarationList.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * VarDeclarationStat syntactical analyzer 5 | */ 6 | void VarDeclarationStat (int* ptr_offset) 7 | { 8 | DataType dt = type (); 9 | 10 | if (sym == ident) 11 | { 12 | ReadSymbol (); 13 | if (sym == lbracket) 14 | { 15 | int size[MAX_DIMENSION] = { 0 }; 16 | int d = 0; 17 | int space = 1; /* the space distributed to this array */ 18 | while (sym == lbracket) 19 | { 20 | ReadSymbol (); 21 | if (sym == intnum) 22 | { 23 | size[d++] = intNum; 24 | space *= intNum; 25 | ReadSymbol (); 26 | if (sym == rbracket) 27 | { 28 | ReadSymbol (); 29 | } 30 | else /* the lack of ']' */ 31 | { 32 | ErrorHandler (9); 33 | } 34 | } 35 | else /* the lack of integer */ 36 | { 37 | ErrorHandler (8); 38 | } 39 | } 40 | 41 | if (dt == Char) /* char array is declared */ 42 | { 43 | EnterTable (charArray, *ptr_offset, size, d, 0); 44 | *ptr_offset = *ptr_offset + space; 45 | } 46 | else if (dt == Int) /* int array is declared */ 47 | { 48 | EnterTable (intArray, *ptr_offset, size, d, 0); 49 | *ptr_offset = *ptr_offset + space; 50 | } 51 | else if (dt == Bool) /* bool array is declared */ 52 | { 53 | EnterTable (boolArray, *ptr_offset, size, d, 0); 54 | *ptr_offset = *ptr_offset + space; 55 | } 56 | else /* double array is declared */ 57 | { 58 | EnterTable (doubleArray, *ptr_offset, size, d, 0); 59 | *ptr_offset = *ptr_offset + space; 60 | } 61 | } 62 | else 63 | { 64 | int size[MAX_DIMENSION] = { 0 }; 65 | int d = 0; 66 | if (dt == Char) /* char variable is declared */ 67 | { 68 | EnterTable (charVar, *ptr_offset, size, d, 0); 69 | *ptr_offset = *ptr_offset + 1; 70 | } 71 | else if (dt == Int) /* int variable is declared */ 72 | { 73 | EnterTable (intVar, *ptr_offset, size, d, 0); 74 | *ptr_offset = *ptr_offset + 1; 75 | } 76 | else if (dt == Bool) /* bool variable is declared */ 77 | { 78 | EnterTable (boolVar, *ptr_offset, size, d, 0); 79 | *ptr_offset = *ptr_offset + 1; 80 | } 81 | else /* double variable is declared */ 82 | { 83 | EnterTable (doubleVar, *ptr_offset, size, d, 0); 84 | *ptr_offset = *ptr_offset + 1; 85 | } 86 | } 87 | 88 | if (sym == semic) 89 | { 90 | ReadSymbol (); 91 | } 92 | else /* the lack of ';' */ 93 | { 94 | ErrorHandler (10); 95 | } 96 | 97 | } 98 | else /* the lack of identifier */ 99 | { 100 | ErrorHandler (6); 101 | } 102 | } 103 | 104 | /* 105 | * VarDeclarationList syntactical analyzer 106 | */ 107 | void VarDeclarationList (int* ptr_offset) 108 | { 109 | /* execute VarDeclarationStat syntactical analyzer if sym belong to first(VarDeclarationStat) */ 110 | while (sym == charsym || sym == intsym || sym == bolsym || sym == dblsym) 111 | { 112 | VarDeclarationStat (ptr_offset); 113 | } 114 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/ConstDeclarationList.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * ConstDeclarationStat syntactical analyzer 5 | */ 6 | void ConstDeclarationStat (int* ptr_offset) 7 | { 8 | if (sym == cstsym) 9 | { 10 | ReadSymbol (); 11 | } 12 | else /* the lack of 'const' */ 13 | { 14 | ErrorHandler (51); 15 | } 16 | 17 | DataType dt = type (); 18 | if (sym == ident) 19 | { 20 | ReadSymbol (); 21 | if (sym == eql) 22 | { 23 | ReadSymbol (); 24 | int size[MAX_DIMENSION] = { 0 }; 25 | int d = 0; 26 | if (sym == intnum || sym == doublenum) 27 | { 28 | ReadSymbol (); 29 | switch (dt) 30 | { 31 | case Int: 32 | EnterTable (constIntVar, *ptr_offset, size, 33 | d, sym == intnum ? intNum : doubleNum); 34 | *ptr_offset = *ptr_offset + 1; 35 | break; 36 | case Double: 37 | EnterTable (constDoubleVar, *ptr_offset, size, 38 | d, sym == intnum ? intNum : doubleNum); 39 | *ptr_offset = *ptr_offset + 1; 40 | break; 41 | case Char: 42 | EnterTable (constCharVar, *ptr_offset, size, 43 | d, sym == intnum ? intNum : doubleNum); 44 | *ptr_offset = *ptr_offset + 1; 45 | break; 46 | case Bool: 47 | EnterTable (constBoolVar, *ptr_offset, size, 48 | d, sym == intnum ? intNum : doubleNum); 49 | *ptr_offset = *ptr_offset + 1; 50 | break; 51 | } 52 | } 53 | else if (sym == truesym || sym == falsesym) 54 | { 55 | ReadSymbol (); 56 | switch (dt) 57 | { 58 | case Int: 59 | EnterTable (constIntVar, *ptr_offset, size, 60 | d, sym == truesym ? 1 : 0); 61 | *ptr_offset = *ptr_offset + 1; 62 | break; 63 | case Double: 64 | EnterTable (constDoubleVar, *ptr_offset, size, 65 | d, sym == truesym ? 1 : 0); 66 | *ptr_offset = *ptr_offset + 1; 67 | break; 68 | case Char: 69 | EnterTable (constCharVar, *ptr_offset, size, 70 | d, sym == truesym ? 1 : 0); 71 | *ptr_offset = *ptr_offset + 1; 72 | break; 73 | case Bool: 74 | EnterTable (constBoolVar, *ptr_offset, size, 75 | d, sym == truesym ? 1 : 0); 76 | *ptr_offset = *ptr_offset + 1; 77 | break; 78 | } 79 | } 80 | else /* the lack of number can be assigned */ 81 | { 82 | ErrorHandler (7); 83 | } 84 | 85 | if (sym == semic) 86 | { 87 | ReadSymbol (); 88 | } 89 | else /* the lack of ';' */ 90 | { 91 | ErrorHandler (10); 92 | } 93 | } 94 | else /* the lack of '=' */ 95 | { 96 | ErrorHandler (11); 97 | } 98 | } 99 | else /* the lack of identifier */ 100 | { 101 | ErrorHandler (6); 102 | } 103 | } 104 | 105 | /* 106 | * ConstDeclarationList syntactical analyzer 107 | */ 108 | void ConstDeclarationList (int* ptr_offset) 109 | { 110 | /* execute ConstDeclarationStat syntactical analyzer if sym belong to first(ConstDeclarationStat) */ 111 | while (sym == cstsym) 112 | { 113 | ConstDeclarationStat (ptr_offset); 114 | } 115 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/ForStat.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * ForStat syntactical analyzer 5 | */ 6 | void ForStat () 7 | { 8 | int startBreakNum = brkNum; /* save the number of 'break' statement to be backfilled before analyzing ForStat */ 9 | int startContinueNum = ctnNum; /* save the number of 'continue' statement to be backfilled before analyzing ForStat */ 10 | 11 | if (sym == forsym) 12 | { 13 | ReadSymbol (); 14 | if (sym == lparen) 15 | { 16 | ReadSymbol (); 17 | 18 | if (sym != semic) 19 | { 20 | expression (); 21 | } 22 | 23 | if (sym == semic) 24 | { 25 | ReadSymbol (); 26 | int L0 = codeNum; /* jumping label */ 27 | int pos1; 28 | int isEmpty = 1; /* isEmpty = 1 means judgement statement is empty */ 29 | if (sym != semic) 30 | { 31 | isEmpty = 0; 32 | expression (); 33 | pos1 = codeNum; /* save current value of codeNum for backfilling */ 34 | GenINTCode (jpc, 0, 0); /* the position where program jump to hasn't been determined. 35 | * we'll backfill it later */ 36 | } 37 | else 38 | { 39 | pos1 = codeNum; 40 | } 41 | 42 | GenINTCode (jmp, 0, 0); /* the position where program jump to hasn't been determined. 43 | * we'll backfill it later */ 44 | 45 | if (sym == semic) 46 | { 47 | ReadSymbol (); 48 | int L1 = codeNum; /* jumping label */ 49 | 50 | if (sym != rparen) 51 | { 52 | expression (); 53 | } 54 | 55 | GenINTCode (jmp, L0, 0); 56 | 57 | if (sym == rparen) 58 | { 59 | ReadSymbol (); 60 | int L2 = codeNum; /* jumping label */ 61 | statement (); 62 | 63 | /* backfill 'continue' statement */ 64 | for (int i = startContinueNum; i < ctnNum; i++) 65 | { 66 | int pos = continueList[i]; 67 | code[pos].opr1 = codeNum; 68 | } 69 | ctnNum = startContinueNum; /* set the value of ctnNum to the value 70 | * that is before analyzing ForStat */ 71 | 72 | GenINTCode (jmp, L1, 0); 73 | 74 | /* backfill the position where program jump to */ 75 | if (!isEmpty) 76 | { 77 | code[pos1].opr1 = codeNum; 78 | code[pos1 + 1].opr1 = L2; 79 | } 80 | else 81 | { 82 | code[pos1].opr1 = L2; 83 | } 84 | } 85 | else /* the lack of ')' */ 86 | { 87 | ErrorHandler (14); 88 | } 89 | } 90 | else /* the lack of ';' */ 91 | { 92 | ErrorHandler (10); 93 | } 94 | } 95 | else /* the lack of ';' */ 96 | { 97 | ErrorHandler (10); 98 | } 99 | } 100 | else /* the lack of '(' */ 101 | { 102 | ErrorHandler (16); 103 | } 104 | } 105 | else /* the lack of 'for' */ 106 | { 107 | ErrorHandler (30); 108 | } 109 | 110 | /* backfill 'break' statement */ 111 | for (int i = startBreakNum; i < brkNum; i++) 112 | { 113 | int pos = breakList[i]; 114 | code[pos].opr1 = codeNum; 115 | } 116 | brkNum = startBreakNum; /* set the value of brkNum to the value 117 | * that is before analyzing ForStat */ 118 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/FunctionList.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* 4 | * parameter syntactical analyzer 5 | */ 6 | void parameter (int* ptr_offset) 7 | { 8 | DataType dt = type (); 9 | 10 | if (sym == ident) 11 | { 12 | int size[MAX_DIMENSION] = { 0 }; 13 | int d = 0; 14 | if (dt == Char) 15 | { 16 | EnterTable (charVar, *ptr_offset, size, d, 0); 17 | *ptr_offset = *ptr_offset + 1; 18 | } 19 | else if (dt == Int) 20 | { 21 | EnterTable (intVar, *ptr_offset, size, d, 0); 22 | *ptr_offset = *ptr_offset + 1; 23 | } 24 | else if (dt == Bool) 25 | { 26 | EnterTable (boolVar, *ptr_offset, size, d, 0); 27 | *ptr_offset = *ptr_offset + 1; 28 | } 29 | else 30 | { 31 | EnterTable (doubleVar, *ptr_offset, size, d, 0); 32 | *ptr_offset = *ptr_offset + 1; 33 | } 34 | ReadSymbol (); 35 | } 36 | else /* the lack of identifier */ 37 | { 38 | ErrorHandler (6); 39 | } 40 | } 41 | 42 | /* 43 | * ParameterList syntactical analyzer 44 | */ 45 | int ParameterList (int* ptr_offset) 46 | { 47 | int paraNum = 0; 48 | if (sym == charsym || sym == intsym || sym == bolsym || sym == dblsym) 49 | { 50 | parameter (ptr_offset); 51 | paraNum++; 52 | while (sym == comma) 53 | { 54 | ReadSymbol (); 55 | parameter (ptr_offset); 56 | paraNum++; 57 | } 58 | } 59 | return paraNum; 60 | } 61 | 62 | /* 63 | * function syntactical analyzer 64 | */ 65 | void function () 66 | { 67 | if (sym == voidsym || sym == intsym || sym == charsym 68 | || sym == dblsym || sym == charsym) 69 | { 70 | Symbol tempSym = sym; 71 | ReadSymbol (); 72 | if (sym == ident) 73 | { 74 | fctNum++; 75 | strcpy (fctInfo[fctNum - 1].name, id); 76 | fctInfo[fctNum - 1].startINTCode = codeNum; 77 | fctInfo[fctNum - 1].tableSize = 0; 78 | 79 | switch (tempSym) 80 | { 81 | case voidsym: 82 | fctInfo[fctNum - 1].retType = retVoid; 83 | break; 84 | case intsym: 85 | fctInfo[fctNum - 1].retType = retInt; 86 | break; 87 | case dblsym: 88 | fctInfo[fctNum - 1].retType = retDouble; 89 | break; 90 | case charsym: 91 | fctInfo[fctNum - 1].retType = retChar; 92 | break; 93 | case bolsym: 94 | fctInfo[fctNum - 1].retType = retBool; 95 | break; 96 | default: 97 | break; 98 | } 99 | 100 | ReadSymbol (); 101 | if (sym == lparen) 102 | { 103 | ReadSymbol (); 104 | int offset = 3; 105 | int ParameterNum = ParameterList (&offset); 106 | fctInfo[fctNum - 1].paraNum = ParameterNum; 107 | if (sym == rparen) 108 | { 109 | ReadSymbol (); 110 | if (sym == lbrace) 111 | { 112 | ReadSymbol (); 113 | 114 | /* offset is increasing when analysing ConstDeclarationList */ 115 | ConstDeclarationList (&offset); 116 | 117 | /* offset is increasing when analysing VarDeclarationList */ 118 | VarDeclarationList (&offset); 119 | 120 | /* initialize a space in the stack for current activity record */ 121 | GenINTCode (ini, fctNum - 1, 0); 122 | 123 | StatementList (); 124 | 125 | if (sym == rbrace) 126 | { 127 | ReadSymbol (); 128 | 129 | /* return to the location where current function is called */ 130 | GenINTCode (opr, 0, fctNum - 1); 131 | } 132 | else /* the lack of '}' */ 133 | { 134 | ErrorHandler (4); 135 | } 136 | } 137 | else /* the lack of '{' */ 138 | { 139 | ErrorHandler (5); 140 | } 141 | } 142 | else /* the lack of ')' */ 143 | { 144 | ErrorHandler (14); 145 | } 146 | } 147 | else /* the lack of '(' */ 148 | { 149 | ErrorHandler (16); 150 | } 151 | } 152 | else /* the lack of identifier */ 153 | { 154 | ErrorHandler (6); 155 | } 156 | } 157 | else /* illegal return type of function */ 158 | { 159 | ErrorHandler (54); 160 | } 161 | } 162 | 163 | /* 164 | * FunctionList syntactical analyzer 165 | */ 166 | void FunctionList () 167 | { 168 | while (sym == voidsym || sym == intsym || sym == charsym 169 | || sym == dblsym || sym == charsym) 170 | { 171 | function (); 172 | } 173 | } -------------------------------------------------------------------------------- /X0-Compiler/synAnaly/ErrorHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "../global.h" 2 | 3 | /* error handler */ 4 | void ErrorHandler (int error_code) 5 | { 6 | char space[81]; 7 | memset (space, 32, sizeof(space)); 8 | 9 | /* mark the position of error */ 10 | if (posCh - 2 >= 0) 11 | { 12 | space[posCh - 2] = '\0'; 13 | } 14 | else 15 | { 16 | space[0] = '\0'; 17 | } 18 | 19 | printf ("%s^", space); 20 | 21 | switch (error_code) 22 | { 23 | case 1: 24 | printf ("too many character in one line of input file !\n"); 25 | break; 26 | case 2: 27 | printf ("the name of the identifier is too long !\n"); 28 | break; 29 | case 3: 30 | printf ("the number is too large !\n"); 31 | break; 32 | case 4: 33 | printf ("the lack of '}' !\n"); 34 | break; 35 | case 5: 36 | printf ("the lack of '{' !\n"); 37 | break; 38 | case 6: 39 | printf ("the lack of identifier !\n"); 40 | break; 41 | case 7: 42 | printf ("the lack of number can be assigned !\n"); 43 | break; 44 | case 8: 45 | printf ("the lack of integer !\n"); 46 | break; 47 | case 9: 48 | printf ("the lack of ']' !\n"); 49 | break; 50 | case 10: 51 | printf ("the lack of ';' !\n"); 52 | break; 53 | case 11: 54 | printf ("the lack of '=' !\n"); 55 | break; 56 | case 14: 57 | printf ("the lack of ')' !\n"); 58 | break; 59 | case 15: 60 | printf ("syntax error of 'factor' !\n"); 61 | break; 62 | case 16: 63 | printf ("the lack of '(' !\n"); 64 | break; 65 | case 17: 66 | printf ("the lack of 'if' !\n"); 67 | break; 68 | case 18: 69 | printf ("the lack of 'read' !\n"); 70 | break; 71 | case 19: 72 | printf ("illegal data type !\n"); 73 | break; 74 | case 20: 75 | printf ("the lack of 'while' !\n"); 76 | break; 77 | case 21: 78 | printf ("the lack of 'write' !\n"); 79 | break; 80 | case 22: 81 | printf ("the lack of 'main' !\n"); 82 | break; 83 | case 23: 84 | printf ("the identifier hasn't been declared !\n"); 85 | break; 86 | case 24: 87 | printf ("identifier isn't {const} variable !\n"); 88 | break; 89 | case 25: 90 | printf ("identifier isn't array !\n"); 91 | break; 92 | case 26: 93 | printf ("the program is too long !\n"); 94 | break; 95 | case 27: 96 | printf ("illegal operand of 'opr' instruction !\n"); 97 | break; 98 | case 28: 99 | printf ("illegal function code !\n"); 100 | break; 101 | case 30: 102 | printf ("the lack of 'for' !\n"); 103 | break; 104 | case 31: 105 | printf ("constant can't be modified !\n"); 106 | break; 107 | case 32: 108 | printf ("'read' function can't read Increasing or decreasing variable !\n"); 109 | break; 110 | case 33: 111 | printf ("the lack of 'break' !\n"); 112 | break; 113 | case 34: 114 | printf ("the lack of 'exit' !\n"); 115 | break; 116 | case 35: 117 | printf ("the lack of 'continue' !\n"); 118 | break; 119 | case 36: 120 | printf ("the lack of 'switch' !\n"); 121 | break; 122 | case 37: 123 | printf ("the lack of ':' !\n"); 124 | break; 125 | case 38: 126 | printf ("the lack of 'do' !\n"); 127 | break; 128 | case 39: 129 | printf ("the operand of mod operation must be integer !\n"); 130 | break; 131 | case 40: 132 | printf ("the parameter of exit function must be integer !\n"); 133 | break; 134 | case 41: 135 | printf ("the operand of && must be integer !\n"); 136 | break; 137 | case 42: 138 | printf ("the operand of || must be integer !\n"); 139 | break; 140 | case 43: 141 | printf ("the operand of ! must be integer !\n"); 142 | break; 143 | case 44: 144 | printf ("the operand of xor must be integer !\n"); 145 | break; 146 | case 45: 147 | printf ("the operand of odd must be integer !\n"); 148 | break; 149 | case 46: 150 | printf ("the subscript of array must be integer !\n"); 151 | break; 152 | case 47: 153 | printf ("illegal number !\n"); 154 | break; 155 | case 48: 156 | printf ("error type of symbol-table object !\n"); 157 | break; 158 | case 49: 159 | printf ("Increasing or decreasing variable must be INT or CHAR !\n"); 160 | break; 161 | case 50: 162 | printf ("array subscript is out of bound !\n"); 163 | break; 164 | case 51: 165 | printf ("the lack of 'const' !\n"); 166 | break; 167 | case 52: 168 | printf ("constant can't be read !\n"); 169 | break; 170 | case 53: 171 | printf ("top element isn't integer, 'tad' instruction can't work !\n"); 172 | break; 173 | case 54: 174 | printf ("illegal return type of function !\n"); 175 | break; 176 | case 55: 177 | printf ("the function hasn't been declared !\n"); 178 | break; 179 | default: 180 | printf ("illegal ErrorHandler code !\n"); 181 | } 182 | exit (0); 183 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /X0-Compiler/X0-Compiler.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;ipp;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 | {0a9f5e79-dc3b-4885-9705-f7bfbf9f6270} 18 | 19 | 20 | {92960a8f-0fd4-453c-8d22-4f6fada8ec59} 21 | 22 | 23 | 24 | 25 | 源文件 26 | 27 | 28 | 源文件 29 | 30 | 31 | 源文件 32 | 33 | 34 | 源文件\lexAnaly 35 | 36 | 37 | 源文件\lexAnaly 38 | 39 | 40 | 源文件\lexAnaly 41 | 42 | 43 | 源文件\synAnaly 44 | 45 | 46 | 源文件\synAnaly 47 | 48 | 49 | 源文件\synAnaly 50 | 51 | 52 | 源文件\synAnaly 53 | 54 | 55 | 源文件\synAnaly 56 | 57 | 58 | 源文件\synAnaly 59 | 60 | 61 | 源文件\synAnaly 62 | 63 | 64 | 源文件\synAnaly 65 | 66 | 67 | 源文件\synAnaly 68 | 69 | 70 | 源文件\synAnaly 71 | 72 | 73 | 源文件\synAnaly 74 | 75 | 76 | 源文件\synAnaly 77 | 78 | 79 | 源文件\synAnaly 80 | 81 | 82 | 源文件\synAnaly 83 | 84 | 85 | 源文件\synAnaly 86 | 87 | 88 | 源文件\synAnaly 89 | 90 | 91 | 源文件\synAnaly 92 | 93 | 94 | 源文件\synAnaly 95 | 96 | 97 | 源文件\synAnaly 98 | 99 | 100 | 源文件\synAnaly 101 | 102 | 103 | 源文件\synAnaly 104 | 105 | 106 | 源文件\synAnaly 107 | 108 | 109 | 源文件\synAnaly 110 | 111 | 112 | 源文件\synAnaly 113 | 114 | 115 | 源文件\synAnaly 116 | 117 | 118 | 源文件\synAnaly 119 | 120 | 121 | 源文件\synAnaly 122 | 123 | 124 | 源文件\synAnaly 125 | 126 | 127 | 源文件\synAnaly 128 | 129 | 130 | 源文件\synAnaly 131 | 132 | 133 | 源文件\synAnaly 134 | 135 | 136 | 源文件\synAnaly 137 | 138 | 139 | 140 | 141 | 头文件 142 | 143 | 144 | 头文件 145 | 146 | 147 | -------------------------------------------------------------------------------- /X0-Compiler/stackobj.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "global.h" 3 | 4 | /* object stored in data stack */ 5 | class StackObject 6 | { 7 | 8 | private: 9 | 10 | DataType ResultType (DataType dt1, DataType dt2) 11 | { 12 | if (dt1 == Double || dt2 == Double) 13 | { 14 | return Double; 15 | } 16 | else if (dt1 == Char || dt2 == Char) 17 | { 18 | return Char; 19 | } 20 | else 21 | { 22 | return Int; 23 | } 24 | } 25 | 26 | public: 27 | 28 | DataType dataType; 29 | int intData; /* store int/char/bool data */ 30 | double dblData; /* store double data */ 31 | 32 | StackObject () 33 | { 34 | dataType = Nul; 35 | } 36 | 37 | void assign (StackObject s) 38 | { 39 | if (dataType != Double) 40 | { 41 | if (s.dataType != Double) 42 | { 43 | intData = s.intData; 44 | } 45 | else 46 | { 47 | intData = (int)s.dblData; 48 | } 49 | } 50 | else 51 | { 52 | if (s.dataType != Double) 53 | { 54 | dblData = s.intData; 55 | } 56 | else 57 | { 58 | dblData = s.dblData; 59 | } 60 | } 61 | } 62 | 63 | /*StackObject operator = (const StackObject& s) 64 | { 65 | dataType = s.dataType; 66 | intData = s.intData; 67 | dblData = s.dblData; 68 | return *this; 69 | }*/ 70 | 71 | StackObject operator + (const StackObject& s) 72 | { 73 | StackObject res; 74 | if (dataType != Double && s.dataType != Double) 75 | { 76 | res.intData = intData + s.intData; 77 | } 78 | else 79 | { 80 | res.dblData = (dataType != Double ? intData : dblData) 81 | + (s.dataType != Double ? s.intData : s.dblData); 82 | } 83 | res.dataType = ResultType (dataType, s.dataType); 84 | return res; 85 | } 86 | 87 | StackObject operator - (const StackObject& s) 88 | { 89 | StackObject res; 90 | if (dataType != Double && s.dataType != Double) 91 | { 92 | res.intData = intData - s.intData; 93 | } 94 | else 95 | { 96 | res.dblData = (dataType != Double ? intData : dblData) 97 | - (s.dataType != Double ? s.intData : s.dblData); 98 | } 99 | res.dataType = ResultType (dataType, s.dataType); 100 | return res; 101 | } 102 | 103 | StackObject operator - () 104 | { 105 | intData = -intData; 106 | dblData = -dblData; 107 | return *this; 108 | } 109 | 110 | StackObject operator * (const StackObject& s) 111 | { 112 | StackObject res; 113 | if (dataType != Double && s.dataType != Double) 114 | { 115 | res.intData = intData * s.intData; 116 | } 117 | else 118 | { 119 | res.dblData = (dataType != Double ? intData : dblData) 120 | * (s.dataType != Double ? s.intData : s.dblData); 121 | } 122 | res.dataType = ResultType (dataType, s.dataType); 123 | return res; 124 | } 125 | 126 | StackObject operator / (const StackObject& s) 127 | { 128 | StackObject res; 129 | if (dataType != Double && s.dataType != Double) 130 | { 131 | res.intData = intData / s.intData; 132 | } 133 | else 134 | { 135 | res.dblData = (dataType != Double ? intData : dblData) 136 | / (s.dataType != Double ? s.intData : s.dblData); 137 | } 138 | res.dataType = ResultType (dataType, s.dataType); 139 | return res; 140 | } 141 | 142 | StackObject operator % (const StackObject& s) 143 | { 144 | /* The operand of mod operation must be integer */ 145 | if (dataType == Double || s.dataType == Double) 146 | { 147 | ErrorHandler (39); 148 | } 149 | StackObject res; 150 | res.intData = intData % s.intData; 151 | res.dataType = Int; 152 | return res; 153 | } 154 | 155 | StackObject operator == (const StackObject& s) 156 | { 157 | StackObject res; 158 | res.dataType = Bool; 159 | res.intData = (dataType != Double ? intData : dblData) 160 | == (s.dataType != Double ? s.intData : s.dblData); 161 | return res; 162 | } 163 | 164 | StackObject operator != (const StackObject& s) 165 | { 166 | StackObject res; 167 | res.dataType = Bool; 168 | res.intData = (dataType != Double ? intData : dblData) 169 | != (s.dataType != Double ? s.intData : s.dblData); 170 | return res; 171 | } 172 | 173 | StackObject operator > (const StackObject& s) 174 | { 175 | StackObject res; 176 | res.dataType = Bool; 177 | res.intData = (dataType != Double ? intData : dblData) 178 | > (s.dataType != Double ? s.intData : s.dblData); 179 | return res; 180 | } 181 | 182 | StackObject operator >= (const StackObject& s) 183 | { 184 | StackObject res; 185 | res.dataType = Bool; 186 | res.intData = (dataType != Double ? intData : dblData) 187 | >= (s.dataType != Double ? s.intData : s.dblData); 188 | return res; 189 | } 190 | 191 | StackObject operator < (const StackObject& s) 192 | { 193 | StackObject res; 194 | res.dataType = Bool; 195 | res.intData = (dataType != Double ? intData : dblData) 196 | < (s.dataType != Double ? s.intData : s.dblData); 197 | return res; 198 | } 199 | 200 | StackObject operator <= (const StackObject& s) 201 | { 202 | StackObject res; 203 | res.dataType = Bool; 204 | res.intData = (dataType != Double ? intData : dblData) 205 | <= (s.dataType != Double ? s.intData : s.dblData); 206 | return res; 207 | } 208 | 209 | StackObject operator && (const StackObject& s) 210 | { 211 | /* The operand of && must be integer */ 212 | if (dataType == Double || s.dataType == Double) 213 | { 214 | ErrorHandler (41); 215 | } 216 | StackObject res; 217 | res.intData = intData && s.intData; 218 | res.dataType = Bool; 219 | return res; 220 | } 221 | 222 | StackObject operator || (const StackObject& s) 223 | { 224 | /* The operand of || must be integer */ 225 | if (dataType == Double || s.dataType == Double) 226 | { 227 | ErrorHandler (42); 228 | } 229 | StackObject res; 230 | res.intData = intData || s.intData; 231 | res.dataType = Bool; 232 | return res; 233 | } 234 | 235 | StackObject operator ^ (const StackObject& s) 236 | { 237 | /* The operand of xor must be integer */ 238 | if (dataType == Double || s.dataType == Double) 239 | { 240 | ErrorHandler (44); 241 | } 242 | StackObject res; 243 | res.intData = intData ^ s.intData; 244 | res.dataType = Bool; 245 | return res; 246 | } 247 | 248 | StackObject operator ! () 249 | { 250 | /* The operand of ! must be integer */ 251 | if (dataType == Double) 252 | { 253 | ErrorHandler (43); 254 | } 255 | StackObject res; 256 | res.intData = !intData; 257 | res.dataType = Bool; 258 | return res; 259 | } 260 | }; 261 | -------------------------------------------------------------------------------- /X0-Compiler/X0-Compiler.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 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 15.0 67 | {2A4EE78C-7A45-4553-A296-78D8FE45A070} 68 | Win32Proj 69 | X0Compiler 70 | 10.0.16299.0 71 | 72 | 73 | 74 | Application 75 | true 76 | v141 77 | Unicode 78 | 79 | 80 | Application 81 | false 82 | v141 83 | true 84 | Unicode 85 | 86 | 87 | Application 88 | true 89 | v141 90 | Unicode 91 | 92 | 93 | Application 94 | false 95 | v141 96 | true 97 | Unicode 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | true 119 | 120 | 121 | true 122 | 123 | 124 | false 125 | 126 | 127 | false 128 | 129 | 130 | 131 | NotUsing 132 | Level3 133 | Disabled 134 | true 135 | _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 136 | true 137 | 138 | 139 | Console 140 | true 141 | 142 | 143 | 144 | 145 | Use 146 | Level3 147 | Disabled 148 | true 149 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 150 | true 151 | 152 | 153 | Console 154 | true 155 | 156 | 157 | 158 | 159 | Use 160 | Level3 161 | MaxSpeed 162 | true 163 | true 164 | true 165 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 166 | true 167 | 168 | 169 | Console 170 | true 171 | true 172 | true 173 | 174 | 175 | 176 | 177 | Use 178 | Level3 179 | MaxSpeed 180 | true 181 | true 182 | true 183 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 184 | true 185 | 186 | 187 | Console 188 | true 189 | true 190 | true 191 | 192 | 193 | 194 | 195 | 196 | --------------------------------------------------------------------------------