如何在制作中写kleene闭包?

时间:2013-09-11 18:04:41

标签: parsing python-2.7 ply

我正在使用PLY编写解析器。解析器所用的语言称为s-lang,在语言的语法中我有以下产生:

IdentList→IdentList,标识符ArrayBrackets *

我已经为ArrayBrackets编写了产品。我尝试将上述作品写成

def p_IdentList(t):
          '''IdentList : IdentList COMMA ID ArrayBrackets*'''

我有vars COMMA和ID的正则表达式。问题是当我加入星星时,我收到以下错误:

ERROR: main.py:115: Illegal name 'ArrayBrackets*' in rule 'IdentList'
Traceback (most recent call last):
  File "main.py", line 175, in <module>

我尝试过这个明星,但它没有帮助 - 我怎么能在制作中写下Kleene封口?

[修改

仔细检查this question之后,我看到@GrijeshChauhan说,给定一个非终结者e。 e的Kleene闭包,即e *将由以下生产给出

  

S→eS | ^

其中eSeS^的串联,为空/空/ epsilon。我的问题是,e必须是终端吗? 我是否可以不应用相同的逻辑来为非终结符号生成新的作品,例如:

def p_ArrayBracketsSTAR(t):
'''ArrayBracketsSTAR : ArrayBracketsSTAR ArrayBrackets | '''

1 个答案:

答案 0 :(得分:1)

也许这会有所帮助:

def p_list(p):
    '''expression   : columnname IN LPAREN listbody RPAREN
    '''
    p[0] = Node('List', leaf=(p[1], tuple(p[4])))

def p_listbody(p):
    '''listbody     : value
                    | value COMMA listbody
    '''
    if len(p) == 2:
        p[0] = [p[1]]
    elif len(p) == 4:
        p[0] = [p[1]] + p[3]
    else:
        raise AssertionError(len(p))

def p_value(p):
    '''value        : SINGLEQUOTEDSTRING
                    | DOUBLEQUOTEDSTRING
                    | NUMBER
    '''
    p[0] = p[1]

此处未显示LPARENRPARENIDCOMMA...STRINGNUMBER的令牌,这些令牌应该是显而易见的。 columnname的制作规则无关紧要。

它基本上表示Listcolumnname后跟IN ( listbody )listbody是单个值或值后跟更多以COMMA分隔的值。

这不允许使用mycolumn in []这样的空列表,但您可以为list添加替代生产规则,例如columnname IN LPAREN RPAREN来涵盖该案例。

希望这有帮助。