python样式元组的CFG
在读了无数遍Stackoverflow上关于“如何用正则表达式解析HTML”的问题后,我再次对语法感兴趣,抓起了我的大学脚本,几分钟后我想知道我是如何通过考试的 作为一个简单的练习(我希望它是“简单的”),我尝试编写一个生成有效python元组的CFG(为了简单起见,只使用标识符python样式元组的CFG,python,tuples,grammar,context-free-grammar,Python,Tuples,Grammar,Context Free Grammar,在读了无数遍Stackoverflow上关于“如何用正则表达式解析HTML”的问题后,我再次对语法感兴趣,抓起了我的大学脚本,几分钟后我想知道我是如何通过考试的 作为一个简单的练习(我希望它是“简单的”),我尝试编写一个生成有效python元组的CFG(为了简单起见,只使用标识符a、b和c)。过了一段时间,我终于想到了这个: G = ( {Tuple, TupleItem, Id}, {“a”, “b”, “c”, “,”, “(“, “)”}, P, Tuple) 作为p: Tuple →
a
、b
和c
)。过了一段时间,我终于想到了这个:
G = ( {Tuple, TupleItem, Id}, {“a”, “b”, “c”, “,”, “(“, “)”}, P, Tuple)
作为p:
Tuple → “(“ TupleItem “)”
Tuple → “(“ TupleItem Id “)”
Tuple → “(“ TupleItem Tuple “)”
TupleItem → TupleItem TupleItem
TupleItem → Id “,”
TupleItem → Tuple “,”
Id → “a”
Id → “b”
Id → “c”
这种语法应该产生例如(a,)
,(a,b)
,(a,b,)
,((a,),)
,((a,b,),(a,)
,但不是(,a)
,,,(a,b)
,等等。我不想产生像()(),,,)或()这样多余的括号。实际上,有时是可选的(当有多个项目时)有时是强制性的(当只有一个项目时)尾随逗号几乎要了我的命
此语法是否生成所有有效的python元组(仅使用a
、b
和c
)
该语法是否生成不是有效python元组的字符串
这语法正确吗?(我不确定循环标准)
为什么我的语法这么长?如何减少生产规则的数量?(不能使用语法上类似于糖的管道,因为这些管道只在一行上放几个规则。)
提前感谢您的评论和回答。在没有实际参考Python语法的情况下,我非常确定您的语法会生成除一个(()
,空元组)之外的所有有效Python元组,并且不会生成任何非Python元组的内容。所以在这个程度上,它是好的
但是,它对解析没有多大用处,因为
TupleItem → TupleItem TupleItem
是指数级的模糊。(Dicho sea de paso,TupleItem不是这个非终端的描述性名称,它实际上是一个列表。)歧义语法是“适当的”,因为它们遵守上下文无关语法的所有规则,但无歧义语法通常更好
很容易修复:
Tuple → “(“ “)”
Tuple → “(“ ItemList “,” “)”
Tuple → “(“ ItemList “,” Item “)”
ItemList → Item
ItemList → ItemList “,” Item
Item → Id
Item → Tuple
(我省略了Id
productions;在实际语法中,Id
将是一个终端,但没有什么区别。)
最后,为什么这个语法“这么长”?(七部作品真的“这么长”吗?我想这取决于你的标准。)
答案很简单,CFG就是这样。您可以添加语法糖来生成右侧正则表达式(不仅是交替,还包括Kleene star及其同伴):
在这里,我使用了有用的插值运算符/
,它很少在学术课上教授,因此很少实现:
a//b=defa(ba)*
无论上面的内容是否更容易阅读,我留给读者。它类似于EBNF(Extended Backus Naur Form),通常用于语法解释,特别是在RFC中。(EBNF是为数不多的带有插值运算符的形式主义之一,尽管它的编写方式不如我的明确。)
无论如何,除此之外,我不相信你的语法能被删减
Tuple → “(“ [ ItemList “,” Item? ]? “)”
ItemList → Item // “,”
Item → Id | Tuple