diff options
Diffstat (limited to 'nandgame/assembler')
| -rwxr-xr-x | nandgame/assembler/parser.py | 89 | ||||
| -rw-r--r-- | nandgame/assembler/parsetypes.py | 11 |
2 files changed, 60 insertions, 40 deletions
diff --git a/nandgame/assembler/parser.py b/nandgame/assembler/parser.py index 9e4bf45..a140eea 100755 --- a/nandgame/assembler/parser.py +++ b/nandgame/assembler/parser.py @@ -8,14 +8,9 @@ from ply.lex import LexToken # Get the token map from the lexer. This is required. from lexer import tokens -# Error rule for syntax errors - +import parsetypes as pt -def p_error(p: LexToken): - if p: - print(f"Unexpected {repr(p.value)} on line {p.lineno}") - else: - print("Unexpected end of file.") +# Error rule for syntax errors def p_program(p): @@ -30,7 +25,7 @@ def p_empty(p): pass -def p_inss(p): +def p_instructions(p): """instruction_list : instruction_list line | line """ @@ -38,15 +33,11 @@ def p_inss(p): p[0] = [p[1]] else: p[0] = p[1] + [p[2]] - - # print(f"INSes: {len(p)}") - # print(f" {p[1]}") - # if len(p) > 2: - # print(f" {p[2]}") pass -def p_inss2(p): +# try right-recursive? +def p_instructions2(p): """instruction_list2 : line instruction_list2 | line """ @@ -73,11 +64,11 @@ def p_line(p): def p_instruction(p): - """instruction : noarg - | onearg - | twoarg + """instruction : no_args + | two_arg + | three_arg | jumpdest - | invalid_arg + | one_arg_invalid """ print(f"Item: {p[1]}") p[0] = p[1] @@ -85,46 +76,57 @@ def p_instruction(p): def p_jumpdest(p): - """jumpdest : SYMBOL COLON""" + """jumpdest : symbol COLON""" p[0] = (p[1],) -def p_twoarg(p): - """twoarg : op REG COMMA argument COMMA argument""" - p[0] = (*p[1], p[2], p[4], p[6]) +def p_no_arg(p): + """no_args : opcode""" + p[0] = (*p[1], None, None, None) pass -def p_argument(p): - """argument : number - | REG - | SYMBOL - """ +def p_onearg_invalid(p): + """one_arg_invalid : opcode argument""" + print(f"Invalid number of arguments: {p[1:]}") + sys.exit(1) pass -def p_onearg(p): - """onearg : op REG COMMA argument""" +def p_two_arg(p): + """two_arg : opcode register COMMA argument""" p[0] = (*p[1], p[2], p[4], None) pass -def p_noarg(p): - """noarg : op""" - p[0] = (*p[1], None, None, None) +def p_three_arg(p): + """three_arg : opcode register COMMA argument COMMA argument""" + p[0] = (*p[1], p[2], p[4], p[6]) pass -def p_invalid_arg(p): - """invalid_arg : op argument""" - print(f"Invalid opcode, destination missing: {p[1:]}") - sys.exit(1) - pass +# checks which combinations are allowed is done one level up +def p_argument(p): + """argument : number + | register + | symbol + """ + p[0] = p[1] + + +def p_symbol(p): + """symbol : SYMBOL""" + p[0] = pt.Symbol(p[1]) + +def p_register(p): + """register : REG""" + p[0] = pt.Register(p[1]) -def p_op(p): - """op : OP DOT JUMP - | OP + +def p_opcode(p): + """opcode : OP DOT JUMP + | OP """ if len(p) == 2: p[0] = (p[1], None) @@ -139,4 +141,11 @@ def p_number(p): p[0] = p[1] +def p_error(p: LexToken): + if p: + print(f"Unexpected {repr(p.value)} on line {p.lineno}") + else: + print("Unexpected end of file.") + + parser = yacc.yacc() diff --git a/nandgame/assembler/parsetypes.py b/nandgame/assembler/parsetypes.py new file mode 100644 index 0000000..4769e02 --- /dev/null +++ b/nandgame/assembler/parsetypes.py @@ -0,0 +1,11 @@ +from dataclasses import dataclass + +@dataclass +class Symbol: + """Define a symbol""" + name: str + +@dataclass +class Register: + """Define a source or dest register""" + name: str |
