0

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

IdentList → IdentList ,标识符 ArrayBrackets*

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

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

我有变量 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 闭包?

[编辑]

在仔细检查了这个问题之后,我看到@GrijeshChauhan 说,给定一个非终结符 e。e 的 Kleene 闭包,即 e* 将由以下产生式给出

S → eS | ^

whereeS是 with 的连接,e并且S^null/empty/epsilon。我的问题是, e 必须是终端吗?我可以不应用相同的逻辑为非终结符生成新的产品吗,例如:

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

1 回答 1

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]

LPAREN, RPAREN, ID,COMMA和的标记在这里没有显示并且应该是显而易见的...STRINGNUMBER的产生规则columnname无关紧要。

它基本上说 aList是 acolumnname后跟IN ( listbody )。Alistbody可以是单个值,也可以是一个值后跟多个用 分隔的值COMMA

这不允许空列表 like ,但您可以为likemycolumn in []添加替代生产规则以涵盖该情况。listcolumnname IN LPAREN RPAREN

希望这可以帮助。

于 2013-09-11T18:34:10.967 回答