def p_def_class(p):
    """
    class_def : CLASS TYPE_ID LBRACE feature_list RBRACE SEMICOLON
              | CLASS TYPE_ID INHERITS TYPE_ID LBRACE feature_list RBRACE SEMICOLON
    """
    if len(p) == 7:
        p[0] = ast.ClassDeclarationNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(2)), p[2], p[4])
    else:
        p[0] = ast.ClassDeclarationNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(2)), p[2], p[6], p[4])
def p_branch_list(p):
    """
    branch_list : OBJECT_ID COLON type ACTION expr SEMICOLON
                | OBJECT_ID COLON type ACTION expr SEMICOLON branch_list
    """
    if len(p) == 7:
        p[0] = [ast.BranchNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1], p[3], p[5])]
    else:
        p[0] = [ast.BranchNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1], p[3], p[5])] + p[7]
def p_attr_def(p):
    """
    attr_def : OBJECT_ID COLON type
             | OBJECT_ID COLON type ASSIGN expr
    """
    if len(p) == 4:
        p[0] = ast.AttrDeclarationNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1], p[3])
    else:
        p[0] = ast.AttrDeclarationNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1], p[3], p[5])
def p_func_call(p):
    """
    func_call : atom DOT OBJECT_ID LPAREN arg_list RPAREN
              | OBJECT_ID LPAREN arg_list RPAREN
              | atom AT TYPE_ID DOT OBJECT_ID LPAREN arg_list RPAREN
    """
    if len(p) == 7:
        p[0] = ast.CallNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1], p[3], p[5])
    elif len(p) == 5:
        p[0] = ast.CallNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), None, p[1], p[3])
    elif len(p) == 9:
        p[0] = ast.CallNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1], p[5], p[7], p[3])
def p_factor(p):
    """
    factor : ISVOID factor
           | INT_COMP factor
           | atom
    """
    first_token = p.slice[1].type if len(p) > 1 else None
    if first_token == 'ISVOID':
        p[0] = ast.IsVoidNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2])
    elif first_token == 'INT_COMP':
        p[0] = ast.IntCompNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2])
    else:
        p[0] = p[1]
def p_term(p):
    """
    term : term MULT factor
         | term DIV factor
         | factor
    """
    operator = p.slice[2].type if len(p) > 2 else None
    if operator is None:
        p[0] = p[1]
    elif operator == 'MULT':
        p[0] = ast.StarNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    elif operator == 'DIV':
        p[0] = ast.DivNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
def p_arith(p):
    """
    arith : arith PLUS term
          | arith MINUS term
          | term
    """
    operator = p.slice[2].type if len(p) > 2 else None
    if operator is None:
        p[0] = p[1]
    elif operator == 'PLUS':
        p[0] = ast.PlusNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    elif operator == 'MINUS':
        p[0] = ast.MinusNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
def p_open_expr(p):
    """
    open_expr : LET let_var_list IN expr
              | OBJECT_ID ASSIGN expr
              | NOT expr
    """
    first_token = p.slice[1].type if len(p) > 1 else None
    if first_token == 'LET':
        p[0] = ast.LetNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2], p[4])
    elif first_token == 'OBJECT_ID':
        p[0] = ast.AssignNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1], p[3])
    elif first_token == 'NOT':
        p[0] = ast.NotNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2])
def p_open_expr_lvl3(p):
    """
    open_expr_lvl3 : ISVOID open_expr_lvl3
                   | INT_COMP open_expr_lvl3
                   | open_expr
    """
    first_token = p.slice[1].type if len(p) > 1 else None
    if first_token == 'ISVOID':
        p[0] = ast.IsVoidNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2])
    elif first_token == 'INT_COMP':
        p[0] = ast.IntCompNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1])
    else:
        p[0] = p[1]
def p_open_expr_lvl2(p):
    """
    open_expr_lvl2 : term MULT open_expr_lvl3
                   | term DIV open_expr_lvl3
                   | open_expr_lvl3
    """
    operator = p.slice[2].type if len(p) > 2 else None
    if operator == 'MULT':
        p[0] = ast.StarNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    elif operator == 'DIV':
        p[0] = ast.DivNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    else:
        p[0] = p[1]
def p_open_expr_lvl1(p):
    """
    open_expr_lvl1 : arith PLUS open_expr_lvl2
                   | arith MINUS open_expr_lvl2
                   | open_expr_lvl2
    """
    operator = p.slice[2].type if len(p) > 2 else None
    if operator == 'PLUS':
        p[0] = ast.PlusNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    elif operator == 'MINUS':
        p[0] = ast.MinusNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    else:
        p[0] = p[1]
def p_comparer(p):
    """
    comparer : comparer LT arith
             | comparer LTEQ arith
             | comparer EQ arith
             | arith
    """
    operator = p.slice[2].type if len(p) > 2 else None
    if operator == 'LT':
        p[0] = ast.LessNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    elif operator == 'LTEQ':
        p[0] = ast.LessEqualNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    elif operator == 'EQ':
        p[0] = ast.EqualNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    else:
        p[0] = p[1]
