parsing - 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()
解决方案
经过多次尝试,我得到了这个:
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 的支持 :)
推荐阅读
- perl - Perl 中的 HASH 值本质上是内存位置吗?
- java - Listview 显示不同类型的行
- git - 如何从.git 中完全删除错误暂存的大文件?
- azure - 如何将事件从 Linux 机器发送到 Azure IoT Edge Hub
- php - 如何使多个语句循环合二为一?(性能问题/PHP)
- c# - 减少元组列表中元组搜索的 foreach 循环
- asp.net-web-api2 - 使用 SimpleInjector 实现 MassTransit IoC
- java - Java - 内部 ArrayList 循环未执行预期功能
- mysql - mysql st_within 不使用虚拟列
- wagtail - 如何列出主页的直接子级?