Пример #1
0
def multiplier():
    if token.table == TABLE_ID:
        return NodeAST(NodeAST.ID, token_line, token.index)

    if token.table == TABLE_NUMBER:
        return NodeAST(NodeAST.NUMBER, token_line, token.index)

    if token.value == token.TRUE or token.value == token.FALSE:
        return NodeAST(NodeAST.BOOL, token_line, token.index)

    if token.value == token.NOT:
        next_token()
        m = multiplier()
        if not m:
            return None
        return NodeAST(
            NodeAST.EXPR, token_line,
            NodeAST(NodeAST.OP, token_line, TABLE_KEYWORD, token.NOT), m, None)

    if token.value == token.LPAR:
        next_token()
        e = expr()
        if e and token.value == token.RPAR:
            return e

    return None
Пример #2
0
def read_stmt():
    args = []
    next_token()
    if token.value == token.LPAR:
        next_token()
        if token.table != TABLE_ID:
            print('Error [line ' + str(token_line) +
                  ']: expected variable after \'(\'')
            return None
        args.append(NodeAST(NodeAST.ID, token_line, token.index))
        next_token()
        while token.value == token.COMMA:
            next_token()
            if token.table != TABLE_ID:
                print('Error [line ' + str(token_line) +
                      ']: expected variable after \'(\'')
                return None
            args.append(NodeAST(NodeAST.ID, token_line, token.index))
            next_token()
        if token.value == token.RPAR:
            next_token()
            return NodeAST(NodeAST.READ, token_line, *args)
    print('Error [line ' + str(token_line) +
          ']: expected \'(\' after \'read\'')
    return None
Пример #3
0
def if_stmt():
    next_token()
    cond = expr()
    if cond:
        if token.value == token.THEN:
            next_token()
            lhs = stmt()
            if lhs:
                if token.value == token.ELSE:
                    next_token()
                    rhs = stmt()
                    if rhs:
                        return NodeAST(NodeAST.IF, token_line, cond, lhs, rhs)
                    print('Error [line ' + str(token_line) +
                          ']: expected statement after \'else\'')
                    return None
                return NodeAST(NodeAST.IF, token_line, cond, lhs, None)
            print('Error [line ' + str(token_line) +
                  ']: expected statement after \'then\'')
            return None
        print('Error [line ' + str(token_line) +
              ']: expected \'then\' in \'if\' statement')
        return None
    print('Error [line ' + str(token_line) +
          ']: expected expression after \'if\'')
    return None
Пример #4
0
def ass_stmt():
    lhs = NodeAST(NodeAST.ID, token_line, token.index)
    next_token()
    if token.value == token.ASS:
        next_token()
        rhs = expr()
        if rhs:
            return NodeAST(NodeAST.ASS, token_line, lhs, rhs)
        print('Error [line ' + str(token_line) +
              ']: expected expression after \'ass\'')
        return None
    print('Error [line ' + str(token_line) + ']: expected \'ass\'')
    return None
Пример #5
0
def write_stmt():
    next_token()
    args = []
    if token.value == token.LPAR:
        next_token()
        args.append(expr())
        if not args[-1]:
            print('Error [line ' + str(token_line) +
                  ']: expected expression after \'(\'')
            return None

        while token.value == token.COMMA:
            next_token()
            args.append(expr())
            if not args[-1]:
                print('Error [line ' + str(token_line) +
                      ']: expected expression')
                return None

        if token.table == TABLE_ID:
            print('Error [line ' + str(token_line) + ']: expected \',\'')
            return None
        elif token.value == token.RPAR:
            next_token()
            return NodeAST(NodeAST.WRITE, token_line, *args)
        else:
            print('Error [line ' + str(token_line) + ']: expected \')')
            return None
    print('Error [line ' + str(token_line) + ']: expected \'(\'')
    return None
Пример #6
0
def for_stmt():
    next_token()
    begin = ass_stmt()
    if begin:
        if token.value == token.TO:
            next_token()
            end = expr()
            if end:
                if token.value == token.DO:
                    next_token()
                    stmts = stmt()
                    if stmts:
                        return NodeAST(NodeAST.FOR, token_line, begin, end,
                                       stmts)
                    print('Error [line ' + str(token_line) +
                          ']: expected statement after \'do\'')
                    return None
                print('Error [line ' + str(token_line) +
                      ']: expected \'do\' in \'for\' statement')
                return None
            print('Error [line ' + str(token_line) +
                  ']: expected expression after \'to\'')
            return None
        print('Error [line ' + str(token_line) +
              ']: expected \'to\' in \'for\' statement')
        return None
    print('Error [line ' + str(token_line) +
          ']: expected statement after \'for\'')
    return None
