ply 中的语法结构 - 允许递归吗?

Grammar construction in ply - recursion allowed?

以前可能有人问过这个问题,但我真的不知道要搜索什么。假设我有一些字符串,我想用它来构建解析器。

我有 a OR bb OR Ca 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 )