首页 > 解决方案 > PLY yacc 解析器:如何为解析矩阵创建递归规则?

问题描述

我正在尝试解析以这种方式编写的矩阵:[[1,2];[3,2];[3,4]]

因此,矩阵语法的形式为:[[A0,0, A0,1, ...]; [A1,0, A1,1, ...];...]

分号用于分隔矩阵的行,因此它不会出现在只有一行的矩阵的分配中。另一方面,逗号用于分隔矩阵的列,另一方面,它不会出现在只有一列的矩阵的分配中。

现在我的问题是:如何解析可变大小的矩阵?我想在 ply yacc 中使用递归规则,但是如何?每一次尝试都会导致无限递归。

这是我得到的错误:

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

(这只是我第一次尝试了解如何在 yacc 中编写递归,甚至不是我真正问题的答案)

这是我的词法分析器

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() 

标签: parsingmatrixyaccply

解决方案


经过多次尝试,我得到了这个:

    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 的支持 :)


推荐阅读