def p_error(p):
    if p is None:
        line_no = find_last_line(input_text)
        errors.append('(%s, 0) - SyntacticError: ERROR at or near EOF' % line_no)
    else:
        col_no = find_column(p.lexer.lexdata, p.lexpos)
        errors.append(('(%s, %s) - SyntacticError: ERROR at or near "%s"'.format(p) % (p.lineno, col_no, p.value)))
def p_expr(p):
    """
    expr : comparer LT open_expr_lvl1
         | comparer LTEQ open_expr_lvl1
         | comparer EQ open_expr_lvl1
         | open_expr_lvl1
         | comparer
    """
    operator = p.slice[2].type if len(p) > 2 else None
    if operator == 'LT':
        p[0] = ast.LessNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    elif operator == 'LTEQ':
        p[0] = ast.LessEqualNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    elif operator == 'EQ':
        p[0] = ast.EqualNode(p.lineno(2), find_column(p.lexer.lexdata, p.lexpos(2)), p[1], p[3])
    else:
        p[0] = p[1]
Exemple #15
0
 def p_error(self, p):
     self.errors = True
     if p:
         self.print_error(p)
     else:
         error_text = SyntaticError.ERROR % 'EOF'
         column = find_column(self.lexer.lexer, self.lexer.lexer)
         line = self.lexer.lexer.lineno
         print(SyntaticError(error_text, line, column - 1))
def t_STRING_newline(t):
    r"\n"
    if not t.lexer.string_backslash:  # FATAL ERROR
        errors.append(
            "(%s, %s) - LexicographicError: STRING ERROR NON-ESCAPED NEWLINE CHARACTER"
            % (t.lexer.lineno, find_column(t.lexer.lexdata, t.lexpos)))
        t.lexer.pop_state()
    else:
        t.lexer.string_backslash = False
    t.lexer.lineno += 1
def p_atom(p):
    """
    atom : INTEGER
         | OBJECT_ID
         | STRING
         | BOOL
         | LPAREN expr RPAREN
         | NEW TYPE_ID
         | IF expr THEN expr ELSE expr FI
         | WHILE expr LOOP expr POOL
         | LBRACE expr_list RBRACE
         | CASE expr OF branch_list ESAC
         | func_call
    """
    first_token = p.slice[1].type if len(p) > 1 else None
    second_token = p.slice[2].type if len(p) > 2 else None
    if first_token == 'INTEGER':
        p[0] = ast.ConstantNumNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1])
    elif first_token == 'OBJECT_ID' and second_token is None:
        p[0] = ast.VariableNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1])
    elif first_token == 'STRING':
        p[0] = ast.StringNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1])
    elif first_token == 'BOOL':
        p[0] = ast.BoolNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1])
    elif first_token == 'LPAREN':
        p[0] = p[2]
    elif first_token == 'NEW':
        p[0] = ast.InstantiateNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2])
    elif first_token == 'IF':
        p[0] = ast.ConditionalNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2], p[4], p[6])
    elif first_token == 'WHILE':
        p[0] = ast.LoopNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2], p[4])
    elif first_token == 'LBRACE':
        p[0] = ast.BlockNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2])
    elif first_token == 'CASE':
        p[0] = ast.CaseNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[2], p[4])
    elif first_token == 'func_call':
        p[0] = p[1]
def t_error(t):
    col = find_column(t.lexer.lexdata, t.lexpos)
    errors.append('(%s, %s) - LexicographicError: ILLEGAL CHARACTER "%s"' %
                  (t.lexer.lineno, col, t.value[0]))
    t.lexer.skip(1)
def t_COMMENT_eof(t):
    if t.lexer.current_state():
        col = find_column(t.lexer.lexdata, t.lexpos)
        errors.append("(%s, %s) - LexicographicError: EOF in comment" %
                      (t.lexer.lineno, col))
def t_COMMENT_error(t):
    col = find_column(t.lexer.lexdata, t.lexpos)
    errors.append("(%s, %s) - LexicographicError: COMMENT ERROR " %
                  (t.lexer.lineno, col))
    t.lexer.skip(1)
def t_STRING_eof(t):
    if t.lexer.current_state():
        errors.append(
            "(%s, %s) - LexicographicError: EOF ERROR IN STRING STATE" %
            (t.lexer.lineno, find_column(t.lexer.lexdata, t.lexpos)))
def t_STRING_error(t):
    col = find_column(t.lexer.lexdata, t.lexpos)
    errors.append("(%s, %s) - LexicographicError: ERROR %s " %
                  (t.lexer.lineno, col, t.value[0]))
    t.lexer.skip(1)
def t_STRING_null(t):
    r"\0"
    errors.append("(%s, %s) - LexicographicError: STRING NULL ERROR" %
                  (t.lexer.lineno, find_column(t.lexer.lexdata, t.lexpos)))
    t.lexer.skip(1)
def p_meth_def(p):
    """
    meth_def : OBJECT_ID LPAREN param_list RPAREN COLON type LBRACE expr RBRACE
    """
    p[0] = ast.FuncDeclarationNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1], p[3], p[6], p[8])
def p_program(p):
    """
    program : class_list
    """
    p[0] = ast.ProgramNode(p.lineno(1), find_column(p.lexer.lexdata, p.lexpos(1)), p[1])
    pass