├── 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 |
--------------------------------------------------------------------------------