PLY ya cc парсер: как мне создать рекурсивное правило для разбора матриц? - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь разобрать матрицы, написанные таким образом: [[1,2];[3,2];[3,4]]

Итак, синтаксис матрицы имеет вид: [[A0,0, A0,1, ...]; [A1,0, A1,1, ...];...]

точка с запятой используется для разделения строк матрицы, поэтому она не присутствует в назначении матрицы, которая имеет только одну строку. С другой стороны, запятая используется для разделения столбцов матрицы, которые, с другой стороны, не будут присутствовать при назначении матрицы, имеющей только один столбец.

Теперь мой вопрос: как я могу разобрать матрицу с переменным размером? Я думаю, с рекурсивным правилом в ply ya cc, но как? Каждая попытка приводит к бесконечной рекурсии.

Вот ошибка, которую я получаю:

WARNING: Symbol 'primary' is unreachable
WARNING: Symbol 'expr' is unreachable
ERROR: Infinite recursion detected for symbol 'primary'
ERROR: Infinite recursion detected for symbol 'expr'

Когда я запускаю такой код:

def p_test(t):
'''primary : constant
           | LPAREN expr RPAREN'''
print('yo')
t[0] = 1


def p_expression_matrice(t):
'''expr : primary 
        | primary '+' primary'''
print('hey')
t[0] = 1

(это просто первая попытка понять, как написать recurion в ya cc, даже не ответ на мою реальную проблему)

Это мой лексер :

from global_variables import tokens
import ply.lex as lex

t_PLUS      = r'\+'
t_MINUS     = r'\-'
t_TIMES     = r'\*'
t_DIVIDE    = r'\/'
t_MODULO    = r'\%'
t_EQUALS    = r'\='
t_LPAREN    = r'\('
t_RPAREN    = r'\)'
t_LBRACK    = r'\['
t_RBRACK    = r'\]'
t_SEMICOLON = r'\;'
t_COMMA     = r'\,'
t_POWER     = r'\^'
t_QUESTION  = r'\?'
t_NAME      = r'[a-zA-Z]{2,}|[a-hj-zA-HJ-Z]'    # all words (only letters) except the word 'i' alone
t_COMMAND   = r'![\x00-\x7F]*'                  # all unicode characters after '!' 

def t_NUMBER(t):
    r'\d+(\.\d+)?'
    try:
        t.value = int(t.value)
    except:
        t.value = float(t.value)
    return t

def t_IMAGINE(t):
    r'i'
    t.value = 1j
    return t

t_ignore = " \t"

def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)

lexer = lex.lex() 

1 Ответ

0 голосов
/ 26 февраля 2020

После нескольких попыток, я получил это:

    def p_test3(t):
        '''expression : expression SEMICOLON expression'''
        t[0] = []
        t[0].append(t[1])
        t[0].append(t[3])

    def p_test2(t):
        '''expression : LBRACK expression RBRACK'''
        t[0] = t[2]


    def p_test(t):
        '''expression : expression COMMA NUMBER'''
        t[0] = [] 
        try:
            for i in t[1]:
                t[0].append(i)
        except:
            t[0].append(t[1])
        t[0].append(t[3])

Что позволяет мне разобрать это: [[1,2,3,4,5];[5,4,3,2,1]] чтобы получить это: [[1, 2, 3, 4, 5], [5, 4, 3, 2, 1]] хранится в массиве массива. Следующий шаг, я буду хранить многие из них в диктовке, и я буду продолжать, спасибо за поддержку @rici:)

...