Палец вверх -2
Перевод
Перевод

проблемы при реализации крошечного парсера языка в python

я надеялся, что кто-нибудь сможет мне помочь в реализации крошечного парсера языка. я пытался реализовать грамматику крошечного языка (фото прилагается) грамматика крошечного языка , но у меня есть некоторые проблемы с некоторыми функциями; которые просты: exp, exp, factor, term. эти функции я реализовал некоторый код в нем на основе грамматики, но он продолжает выводить ошибки вывода ошибки. вот код синтаксического анализатора, я поместил его в список, чтобы я мог контролировать элементы внутри него

import scanner3


def program(l):
    if len(l) > 1:
        if l[len(l) - 1].value is ";":
            print("ERROR.. semi colon at last line")
            return False

        return stmt_seq(l)

    else:
        print("minimum num of expressions is not met")
        return False


def stmt_seq(l):
    if stmt(l):
        if l[0].value is ";":
            l.remove(l[0])
            return stmt(l)
    else:
        print("hiiio")
        return False


def stmt(l):
    if if_stmt(l):
        print("hi1")
        return True
    elif repeat_stmt(l):
        print("hi2")
        return True
    elif assign_stmt(l):
        print("hi3")
        return True
    elif read_stmt(l):
        print("hi4")
        return True
    elif write_stmt(l):
        print("hi5")
        return True
    else:
        return False


def if_stmt(l):
    if l[0].value == "IF":
        l.remove(l[0])
        exp(l)
        if l[0].value == "THEN":
            l.remove(l[0])
            stmt_seq(l)
            if l[0].value is "END":
                l.remove(l[0])
                return True
            elif l[0].value is "ELSE":
                l.remove(l[0])
                stmt_seq(l)
                if l[0].value is "END":
                    l.remove(l[0])
                    return True
                else:
                    return False
        else:
            return False
    else:
        return False


def repeat_stmt(l):
    if l[0].value is not "REPEAT":
        return False
    else:
        l.remove(l[0])
        return True


def assign_stmt(l):
    if l[0].type == 'var' and len(l) > 1:
        if l[1].value == ":=":
            l.remove(l[0])
            l.remove(l[1])
            # return exp(l)
            return True

        return False


def read_stmt(l):
    if l[0].value == 'READ' and len(l) > 1:
        if l[1].type is "var":
            l.remove(l[0])
            l.remove(l[1])
            return True
        else:
            print("ERROR is in read in line " + str(l[0].line_no))
            return False

    else:
        return False


def write_stmt(l):
    if l[0].value == "WRITE":
        l.remove(l[0])
        # return exp(l)
        return True
    return False


def exp(l):
    # for wa7da in list(tokens.queue):
    #     print(wa7da.value, ", ", wa7da.type, "  in line ", wa7da.line_no)
    # print("________")
    if simple_exp(l):
        if comparison_op(l)and simple_exp(l):
            return True
    return False


def comparison_op(l):
    print("compaaaaare "+l[0].value)
    if l[0].value is "<" or l[0].value is ">" or l[0].value is "=":
        l.remove(l[0])
        return True
    else:
        print("ERROR is in comparison in line " + str(l[0].line_no))
        return False


def simple_exp(l):
    if l[0].value is "+" or l[0].value is "-":
        return term(1)
        return True
    else:
        return False

    # return term(l)
    # if term(l):
    #     if add_op(l):
    #         return term(l)
    #     return True
    # else:
    #     return False


def add_op(l):
    if l[0].value is "+" or l[0].value is "-":
        l.remove(l[0])
        return True
    else:
        print("ERROR is in add in line "+str(l[0].line_no))
        return False


def term(l):
    if l[0].value is "*" or l[0].value is "/":
        mul_op(1)
        return True
    return factor(l)
    # if factor(l):
    #     if mul_op(l):
    #         return factor(l)
    #     return True
    # else:
    #     return False


def mul_op(l):
    if l[0].value is "*" or l[0].value is "/":
        l.remove(l[0])
        return True
    else:
        print("ERROR is in mul in line "+str(l[0].line_no))
        return False


def factor(l):
    print(l[0].value)
    if l[0].value == "(":
        l.remove(l[0])
        exp(l)
        if l[0].value == ")":
            l.remove(l[0])
            return True

    elif l[0].type == "num":
        l.remove(l[0])
        return True
    elif l[0].type == "var":
        l.remove(l[0])
        return True
    else:
        print("ERROr is in factor in line "+str(l[0].line_no))
        return False


# #####main
tokens = scanner3.tagheez("res.txt").tokenz
for wa7da in tokens:
    print(wa7da.value, ", ", wa7da.type, "  in line ", wa7da.line_no)

print(program(tokens))
python parsing
задан Mariam Mohie Sleem 13 мая 2018 г., 0:44:09
источник

1 ответ

Решение 0
Перевод
Перевод

Ваша проблема в том, что в вашем коде есть несколько мест, где вы передаете число 1 вместо списка токенов l . Например:

def simple_exp(l):
    if l[0].value is "+" or l[0].value is "-":
        return term(1)

… а также:

def term(l):
    if l[0].value is "*" or l[0].value is "/":
        mul_op(1)

Все ваши функции ожидают получить список токенов как l , а не как число. Когда в первый раз один из них попытается ввести значение l[0].value или подобное, когда l будет номером 1 , он вызовет именно то исключение, о котором вы спрашиваете:

TypeError: 'int' object has no attribute '__getitem__'

Я не знаю, какая из этих опечаток является причиной вашей конкретной проблемы, но это не имеет значения; вам, очевидно, нужно исправить все из них.

И, как предположил Рори Даултон в первом комментарии, именно поэтому l - ужасное имя переменной. Если бы ваша переменная называлась tokens или lst или почти что-нибудь еще, вы могли бы сразу сказать, что 1 была ошибкой, но, поскольку это l , которое выглядит почти идентично 1 , вы не сможете увидеть проблему даже после того, как на нее указывают ,

Конечно, у вас также есть другие ошибки в вашем коде (например, l.remove(l[0]) за которым следует l.remove(l[1]) , удалит первый и третий элементы, а не первые два, и, на на более глубоком уровне ваш term вообще не проверяет термин, он просто проверяет mul_op ), но именно он блокирует вас.

ответ дан abarnert 13 мая 2018 г., 1:08:57
источник