Пример #7
0
def parse():
    global errors

    if token.value != token.PROGRAM:
        print('Error [line ' + str(token_line) + ']: expected \'program\'')
        return None
    next_token()

    if token.value != token.VAR:
        print('Error [line ' + str(token_line) + ']: expected \'var\'')
        return None
    next_token()

    decls = []
    decls.append(declaration())
    while decls[-1]:
        if token.value == token.BEGIN:
            break
        decls.append(declaration())
    if not decls:
        print('Error [line ' + str(token_line) + ']: expected declarations')
        return None

    next_token()
    stmts = []
    result = stmt()
    while True:
        if not result:
            if token.value == token.END or not token.value:
                break
            errors = True
            while token.value != token.SEMICOLON:
                next_token()
                if not token.value:
                    break
            next_token()
            if token.value == token.END or not token.value:
                break
            result = stmt()

        stmts.append(result)
        if token.value != token.SEMICOLON:
            print('Error [line ' + str(token_line) + ']: ' +
                  'expected \';\' after statement')
            return None
        next_token()
        result = stmt()

    if token.value != token.END:
        print('Error [line ' + str(token_line) + ']: ' + 'expected \'end\'')
        return None
    next_token()

    if token.value != token.DOT:
        print('Error [line ' + str(token_line) + ']: ' +
              'expected \'.\' after \'end\'')
        return None

    return NodeAST(NodeAST.PROGRAM, token_line, decls, stmts)
Пример #8
0
def operand():
    lhs = summand()
    if lhs:
        op = sumop()
        if op:
            next_token()
            rhs = operand()
            if rhs:
                return NodeAST(NodeAST.EXPR, token_line, op, lhs, rhs)
            return None
        return lhs
    return None
Пример #9
0
def summand():
    lhs = multiplier()
    if lhs:
        next_token()
        op = mulop()
        if op:
            next_token()
            rhs = summand()
            if rhs:
                return NodeAST(NodeAST.EXPR, token_line, op, lhs, rhs)
            return None
        return lhs
    return None
Пример #10
0
def while_stmt():
    next_token()
    cond = expr()
    if cond:
        if token.value == token.DO:
            next_token()
            stmts = stmt()
            if stmts:
                return NodeAST(NodeAST.WHILE, token_line, cond, stmts)
            print('Error [line ' + str(token_line) +
                  ']: expected statement after \'do\'')
            return None
        print('Error [line ' + str(token_line) +
              ']: expected \'do\' in \'while\' statement')
        return None
    print('Error [line ' + str(token_line) +
          ']: expected expression after \'while\'')
    return None
Пример #11
0
def stmt():
    args = []
    node = None
    if token.table == TABLE_ID:
        node = ass_stmt()
    elif token.value == token.IF:
        node = if_stmt()
    elif token.value == token.WRITE:
        node = write_stmt()
    elif token.value == token.READ:
        node = read_stmt()
    elif token.value == token.FOR:
        node = for_stmt()
    elif token.value == token.WHILE:
        node = while_stmt()
    if node:
        if token.value == token.COLON:
            args.append(node)
            while token.value == token.COLON:
                next_token()
                if token.table == TABLE_ID:
                    node = ass_stmt()
                elif token.value == token.IF:
                    node = if_stmt()
                elif token.value == token.WRITE:
                    node = write_stmt()
                elif token.value == token.READ:
                    node = read_stmt()
                elif token.value == token.FOR:
                    node = for_stmt()
                elif token.value == token.WHILE:
                    node = while_stmt()
                if not node:
                    return None
                args.append(node)
            return NodeAST(NodeAST.STMT_SEQ, token_line, *args)
        return node
    return None
Пример #12
0
def relop():
    if (token.value == token.NOTEQUAL) or (token.value == token.EQUAL) or \
       (token.value == token.LESS) or (token.value == token.GREAT) or     \
       (token.value == token.LESSEQUAL) or (token.value == token.GREATEQUAL):
        return NodeAST(NodeAST.OP, token_line, TABLE_SEPARATOR, token.value)
    return None
Пример #13
0
def sumop():
    if token.value == token.PLUS or token.value == token.MINUS:
        return NodeAST(NodeAST.OP, token_line, TABLE_SEPARATOR, token.value)
    if token.value == token.OR:
        return NodeAST(NodeAST.OP, token_line, TABLE_KEYWORD, token.value)
    return None
Пример #14
0
def mulop():
    if token.value == token.MUL or token.value == token.DIV:
        return NodeAST(NodeAST.OP, token_line, TABLE_SEPARATOR, token.value)
    if token.value == token.AND:
        return NodeAST(NodeAST.OP, token_line, TABLE_KEYWORD, token.value)
    return None