层中的语法构造-允许递归吗?

时间:2019-01-19 19:20:53

标签: python grammar yacc lex

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

我有a OR bb 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)"),但无济于事。


附注:确实基于another one's question

1 个答案:

答案 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 )