我正在使用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 | ^
其中eS
是e
与S
和^
的串联,为空/空/ epsilon。我的问题是,e必须是终端吗?
我是否可以不应用相同的逻辑来为非终结符号生成新的作品,例如:
def p_ArrayBracketsSTAR(t):
'''ArrayBracketsSTAR : ArrayBracketsSTAR ArrayBrackets | '''
答案 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]
此处未显示LPAREN
,RPAREN
,ID
,COMMA
,...STRING
和NUMBER
的令牌,这些令牌应该是显而易见的。 columnname
的制作规则无关紧要。
它基本上表示List
是columnname
后跟IN ( listbody )
。 listbody
是单个值或值后跟更多以COMMA
分隔的值。
这不允许使用mycolumn in []
这样的空列表,但您可以为list
添加替代生产规则,例如columnname IN LPAREN RPAREN
来涵盖该案例。
希望这有帮助。