ply 中的语法结构 - 允许递归吗?
Grammar construction in ply - recursion allowed?
以前可能有人问过这个问题,但我真的不知道要搜索什么。假设我有一些字符串,我想用它来构建解析器。
我有 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)")
但无济于事。
P.S.: 这个是根据, 真的.
表达式中的圆括号很常见。我将首先向您介绍 the PLY documentation 的第 5 部分,其中提供了嵌套表达式解析的示例。是的,递归就是答案。
有几个短语用来表示 "smallest element of an expression." 您可能会看到 "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 )
以前可能有人问过这个问题,但我真的不知道要搜索什么。假设我有一些字符串,我想用它来构建解析器。
我有 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)")
但无济于事。
P.S.: 这个是根据
表达式中的圆括号很常见。我将首先向您介绍 the PLY documentation 的第 5 部分,其中提供了嵌套表达式解析的示例。是的,递归就是答案。
有几个短语用来表示 "smallest element of an expression." 您可能会看到 "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 )