#!/usr/bin/env python3 import sys import ply.yacc as yacc from ply.lex import LexToken # Get the token map from the lexer. This is required. from lexer import tokens # Error rule for syntax errors def p_error(p: LexToken): if p: print(f"Unexpected {repr(p.value)} on line {p.lineno}") else: print("Unexpected end of file.") def p_program(p): """program : instruction_list | empty """ pass def p_empty(p): """empty :""" pass def p_inss(p): """instruction_list : instruction_list line | line """ if len(p) == 2: 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): """instruction_list2 : line instruction_list2 | line """ if len(p) == 2: p[0] = [p[1]] else: p[0] = [p[1]] + p[2] print(f"INSes2: {len(p)}") print(f" {p[1]}") if len(p) > 2: print(f" {p[2]}") pass def p_line(p): """line : instruction NL | NL """ if len(p) == 2: pass else: p[0] = p[1] def p_instruction(p): """instruction : noarg | onearg | twoarg | jumpdest | invalid_arg """ print(f"Item: {p[1]}") p[0] = p[1] pass def p_jumpdest(p): """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]) pass def p_argument(p): """argument : number | REG | SYMBOL """ pass def p_onearg(p): """onearg : op REG 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) pass def p_invalid_arg(p): """invalid_arg : op argument""" print(f"Invalid opcode, destination missing: {p[1:]}") sys.exit(1) pass def p_op(p): """op : OP DOT JUMP | OP """ if len(p) == 2: p[0] = (p[1], None) else: p[0] = (p[1], p[3]) def p_number(p): """number : NUMBER | HEXNUMBER """ p[0] = p[1] parser = yacc.yacc()