Skip to content

Commit

Permalink
fix test cases, redirect output to correct subfolders, update README
Browse files Browse the repository at this point in the history
  • Loading branch information
Hyper5phere committed Sep 19, 2020
1 parent 4a6f5c7 commit e628a92
Show file tree
Hide file tree
Showing 21 changed files with 563 additions and 137 deletions.
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 1,6 @@
# Simple C Compiler written in Python

Simple C Compiler supports a subset of C programming language. Most notably it has only integer typed variables. Nevertheless, it is a fully functional C compiler front-end for generating intermediate representation (IR) three address codes from a C source file. Also an interpreter for the three address "assembly" code is provided for all major platforms (Windows, Linux and Mac).
Simple C Compiler supports a subset of C programming language. Most notably it has only integer typed variables. Nevertheless, it is a fully functional C compiler front-end for generating intermediate representation (IR) three address codes from a C source file. Furthermore, an interpreter program [1] for the three address "assembly" code is provided for all major platforms (Windows, Linux and Mac) to execute the programs with ease.

As the name hints, it is also simple to use! Only one python module needed to start using it!

Expand All @@ -23,39 23,53 @@ For testing the compiler here is a simple test program that prints the 5 first o
*/

void main(void) {
/* all variables need to be declared first */
int i;
int j;
int m;
int N;

m = 0-1;
/* ...and then assigned to */
i = 1;
j = 1;
m = 0-1; // syntax only supports binary operations, this is how we get -1

N = 5; // change me to increase number of odd numbers
N = 15; // change me to increase number of odd numbers

while (i < N * 2 1) {
j = m * j;
if (j < 0) {
output(i);
} else {
// do nothing
// do nothing, the syntax does not support if without else :^)
}
i = i 1;
}

}
```
To compile and run it, type
```bash
git clone https://github.com/Hyper5phere/c-minus-compiler.git
cd c-minus-compiler
git clone https://github.com/Hyper5phere/simple-c-compiler.git
cd simple-c-compiler
python compiler.py input/input_simple.c --run
```

To see all input arguments type
```bash
python compiler.py --help
```

All output of the compiler is stored in the ``./output`` folder and all the input examples can be found from ``./input`` folder. Additionally errors are logged in the ``./errors/`` folder if ``--error-files`` input flag is used.


## Possible Future Improvements
Language support for
- arrays
- recursion
- string types
- string types
- nested functions (not really C though)

## References
[1] The interpreter program has been implemented by Romina Jafarian, at Computer Engineering Department of Sharif
University of Technology (Tehran) in Fall 2017.
10 changes: 5 additions & 5 deletions compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 80,14 @@ def compile(args):


if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Automatic test case runner for Compilers course exercises.')
parser.add_argument("source_file")
parser = argparse.ArgumentParser(description='Simple C Compiler written in Python')
parser.add_argument("source_file", help="Path to C source file.")
parser.add_argument('-r', '--run', action='store_true', help='Run the output program after compilation.')
parser.add_argument('-v', '--verbose', action='store_true', help='Print all used three address codes.')
parser.add_argument('-ef', '--error-files', action='store_true', help='Save compilation errors to text files.')
parser.add_argument('-ast', '--abstract-syntax-tree', action='store_true', help='Save abstract syntax tree to a text file.')
parser.add_argument('-st', '--symbol-table', action='store_true', help='Save symbol table to a text file.')
parser.add_argument('-t', '--tokens', action='store_true', help='Save tokens to a text file.')
parser.add_argument('-ast', '--abstract-syntax-tree', action='store_true', help='Save abstract syntax tree into a text file.')
parser.add_argument('-st', '--symbol-table', action='store_true', help='Save symbol table into a text file.')
parser.add_argument('-t', '--tokens', action='store_true', help='Save lexed tokens into a text file.')
args = parser.parse_args()
if not os.path.isabs(args.source_file):
args.source_file = os.path.abspath(script_dir)
Expand Down
2 changes: 1 addition & 1 deletion errors/semantic_errors.txt
Original file line number Diff line number Diff line change
@@ -1 1 @@
The input program is semantically correct.
The input program is semantically correct.
2 changes: 1 addition & 1 deletion errors/syntax_errors.txt
Original file line number Diff line number Diff line change
@@ -1 1 @@
There is no syntax error.
There is no syntax error.
30 changes: 30 additions & 0 deletions input/fibonacci.c
Original file line number Diff line number Diff line change
@@ -0,0 1,30 @@
/*
* Example source code
*
* prints N numbers from Fibonacci sequence
*/

void main(void) {
int i;
int N;
int a;
int b;
int tmp;

i = 0;
a = 0;
b = 1;
tmp = 0;

N = 20; // how many numbers to print?

output(0); // always print the first number

while (i < N) {
output(a b);
tmp = b;
b = a tmp;
a = tmp;
i = i 1;
}
}
7 changes: 4 additions & 3 deletions input/input_simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 5,16 @@
*/

void main(void) {
/* all variables need to be declared first */
int i;
int j;
int m;
int N;

m = 0-1;
/* ...and then assigned to */
i = 1;
j = 1;
m = 0-1; // syntax only supports binary operations, this is how we get -1

N = 15; // change me to increase number of odd numbers

Expand All @@ -21,9 23,8 @@ void main(void) {
if (j < 0) {
output(i);
} else {
// do nothing
// do nothing, the syntax does not support if without else :^)
}
i = i 1;
}

}
8 changes: 5 additions & 3 deletions modules/cparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 16,7 @@
from semantic_analyser import SemanticAnalyser
from code_gen import CodeGen, MemoryManager

script_dir = os.path.dirname(os.path.abspath(__file__))
script_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

non_terminal_to_missing_construct = {
"Program" : "int ID;",
Expand Down Expand Up @@ -305,6 305,8 @@

class Parser(object):
def __init__(self, input_file):
if not os.path.isabs(input_file):
input_file = os.path.join(script_dir, input_file)
self.scanner = Scanner(input_file)
self.semantic_analyzer = SemanticAnalyser()
self.code_generator = CodeGen()
Expand All @@ -313,8 315,8 @@ def __init__(self, input_file):
self.parse_tree = self.root
self.stack = [Node("$"), self.root]

self.parse_tree_file = os.path.join(script_dir, "parse_tree.txt")
self.syntax_error_file = os.path.join(script_dir, "syntax_errors.txt")
self.parse_tree_file = os.path.join(script_dir, "output", "parse_tree.txt")
self.syntax_error_file = os.path.join(script_dir, "errors", "syntax_errors.txt")


@property
Expand Down
1 change: 1 addition & 0 deletions modules/lexical_errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 1 @@
There is no lexical errors.
10 changes: 0 additions & 10 deletions modules/output.txt

This file was deleted.

Loading

0 comments on commit e628a92

Please sign in to comment.