def analyze_logic_expr(): ''' logic_term {||, logic_term} ''' result = Parser.analyze_logic_term() value = Parser.tok.curr while Parser.is_valid(value) and value.t == const.OR: result = nd.BinOp(value.t, [result, Parser.analyze_logic_term()]) value = Parser.tok.curr return result
def analyze_logic_term(): ''' logic_factor {&&, logic_factor} ''' result = Parser.analyze_logic_factor() value = Parser.tok.curr # expected to be a TERM_OPS while Parser.is_valid(value) and value.t == const.AND: result = nd.BinOp(value.t, [result, Parser.analyze_logic_factor()]) value = Parser.tok.curr return result
def analyze_term(): ''' terms accept * and / and are "inside" expressions ''' result = Parser.analyze_fact() value = Parser.tok.get_next() # expected to be a TERM_OPS while Parser.is_valid(value) and value.t in const.TERM_OPS: result = nd.BinOp(value.t, [result, Parser.analyze_fact()]) value = Parser.tok.get_next() return result
def p_relexp(p): '''relexp : expression | relexp GT relexp | relexp EQ relexp | relexp LT relexp''' if len(p) == 2: # relexp : expression p[0] = p[1] else: p[0] = nd.BinOp(p[2], [p[1], p[3]])
def analyze_expression(): ''' expressions accept + and - and are the most "outter" math operation ''' result = Parser.analyze_term() value = Parser.tok.curr while Parser.is_valid(value) and value.t in const.EXPR_OPS: result = nd.BinOp(value.t, [result, Parser.analyze_term()]) value = Parser.tok.curr return result
def analyze_logic_stmt(): ''' expr (== | > | <) expr ''' expr = Parser.analyze_expression() value = Parser.tok.curr if value.t not in const.LOGIC_EXPR_OPS: utils.print_error(Parser) raise ValueError(f'Unexpected token type {value.t}, expected a' + ' logic expression') operator = value.t return nd.BinOp(operator, [expr, Parser.analyze_expression()])
def analyze_argdec(): ''' <type> <varname> {, <varname>} ''' type_ = Parser.tok.curr.val varnames = [Parser.tok.get_next()] if varnames[0].t != const.VARIABLE: utils.print_error(Parser) raise ValueError( 'Unexpected token type {}, expected variable name'.format( varnames[0].t)) varnames = [varname.val for varname in varnames] return nd.BinOp(const.DECLARE, [type_, varnames])
def analyze_attr(): ''' attr are basically formed of variable = expr ''' variable_name = Parser.tok.curr.val value = Parser.tok.get_next() # should be assigner if value.t != const.ASSIGN: utils.print_error(Parser) raise ValueError('Unexpected token type {}, expected ='.format( value.t)) return nd.BinOp( const.ASSIGN, [variable_name, Parser.analyze_expression()])
def analyze_while(): ''' while has 3 children: 1: Operation to be evaluated (true/false) 2: Loop content (stmt) ''' value = Parser.tok.get_next() if value.t != const.OPEN_PARENT: raise ValueError('Unexpected token type {}, expected ('.format( value.t)) logic = Parser.analyze_logic_expr() value = Parser.tok.curr if value.t != const.CLOSE_PARENT: raise ValueError('Unexpected token type {}, expected )'.format( value.t)) return nd.BinOp(const.WHILE, [logic, Parser.analyze_stmt()])
def analyze_vardec(): ''' <type> <varname> {, <varname>} ''' type_ = Parser.tok.curr.val varnames = [Parser.tok.get_next()] if varnames[0].t != const.VARIABLE: raise ValueError( 'Unexpected token type {}, expected variable name'.format( varnames[0].t)) value = Parser.tok.get_next() if value.t == const.OPEN_PARENT: return Parser.analyze_funcdec_pt2(type_, varnames[0].val) while Parser.is_valid(value) and value.t == const.COMMA: value = Parser.tok.get_next() if value.t != const.VARIABLE: raise ValueError(f'Unexpected token type {value.t}, ' + 'expected variable name') varnames.append(value) value = Parser.tok.get_next() varnames = [varname.val for varname in varnames] return nd.BinOp(const.DECLARE, [type_, varnames])
def p_expression_plus(p): 'expression : expression PLUS expression' p[0] = nd.BinOp('+', [p[1], p[3]])
def p_assign(p): 'assign : ID ASSIGNER relexp' p[0] = nd.BinOp(':=', [p[1], p[3]])
def p_loop(p): 'loop : LOOP relexp OPEN_BRACKET stmts CLOSE_BRACKET' p[0] = nd.BinOp('loop', [p[2], p[4]])
def p_term_and(p): 'term : term AND relexp' p[0] = nd.BinOp('&', [p[1], p[3]])
def p_term_div(p): 'term : term DIV expression' p[0] = nd.BinOp('/', [p[1], p[3]])
def p_term_times(p): 'term : term MULT expression' p[0] = nd.BinOp('*', [p[1], p[3]])
def p_expression_minus(p): 'expression : expression MINUS expression' p[0] = nd.BinOp('-', [p[1], p[3]])
def p_expression_or(p): 'expression : expression OR relexp' p[0] = nd.BinOp('|', [p[1], p[3]])