也许以前有人问过这个,但是我真的不知道要搜索什么。假设我想使用一些字符串来构建解析器。
我有a OR b
,b OR C
之类的字符串,也有a OR (b AND c)
之类的字符串。现在,嵌套的括号对我造成了麻烦,而且我不知道如何构造适当的p_*
函数。允许递归吗?如果可以,怎么办?
import ply.lex as lex
import ply.yacc as yacc
# List of token names. This is always required
tokens = (
'VARIABLE',
'OR',
'AND',
'PAR_OPEN',
'PAR_CLOSE',
)
# Regular expression rules for simple tokens
t_ignore = ' \t'
t_VARIABLE = r'\b[a-z]+\b'
t_OR = r'\bOR\b'
t_AND = r'\bAND\b'
t_PAR_OPEN = r'\('
t_PAR_CLOSE = r'\)'
def t_error(t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
# Build the lexer
lexer = lex.lex()
def p_term(p):
'''term : VARIABLE OR VARIABLE
| VARIABLE AND VARIABLE
| PAR_OPEN VARIABLE AND VARIABLE PAR_CLOSE'''
if p[2] == 'AND':
p[0] = "".join([p[1], p[3]])
for idx, val in enumerate(p):
print(idx, val)
def p_error(p):
print("Syntax error in input!")
print(p)
parser = yacc.yacc()
res = parser.parse("(a AND b)")
print(res)
我也想用例如res = parser.parse("a OR (b AND c)")
,但无济于事。
答案 0 :(得分:1)
表达式中的括号很常见。我将首先为您介绍the PLY documentation的第5部分,该部分提供了嵌套表达式解析的示例。是的,递归就是答案。
有几个短语用来表示“表达式的最小元素”。您可能会看到“ atom”或“ term”(“ terminal”的缩写)或“ primary-expression”。
在处理带括号的子表达式时,通常采用这种方法。编写一个语法规则以统一各种低级内容(例如,文字数字和变量名称),并在该点添加子表达式。
在此示例中,从PLY文档中,expression
是最高级别的内容,并支持加法和减法。下一层是term
,它支持乘法和除法。最低级别的是factor
,它不支持任何操作,但是将NUMBER
和括号子表达式统一起来。一个因素可能是7
,但也可能是(7 + 2 * 3)
。
expression : expression + term
| expression - term
| term
term : term * factor
| term / factor
| factor
factor : NUMBER
| ( expression )