Exemplo n.º 1
0
def p_expr_number(p: YaccProduction):
    """expr : INTEGER
            | FLOAT
            | INTEGER FLOAT"""
    if len(p) == 2:
        p[0] = Number([p[1]], p.lineno(1), p.lineno(1), p.lexpos(1), p.lexpos(1) + len(str(p[1])) - 1)
    elif len(p) == 3:
        p[0] = Number([p[1] + p[2]], p.lineno(1), p.lineno(2), p.lexpos(1), p.lexpos(2) + len(str(p[2])))
Exemplo n.º 2
0
def p_expr_variable(p: YaccProduction):
    """expr : ID"""
    # Get the the table of variable from parser
    variables: dict = p.parser.variables
    # If the variable has not been defined, raise error
    if p[1] not in variables.keys():
        raise UndefineError(p[1], p.lineno(1), p.lexpos(1))
    # If the variable has been defined, get variable from table
    p[0] = Variable(variables.get(p[1]), p.lineno(1), p.lineno(1), p.lexpos(1), p.lexpos(1) + len(p[1]) - 1)
Exemplo n.º 3
0
def p_expr_arithmetic(p: YaccProduction):
    """expr : LPAREN expr RPAREN
            | expr PLUS expr
            | expr MINUS expr
            | expr TIMES expr
            | expr DIVIDE expr"""
    if p[1] == "(" and p[3] == ")":
        p[0] = Arithmetic("()", [p[2]], p.lineno(1), p.lineno(3), p.lexpos(1), p.lexpos(3))
    else:
        p[0] = Arithmetic(p[2], [p[1], p[3]],
                          p[1].start_line_number, p[3].end_line_number, p[1].start_position, p[3].end_position)
Exemplo n.º 4
0
def make_none(p: YaccProduction, token: int) -> Literal:
    assert namespace
    none = Literal(NoneValue())
    none.location = Location(file, p.lineno(token))
    none.namespace = namespace
    none.lexpos = p.lexpos(token)
    return none
Exemplo n.º 5
0
    def copy_p_tracking(self, p: P, from_: int = 1, to: int = 0) -> None:
        """Don't know why P's tracking info (lexpos and lineno) sometimes missing.
        Particular in recursion grammar situation. We have to copy it manually.

        Add this function in a p_xxx function when:
            1. the p[0] is gona to be used in another parsing target.
            2. and the tracking information is gona to be used there.
        """
        p.set_lexpos(to, p.lexpos(from_))
        p.set_lineno(to, p.lineno(from_))
Exemplo n.º 6
0
def merge_lnr_to_string(p: YaccProduction,
                        starttoken: int = 1,
                        endtoken: int = 2) -> None:
    assert namespace
    v = p[0]

    et = p[endtoken]
    st = p[starttoken]

    expanded_range: Range = expand_range(
        st.location, et.location) if isinstance(
            st, LocatableString) else et.location
    p[0] = LocatableString(v, expanded_range, p.lexpos(endtoken), namespace)
Exemplo n.º 7
0
def p_expr_function(p: YaccProduction):
    """expr : ID LPAREN RPAREN
            | ID LPAREN args RPAREN"""
    # Judge whether the function has been defined
    if p[1] not in dir(builtins):
        raise UndefineError(p[1], p.lineno(1), p.lexpos(1))
    # Judge the count of arguments
    if len(p) == 4:
        input_args_count = 0
    elif len(p) == 5:
        print(p[3])
        input_args_count = len(p[3])
    func = getattr(builtins, p[1])
    args_count = func.__code__.co_argcount
    # why minus 1: because builtin function will be injected argument of 'env' at the first position
    if input_args_count != args_count - 1:
        raise ArgumentError(p[1], p.lineno(1), p.lexpos(1), args_count-1, input_args_count)
    if len(p) == 4:
        p[0] = Function(p[1], [], p.lineno(1), p.lineno(3), p.lexpos(1), p.lexpos(3))
    elif len(p) == 5:
        p[0] = Function(p[1], p[3], p.lineno(1), p.lineno(4), p.lexpos(1), p.lexpos(4))
Exemplo n.º 8
0
def p_statement_assign(p: YaccProduction):
    """statement : ID ASSIGN expr SEMI"""
    # register variable in parser, and it will help us detect undefine error early
    variables: dict = p.parser.variables
    p[0] = AssignStatement(p[1], p[2], p[3], p.lineno(1), p.lineno(4), p.lexpos(1), p.lexpos(4))
    variables[p[1]] = p[0]
Exemplo n.º 9
0
 def loc(p: yacc.YaccProduction) -> Dict[str, int]:
     return {
         'line': p.lineno(1),
         'column': find_column(p.lexpos(1)),
     }
Exemplo n.º 10
0
 def p_comment(self, p: P) -> None:
     comment = p[1]
     self.push_comment(comment)
     self.set_last_newline_pos(p.lexpos(2))
Exemplo n.º 11
0
def p_expr_unary(p: YaccProduction):
    """expr : MINUS expr %prec UMINUS
            | PLUS expr %prec UPLUS"""
    p[0] = Unary(p[1], [p[2]], p.lineno(1), p[2].end_line_number, p.lexpos(1), p[2].end_position)
Exemplo n.º 12
0
def p_expr_bool(p: YaccProduction):
    """expr : BOOL"""
    p[0] = Bool([p[1]], p.lineno(1), p.lineno(1), p.lexpos(1), p.lexpos(1) + len(str(p[1])))
Exemplo n.º 13
0
def p_expr_string(p: YaccProduction):
    """expr : STRING"""
    p[0] = String([p[1]], p.lineno(1), p.lineno(1), p.lexpos(1), p.lexpos(1) + len(p[1]) - 1)
Exemplo n.º 14
0
 def p_newline(self, p: P) -> None:
     self.clear_comment_block()
     self.set_last_newline_pos(p.lexpos(1))
Exemplo n.º 15
0
def attach_lnr(p: YaccProduction, token: int = 1) -> None:
    v = p[0]
    v.location = Location(file, p.lineno(token))
    v.namespace = namespace
    v.lexpos = p.lexpos(token)
Exemplo n.º 16
0
def p_statement_conditional(p: YaccProduction):
    """statement : expr COMMA expr SEMI"""
    p[0] = ConditionalStatement(p[1], p[3], p[1].start_line_number, p.lineno(4), p[1].start_position, p.lexpos(4))
Exemplo n.º 17
0
def p_statement_normal(p: YaccProduction):
    """statement : expr SEMI"""
    p[0] = NormalStatement(p[1], p[1].start_line_number, p.lineno(2), p[1].start_position, p.lexpos(2))
Exemplo n.º 18
0
def p_statement_if(p: YaccProduction):
    """statement : IF expr THEN BEGIN statements END"""
    p[0] = IfStatement(p[2], p[5], p.lineno(1), p.lineno(6), p.lexpos(1), p.lexpos(6)+len(p[6])-1)
Exemplo n.º 19
0
 def current_indent(self, p: P, i: int = 1) -> int:
     lexpos = p.lexpos(i)
     indent = lexpos - self.last_newline_pos - 1
     if indent < 0:
         return -1
     return indent