class Parser: tokens = Lexer.tokens def __init__(self): self.parser = None self.lexer = None self.cNote = 60 # start values for notes self.cDur = 16 # start values for duration self.notes = [] self.commands = [] self.macros = {} def Parse(self, input, file, **kwargs): self.lexer = Lexer() self.lexer.Build(input, **kwargs) self.parser = yacc.yacc(module=self, **kwargs) self.commands = self.parser.parse(lexer=self.lexer.lexer) # print(f"Comandos: {self.commands}\n") Composer.compose(self.commands, self) if make_midi(self.notes, file): print( f"{bcolors.OKGREEN}File {bcolors.OKCYAN}{file}.midi{bcolors.OKGREEN} generated successfully{bcolors.RESET}" ) print( f"{bcolors.WARNING}*************************************************{bcolors.RESET}\n" ) else: print( f"{bcolors.FAIL}File {bcolors.OKCYAN}{file}.midi{bcolors.FAIL} not generated{bcolors.RESET}", file=sys.stderr) print( f"{bcolors.WARNING}*************************************************{bcolors.RESET}\n", file=sys.stderr) # error for yacc def p_error(self, p): print("Syntax error", file=sys.stderr) if p: print(f"Unexpected token '{p.type}'", file=sys.stderr) exit(1) # first note // start of melody def p_music0(self, p): """ music : action """ p[0] = [p[1]] # following notes of melody def p_music1(self, p): """ music : music action """ lst = p[1] lst.append(p[2]) p[0] = lst # sets the commands for a macro def p_action_def_macro(self, p): r""" action : MACRO '[' music ']' """ p[0] = Composer('def_macro', {'name': p[1][:-1], 'notes': p[3]}) # runs the stored commands in the macro def p_action_run_macro(self, p): """ action : RUNMACRO """ p[0] = Composer('run_macro', {'name': p[1][1:]}) # just the note def p_action0(self, p): """ action : NOTE """ args = {'note': p[1]} p[0] = Composer('note', args) # takes an action that affects notes def p_action1(self, p): """ action : up | dn | faster | slower """ if '^' in p[1]: args = {'val': len(p[1])} p[0] = Composer('raise', args) elif '_' in p[1]: args = {'val': len(p[1])} p[0] = Composer('lower', args) elif '<' in p[1]: args = {'val': len(p[1]) * 2} p[0] = Composer('faster', args) elif '>' in p[1]: args = {'val': len(p[1]) * 2} p[0] = Composer('slower', args) # defines a pause def p_action2(self, p): """ action : PAUSE """ args = {'val': len(p[1])} p[0] = Composer('pause', args) # defines a merge between notes def p_action3(self, p): """ action : NOTE JOIN NOTE | NOTE JOIN faster NOTE | NOTE JOIN slower NOTE """ if len(p) == 5: if '<' in p[3]: args = {'val': len(p[3]), 'note': p[1]} else: args = {'val': -len(p[3]), 'note': p[1]} else: args = {'val': 1, 'note': p[1]} p[0] = Composer('merge', args) # sets an highchord def p_action4(self, p): """ action : highchord """ p[0] = p[1] # raises half freq. by one def p_up0(self, p): """ up : UP """ p[0] = p[1] # produces a '^' times a factor def p_up1(self, p): """ up : up val""" p[0] = p[1] * p[2] # lowers half freq. by one def p_dn0(self, p): """ dn : DN """ p[0] = p[1] # produces a '_' times a factor def p_dn1(self, p): """ dn : dn val""" p[0] = p[1] * p[2] # gets the value factor def p_val(self, p): """ val : VAL """ p[0] = p[1] # speeds up def p_faster0(self, p): """ faster : FASTER """ p[0] = p[1] # slows down def p_slower0(self, p): """ slower : SLOWER """ p[0] = p[1] # highchord command def p_highchord(self, p): """ highchord : HIGHCHORD """ args = {'levels': [0, 4, 7]} p[0] = Composer('hchord', args)
class Parser: tokens = Lexer.tokens def __init__(self): self.parser = None self.lexer = None self.turtle = Turtle() self.vars = {} self.funcs = {} def Parse(self, input, **kwargs): self.lexer = Lexer() self.lexer.Build(input, **kwargs) self.parser = yacc.yacc(module=self, **kwargs) program = self.parser.parse(lexer=self.lexer.lexer) Command.exec(program, self) def value(self, val): if type(val) == dict and "operator" in val: left = self.value(val["left"]) right = self.value(val["right"]) op = val["operator"] if op == "+": return left + right elif op == "*": return left * right elif op == "-": return left - right elif op == "/": if right == 0: print("(Parser.py) Division by zero") exit(1) return left / right else: print(f"(Parser.py) Unknown operator: {op}") if type(val) == float: if val < 0: val = val * (-1) return val if type(val) == tuple: return val if val in self.vars: return self.vars[val] print(f"(Parser.py) Variable {val} undefined") return 0 def p_error(self, p): print("(Parser.py) Syntax error", file=sys.stderr) if p: print(f"(Parser.py) Unexpected token '{p}'", file=sys.stderr) exit(1) def p_program0(self, p): """ program : command """ p[0] = [p[1]] def p_program1(self, p): """ program : program command """ lst = p[1] lst.append(p[2]) p[0] = lst def p_value(self, p): """ value : NUMBER | VAR """ p[0] = p[1] def p_command0(self, p): """ command : forward value | fd value """ p[0] = Command("forward", p[2]) def p_command1(self, p): """ command : right value | rt value """ p[0] = Command("right", p[2]) def p_command2(self, p): """ command : back value | bk value """ p[0] = Command("backward", p[2]) def p_command3(self, p): """ command : left value | lt value """ p[0] = Command("left", p[2]) # SETPOS | SETXY def p_command4(self, p): """ command : setpos '[' value value ']' | setxy value value """ if len(p) == 6: args = {'x': p[3], 'y': p[4]} else: args = {'x': p[2], 'y': p[3]} p[0] = Command("setpos", args) def p_command5(self, p): """ command : setx value """ p[0] = Command("setx", p[2]) def p_command6(self, p): """ command : sety value """ p[0] = Command("sety", p[2]) def p_command7(self, p): """ command : home """ p[0] = Command("home", "") def p_command8(self, p): """ command : pendown | pd """ p[0] = Command("pendown") def p_command9(self, p): """ command : penup | pu """ p[0] = Command("penup") def p_command10(self, p): """ command : setpencolor '[' value value value ']' """ p[0] = Command("pencolor", {'r': p[3], 'g': p[4], 'b': p[5]}) def p_command11(self, p): """ command : make value value | make value value OPERATOR value """ args = {'var': p[2], 'val1': p[3]} if len(p) == 6: args['operator'] = p[4] args['val2'] = p[5] p[0] = Command("make", args) def p_command12(self, p): """ command : repeat value '[' program ']' """ p[0] = Command("repeat", {"value": p[2], "code": p[4]}) def p_command13(self, p): """ command : while '[' value SIGN value ']' '[' program ']' """ p[0] = Command("while", { 'value1': p[3], 'sign': p[4], 'value2': p[5], 'code': p[8] }) # IF | IFELSE def p_command14(self, p): """ command : if value SIGN value '[' program ']' | ifelse value SIGN value '[' program ']' '[' program ']' """ args = {'value1': p[2], 'sign': p[3], 'value2': p[4], 'code1': p[6]} if len(p) == 11: args['code2'] = p[9] p[0] = Command("if", args) def p_varlist(self, p): """ varlist : | value | varlist value """ if len(p) == 1: p[0] = [] elif len(p) == 2: p[0] = [p[1]] else: p[0] = p[1] p[0].append(p[2]) def p_command16(self, p): """ command : TO STR varlist program END """ p[0] = Command("to", {'name': p[2], 'args': p[3], 'code': p[4]}) def p_valuelist(self, p): """ valuelist : | value | valuelist value """ if len(p) == 1: p[0] = [] elif len(p) == 2: p[0] = [p[1]] else: p[0] = p[1] p[0].append(p[2]) def p_command17(self, p): """ command : STR valuelist """ p[0] = Command("call", {'name': p[1], 'args': p[2]})
class Parser: tokens = Lexer.tokens def __init__(self): self.parser = None self.lexer = None self.turtle = Turtle() def Parse(self, input, **kwargs): self.lexer = Lexer() self.lexer.Build(input, **kwargs) self.parser = yacc.yacc(module=self, **kwargs) program = self.parser.parse(lexer=self.lexer.lexer) for command in program: #print(command) command.line(self) def p_error(self): print("Syntax error", file=sys.stderr) exit(1) def p_program0(self, p): """ program : command """ p[0] = [p[1]] def p_program1(self, p): """ program : program command """ lst = p[1] lst.append(p[2]) p[0] = lst def p_command0(self, p): """ command : fd len """ args = {'len': p[2]} p[0] = Command("forward", args) def p_command1(self, p): """ command : forward len """ args = {'len': p[2]} p[0] = Command("forward", args) def p_command2(self, p): """ command : bk len """ args = {'len': p[2]} p[0] = Command("back", args) def p_command3(self, p): """ command : back len """ args = {'len': p[2]} p[0] = Command("back", args) def p_command4(self, p): """ command : lt deg """ args = {'deg': p[2]} p[0] = Command("left", args) def p_command5(self, p): """ command : left deg """ args = {'deg': p[2]} p[0] = Command("left", args) def p_command6(self, p): """ command : rt deg """ args = {'deg': p[2]} p[0] = Command("right", args) def p_command7(self, p): """ command : right deg """ args = {'deg': p[2]} p[0] = Command("right", args) def p_command8(self, p): """ command : setpos coordinate """ args = {'coordinate': p[2]} p[0] = Command("setpos", args) def p_command9(self, p): """ command : setxy coordinate """ args = {'coordinate': p[2]} p[0] = Command("setxy", args) def p_command10(self, p): """ command : sety y """ args = {'y': p[2]} p[0] = Command("sety", args) def p_command11(self, p): """ command : setx x """ args = {'x': p[2]} p[0] = Command("setx", args) def p_command12(self, p): """ command : home""" args = {} p[0] = Command("home", args) def p_command13(self, p): """ command : pendown """ args = {} p[0] = Command("pendown", args) def p_command14(self, p): """ command : pd """ args = {} p[0] = Command("pendown", args) def p_command15(self, p): """ command : penup """ args = {} p[0] = Command("penup", args) def p_command16(self, p): """ command : pu """ args = {} p[0] = Command("penup", args) def p_command17(self, p): """ command : setpencolor color """ args = {'color': p[2]} p[0] = Command("setpencolor", args) def p_color(self, p): """ color : '[' INT INT INT ']' """ p[0] = (p[2], p[3], p[4]) def p_len(self, p): """ len : INT """ p[0] = p[1] def p_deg(self, p): """ deg : INT """ p[0] = p[1] def p_x(self, p): """ x : INT """ p[0] = p[1] def p_y(self, p): """ y : INT """ p[0] = p[1] def p_coordinate0(self, p): """ coordinate : '[' INT INT ']' | INT INT """ if len(p) == 5: p[0] = (p[2], p[3]) else: p[0] = (p[1], p[2])
class Parser: tokens = Lexer.tokens precedence = ( ("left", '+', '-'), ("left", '*', '/') ) def __init__(self): self.parser = None self.lexer = None self.svg = LOGODraw() self.vars = {} # Symbol Table self.funcs = {} #self.color = (0, 0, 0) def value(self, val): _type = type(val) #type2 = Command #verifica se é uma expressao if _type == dict: value1 = self.value(val['value1']) if type(value1) != float: if value1 in self.vars: value1 = self.vars[value1] operator = val['op'] value2 = self.value(val['value2']) if type(value2) != float: if value2 in self.vars: value2 = self.vars[value2] if operator == '-': val = float(eval("value1 - value2",{"value1": value1, "value2": value2})) elif operator == '+': val = float(eval("value1 + value2",{"value1": value1, "value2": value2})) elif operator == '/': if value2 == 0: print("Division by zero") exit(1) val = float(eval("value1 / value2",{"value1": value1, "value2": value2})) elif operator == '*': val = float(eval("value1 * value2",{"value1": value1, "value2": value2})) #print(val) if type(val) == float: return val if val in self.vars: return self.vars[val] print(f"Variable {val} undefined") self.vars[val] = 0 return 0 def Parse(self, input, **kwargs): self.lexer = Lexer() self.lexer.Build(input,**kwargs) self.parser = yacc.yacc(module=self, **kwargs) program = self.parser.parse(lexer=self.lexer.lexer) Command.exec(program, self) def p_error(self, t): print("Syntax error", file=sys.stderr) exit(1) def p_program0(self, p): """ program : command """ p[0] = [p[1]] def p_program1(self, p): """ program : program command """ lst = p[1] lst.append(p[2]) p[0] = lst def p_command0(self, p): """ command : forward value | fd value """ p[0] = Command("forward", {'value': p[2]}) def p_command1(self, p): """ command : right value | rt value """ p[0] = Command("right", {'value': p[2]}) def p_command2(self, p): """ command : left value | lt value """ p[0] = Command("left", {'value': p[2]}) def p_command3(self, p): """ command : back value | bk value """ p[0] = Command("back", {'value': p[2]}) def p_command4(self, p): """ command : setpos '[' value value ']' | setxy value value """ if len(p) == 6: p[0] = Command("setpos", {'value1': p[3], 'value2': p[4]}) else: p[0] = Command("setpos", {'value1': p[2], 'value2': p[3]}) def p_command5(self, p): """ command : setx value """ p[0] = Command("setx", {'value': p[2]}) def p_command6(self, p): """ command : sety value """ p[0] = Command("sety", {'value': p[2]}) def p_command7(self, p): """ command : home """ p[0] = Command("home", {}) def p_command8(self, p): """ command : pendown | pd """ p[0] = Command("pendown", {}) def p_command9(self, p): """ command : penup | pu """ p[0] = Command("penup", {}) def p_command10(self, p): """ command : setpencolor '[' color ']' """ p[0] = Command("setpencolor",{ 'rgb': p[3] }) def p_color(self, p): """ color : value value value """ p[0] = (p[1], p[2], p[3]) def p_value(self, p): """ value : NUMBER | VAR | value '+' value | value '-' value | value '*' value | value '/' value """ if len(p)>2: p[0] = { 'value1': p[1], 'op': p[2], 'value2': p[3] } else: value = p[1] if type(p[1]) != float: value = p[1].replace('"',':') p[0] = value def p_command11(self, p): """ command : make VAR value """ var_value = p[2].replace('"',':') p[0] = Command("assign", {"target": var_value, "source": p[3]}) def p_command12(self, p): """ command : if value SIGN value '[' program ']' | ifelse value SIGN value '[' program ']' """ p[0] = Command("if", { 'value1': p[2], 'sign': p[3], 'value2': p[4], 'code': p[6], }) def p_command13(self, p): """ command : repeat value '[' program ']' """ p[0] = Command("repeat", { 'value': p[2], 'code': p[4] }) def p_command14(self, p): """ command : while '[' value SIGN value ']' '[' program ']' """ p[0] = Command("while", { 'value1': p[3], 'value2': p[5], 'sign': p[4], 'code': p[8] }) #function def p_command15(self, p): """ command : to STR varlist program end """ p[0] = Command("to", {"name": p[2], "args": p[3], "code": p[4]}) #varlist def p_varlist(self, p): """ varlist : | VAR | varlist VAR """ if len(p) == 1: p[0] = [] elif len(p) == 2: p[0] = [p[1]] else: p[0] = p[1] p[0].append(p[2]) #call def p_command_16(self, p): """ command : STR valuelist """ p[0] = Command("call", {"name": p[1], "args": p[2]}) #valuelist def p_valuelist(self, p): """ valuelist : | value | valuelist value """ if len(p) == 1: p[0] = [] elif len(p) == 2: p[0] = [p[1]] else: p[0] = p[1] p[0].append(p[2]) def p_stop(self,p): """ command : stop """ p[0] = Command("stop", {})