def analyze_logic_factor(): '''' !, logic_factor | logic_stmt ''' value = Parser.tok.curr if not Parser.is_valid(value): raise ValueError(f'invalid token {value.val} in logic factor') if value.t == const.NOT: return nd.UnOp(const.NOT, [Parser.analyze_logic_expr()]) else: return Parser.analyze_logic_stmt()
def analyze_print(): value = Parser.tok.get_next() # should be open_par if value.t != const.OPEN_PARENT: raise ValueError('Unexpected token type {}, expected ('.format( value.t)) result = nd.UnOp(const.PRINT, [Parser.analyze_expression()]) value = Parser.tok.curr if value.t != const.CLOSE_PARENT: raise ValueError('Unexpected token type {}, expected )'.format( value.t)) Parser.tok.get_next() return result
def analyze_fact(): ''' analyze a factor, as defined in the README.md ''' value = Parser.tok.get_next() if not Parser.is_valid(value): raise ValueError( 'Invalid token at position {} of the string "{}"'.format( Parser.tok.pos, Parser.tok.src)) if value.t == const.OPEN_PARENT: # analyze expr result = Parser.analyze_expression() if Parser.tok.curr.val == const.CLOSE_PARENT: return result else: raise ValueError( 'Expected closing parentesis, instead got {}'.format( Parser.tok.curr.val)) elif value.t in const.SIGN_OPS: # + or - factor return nd.UnOp(value.t, [Parser.analyze_fact()]) elif value.t == const.INT: return nd.IntVal(value.val, []) elif value.t == const.VARIABLE: if Parser.tok.peek().val == const.OPEN_PARENT: return Parser.analyze_funccall() return nd.VarVal(value.val, []) elif value.t == const.RESERVED_WORD and value.val == const.SCANF: value = Parser.tok.get_next() if value.t != const.OPEN_PARENT: raise ValueError(f'Unexpected token type {value.t}, ' + 'expected (') value = Parser.tok.get_next() if value.t != const.CLOSE_PARENT: raise ValueError(f'Unexpected token type {value.t}, ' + 'expected )') return nd.Scanf(value.val, []) else: utils.print_error(Parser) raise ValueError( 'Unexpected token type, expected a factor, got a {}'.format( value.t))
def p_out(p): 'out : PRINT relexp' p[0] = nd.UnOp(p[1], [p[2]])
def p_factor_sign_num(p): '''factor : PLUS expression %prec UPLUS | MINUS expression %prec UMINUS | NOT relexp''' p[0] = nd.UnOp(p[1], [p[2]])
def analyze_return(): ''' return <expression> ''' res = nd.UnOp(const.RETURN, [Parser.analyze_expression()]) return res