Ошибка генерации AST (абстрактного синтаксического дерева) из-за грамматики BNF - PullRequest
1 голос
/ 06 апреля 2019

Итак, у меня есть грамматика:

    termo : PESQ termo termo PDIR

     | PESQ LAMBDA listav PONTO termo PDIR

     | VAR

    listav : VAR listav
      | VAR

Где termo = термин, PESQ = (, PDIR =), LAMBDA =!, PONTO =., VAR = [a-z], listav = список переменных.

Проблема в том, что, когда я пытаюсь сгенерировать абстрактное синтаксическое дерево для ввода некоторого выражения, скажем,! X.x, оно выдает мне ошибку: yacc: Синтаксическая ошибка в строке 1, токен = LAMBDA.

Я думаю, что проблема здесь в том, как я определяю свою грамматику (и вставляю нетерминалы в массив стека. Я оставлю свой код внизу. Возможно, речь идет о stack.append (p [x ])? Я не совсем уверен, какие нетерминалы я должен добавить в массив, потому что у меня более одного производства.

import sys
from tree import *

stack = []

tokens = [

    'LAMBDA',
    'PONTO',
    'VAR',
    'PDIR',
    'PESQ'
]


t_LAMBDA = r'\!'
t_PONTO = r'\.'
t_VAR = r'[a-z]'
t_PDIR = r'\)'
t_PESQ = r'\('

t_ignore = r' '


def t_error(t):
    print("Illegal Character!")
    t.lexer.skip(1)

import ply.lex as lex
lexer = lex.lex()

def p_termo(p):
    '''
    termo : PESQ termo termo PDIR
          | PESQ LAMBDA listav PONTO termo PDIR
          | VAR
    '''

    if len(p) == 7:
        stack.append(p[2])
        stack.append(p[3])
        stack.append(p[4])
    elif len(p) == 2:
        stack.append(p[1])


def p_listav(p):
    '''
    listav : VAR listav
           | VAR
    '''

    if len(p) == 3:
        stack.append(p[1])
    elif len(p) == 2:
        stack.append(p[1])

import ply.yacc as yacc
parser = yacc.yacc()




while True:
    try:
        print('')
        print('Input: ')
        inp = input('')
    except EOFError:
        break
    stack = []
    p = parser.parse(inp)


    z = 0
    while z < len(stack):
        if z == 0:
            if len(stack) == 1:
                a = Tree(stack[z])
                z += 1
            elif stack[z+1] != '!':
                auxL = Tree(stack[z + 1])
                auxR = Tree(stack[z])
                a = Tree('@', auxL, auxR)
                z += 2
            else:
                a = Tree(stack[z])
                z += 1

        else:
            if stack[z] == '!' and stack[z-2] == '.' and z > 1:
                auxR = Tree(stack[z + 1])
                b = Tree('!', m, auxR)
                a = Tree('@', a, b)
                z += 3
            elif stack[z] == '!':
                auxL = Tree(stack[z+1])
                a = Tree('!', auxL, a)
                z += 3
            elif stack[z] != '!' and stack[z-1] == '.' and z != len(stack) - 1:
                if stack[z+1] == '!':
                    m = Tree(stack[z])
                    z += 1
                else:
                    auxR = Tree(stack[z])
                    a = Tree('@', a, auxR)
                    z += 1
            else:
                auxR = Tree(stack[z])
                a = Tree('@', a, auxR)
                z += 1



        arv = Tree.print_tree(a)
        print('###########################')
        print('Arvore: ')
        print(arv)
        print('###########################')
...