compile a file(into another file)
This commit is contained in:
parent
ae2337376c
commit
272b9801a9
5 changed files with 72 additions and 30 deletions
|
@ -2,4 +2,4 @@
|
|||
|
||||
- [ ] Error handling(so it wont just print sly: unexpected token or whatever it says)
|
||||
- [ ] Proper readme about files
|
||||
- [ ] Make cpq.py act as a cmd util - get input and output and such
|
||||
- [x] Make cpq.py act as a cmd util - get input and output and such
|
46
cpq.py
46
cpq.py
|
@ -1,4 +1,5 @@
|
|||
import sly
|
||||
import sys
|
||||
# for ease of reading, the compiler is broken down to multiple files
|
||||
# parser.py for the parser
|
||||
# lexer.py for the lexer
|
||||
|
@ -8,35 +9,24 @@ from parser import Parser
|
|||
from helper import print_err
|
||||
|
||||
|
||||
|
||||
|
||||
print_err('Aviv Romem')
|
||||
|
||||
if len(sys.argv) != 2 or not sys.argv[1].endswith('.ou'):
|
||||
print('USAGE: python cpq.py <file-name>.ou')
|
||||
exit(1)
|
||||
|
||||
file = sys.argv[1]
|
||||
output = file[:-3] + '.qud'
|
||||
f = open(file, 'r')
|
||||
text = f.read()
|
||||
f.close()
|
||||
lexer = Lexer()
|
||||
parser = Parser()
|
||||
text = '''
|
||||
a: int;
|
||||
{
|
||||
while(a < 10) {
|
||||
a = a + 1;
|
||||
if(a >= 6 || a == 5)
|
||||
break;
|
||||
else
|
||||
a = a + 0;
|
||||
}
|
||||
output(a);
|
||||
switch(a * 5) {
|
||||
case 1:
|
||||
a = 5;
|
||||
break;
|
||||
case 5:
|
||||
output(a);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
output(a);
|
||||
|
||||
}
|
||||
'''
|
||||
|
||||
file = sys.argv[1]
|
||||
|
||||
parser.parse(lexer.tokenize(text))
|
||||
for l, t in enumerate(parser.lines):
|
||||
print(l,':',t)
|
||||
if not parser.had_errors:
|
||||
f = open(output, 'w')
|
||||
f.writelines([l + '\n' for l in parser.lines])
|
||||
f.close()
|
||||
|
|
|
@ -13,7 +13,7 @@ class Parser(sly.Parser):
|
|||
tokens = Lexer.tokens
|
||||
symbol_table = {}
|
||||
had_errors = False # Simply to know if we need to write the program in the end
|
||||
lines = [ ]
|
||||
lines = [ '' ] # Start with en empty line, so len(lines) will represent the next line
|
||||
last_used_temp = 0 # cpl doesnt allow _ in ids, so use t_NUM as variables
|
||||
|
||||
def next_temp(self):
|
||||
|
@ -24,6 +24,7 @@ class Parser(sly.Parser):
|
|||
def program(self, p):
|
||||
self.lines.append('HALT')
|
||||
self.lines.append('Aviv Romem')
|
||||
self.lines.pop(0) # remove the empty line
|
||||
return None
|
||||
|
||||
@_('declarations declaration')
|
||||
|
|
22
test.ou
Normal file
22
test.ou
Normal file
|
@ -0,0 +1,22 @@
|
|||
a: int;
|
||||
{
|
||||
while(a < 10) {
|
||||
a = a + 1;
|
||||
if(a >= 6 || a == 5)
|
||||
break;
|
||||
else
|
||||
a = a + 0;
|
||||
}
|
||||
output(a);
|
||||
switch(a * 5) {
|
||||
case 1:
|
||||
a = 5;
|
||||
break;
|
||||
case 5:
|
||||
output(a);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
output(a);
|
||||
|
||||
}
|
29
test.qud
Normal file
29
test.qud
Normal file
|
@ -0,0 +1,29 @@
|
|||
ILSS t_1 a 10
|
||||
JMPZ 15 t_1
|
||||
IADD t_2 a 1
|
||||
IASN a t_2
|
||||
ILSS t_3 a 6
|
||||
IEQL t_3 t_3 0
|
||||
IEQL t_4 a 5
|
||||
IADD t_5 t_3 t_4
|
||||
JMPZ 12 t_5
|
||||
JUMP 15
|
||||
JUMP 14
|
||||
IADD t_6 a 0
|
||||
IASN a t_6
|
||||
JUMP 1
|
||||
IPRT a
|
||||
IMLT t_7 a 5
|
||||
IEQL t_8 t_7 1
|
||||
JMPZ 22 t_8
|
||||
IASN a 5
|
||||
JUMP 27
|
||||
JUMP 24
|
||||
IEQL t_8 t_7 5
|
||||
JMPZ 26 t_8
|
||||
IPRT a
|
||||
JUMP 26
|
||||
JUMP 27
|
||||
IPRT a
|
||||
HALT
|
||||
Aviv Romem
|
Loading…
Reference in a new issue