Franck Pommereau

fixed heratic parsing error, minor changes

...@@ -69,7 +69,7 @@ tokens = ( ...@@ -69,7 +69,7 @@ tokens = (
69 'DOUBLE_MINUS', 69 'DOUBLE_MINUS',
70 'PLUS', 70 'PLUS',
71 'MINUS', 71 'MINUS',
72 - 'TIMES', 72 +# 'TIMES',
73 'DIV', 73 'DIV',
74 'MODULO', 74 'MODULO',
75 'DOUBLE_AMPERSAND', 75 'DOUBLE_AMPERSAND',
...@@ -169,7 +169,7 @@ t_DOUBLE_PLUS = r'\+\+' ...@@ -169,7 +169,7 @@ t_DOUBLE_PLUS = r'\+\+'
169 t_DOUBLE_MINUS = r'--' 169 t_DOUBLE_MINUS = r'--'
170 t_PLUS = r'\+' 170 t_PLUS = r'\+'
171 t_MINUS = r'-' 171 t_MINUS = r'-'
172 -t_TIMES = r'\*' 172 +# t_TIMES = r'\*'
173 t_DIV = r'/(?!\*)' 173 t_DIV = r'/(?!\*)'
174 t_MODULO = r'%' 174 t_MODULO = r'%'
175 t_DOUBLE_AMPERSAND = r'&&' 175 t_DOUBLE_AMPERSAND = r'&&'
......
...@@ -755,9 +755,7 @@ def p_empty(t): ...@@ -755,9 +755,7 @@ def p_empty(t):
755 pass 755 pass
756 756
757 def p_error(t): 757 def p_error(t):
758 - print("You've got a syntax error somewhere in your code.") 758 + print("[%s:%s] syntax error" % (t.lineno, t.lexpos))
759 - print("It could be around line %d." % t.lineno)
760 - print("Good luck finding it.")
761 raise ParseError() 759 raise ParseError()
762 760
763 yacc.yacc(debug=1) 761 yacc.yacc(debug=1)
......
...@@ -2,6 +2,15 @@ import argparse, sys, os.path ...@@ -2,6 +2,15 @@ import argparse, sys, os.path
2 2
3 import ply.yacc as yacc 3 import ply.yacc as yacc
4 from . import cparse, cvisitors, cx86 4 from . import cparse, cvisitors, cx86
5 +cttc = cx86
6 +
7 +ARCH = {"x86" : cx86,
8 + "ttc" : cttc}
9 +
10 +ARCHDOC = """supported target architectures:
11 + x86 Intel 80x86 assembly (in GNU Assemble format)
12 + ttc The Tiny Computer assembly
13 +"""
5 14
6 class CompileError (Exception) : 15 class CompileError (Exception) :
7 "Exception raised when there's been a compilation error." 16 "Exception raised when there's been a compilation error."
...@@ -11,7 +20,8 @@ class Compiler (object) : ...@@ -11,7 +20,8 @@ class Compiler (object) :
11 """This object encapsulates the front-end for the compiler and 20 """This object encapsulates the front-end for the compiler and
12 serves as a facade interface to the 'meat' of the compiler 21 serves as a facade interface to the 'meat' of the compiler
13 underneath.""" 22 underneath."""
14 - def __init__ (self) : 23 + def __init__ (self, arch) :
24 + self.arch = arch
15 self.total_errors = 0 25 self.total_errors = 0
16 self.total_warnings = 0 26 self.total_warnings = 0
17 def _parse (self) : 27 def _parse (self) :
...@@ -31,12 +41,15 @@ class Compiler (object) : ...@@ -31,12 +41,15 @@ class Compiler (object) :
31 self._compile_phase(cvisitors.SymtabVisitor()) 41 self._compile_phase(cvisitors.SymtabVisitor())
32 self._compile_phase(cvisitors.TypeCheckVisitor()) 42 self._compile_phase(cvisitors.TypeCheckVisitor())
33 self._compile_phase(cvisitors.FlowControlVisitor()) 43 self._compile_phase(cvisitors.FlowControlVisitor())
34 - self._compile_phase(cx86.CodeGenVisitor(outfile)) 44 + self._compile_phase(self.arch.CodeGenVisitor(outfile))
35 if ast_file is not None: 45 if ast_file is not None:
36 self._compile_phase(cvisitors.ASTPrinterVisitor(ast_file)) 46 self._compile_phase(cvisitors.ASTPrinterVisitor(ast_file))
37 def _print_stats (self) : 47 def _print_stats (self) :
38 "Prints the total number of errors/warnings from compilation." 48 "Prints the total number of errors/warnings from compilation."
39 - print("%d errors, %d warnings." % (self.total_errors, self.total_warnings)) 49 + if self.total_errors :
50 + print("%d errors" % self.total_errors)
51 + if self.total_warnings :
52 + print("%s warnings" % self.total_warnings)
40 def compile (self, code, outfile, show_ast) : 53 def compile (self, code, outfile, show_ast) :
41 "Compiles the given code string to the given file object." 54 "Compiles the given code string to the given file object."
42 self.code = code 55 self.code = code
...@@ -54,21 +67,32 @@ class Compiler (object) : ...@@ -54,21 +67,32 @@ class Compiler (object) :
54 return 0 67 return 0
55 68
56 def main (args=None) : 69 def main (args=None) :
57 - parser = argparse.ArgumentParser(prog="cct") 70 + parser = argparse.ArgumentParser(prog="cct",
71 + epilog=ARCHDOC,
72 + formatter_class=argparse.RawDescriptionHelpFormatter)
58 parser.add_argument("-o", action="store", metavar="PATH", 73 parser.add_argument("-o", action="store", metavar="PATH",
59 type=argparse.FileType('w'), default=sys.stdout, 74 type=argparse.FileType('w'), default=sys.stdout,
60 help="write output to PATH") 75 help="write output to PATH")
61 parser.add_argument("--ast", action="store_true", default=False, 76 parser.add_argument("--ast", action="store_true", default=False,
62 help="dump AST for each C file") 77 help="dump AST for each C file")
78 + parser.add_argument("--arch", action="store", choices=list(ARCH),
79 + default="ttc",
80 + help="output assembly for specified architecture (default 'ttc')")
81 + parser.add_argument("-t", "--ttc", action="store_const", const="ttc",
82 + dest="arch", help="output TTC assembly")
63 parser.add_argument("source", nargs="+", metavar="PATH", 83 parser.add_argument("source", nargs="+", metavar="PATH",
64 help="C source files(s) to compile") 84 help="C source files(s) to compile")
65 args = parser.parse_args(args) 85 args = parser.parse_args(args)
66 for src in args.source : 86 for src in args.source :
87 + print("Compiling %r" % src)
67 if args.ast : 88 if args.ast :
68 - ast_file = open(os.path.splitext(src)[0] + ".ast", "w") 89 + ast_path = os.path.splitext(src)[0] + ".ast"
90 + print("Dumping AST to %r" % ast_path)
91 + ast_file = open(ast_path, "w")
69 else : 92 else :
70 ast_file = None 93 ast_file = None
71 - retval = Compiler().compile(open(src).read(), args.o, ast_file) 94 + code = "\n".join(open(src).readlines())
95 + retval = Compiler(ARCH[args.arch]).compile(code, args.o, ast_file)
72 if ast_file is not None : 96 if ast_file is not None :
73 ast_file.close() 97 ast_file.close()
74 if retval != 0 : 98 if retval != 0 :
......
This diff is collapsed. Click to expand it.