我想知道我是否可以使用CFG或PEG启发式语法表示CLI提示符;例如,自动生成设置向导或调查。为了实现这一点,解析器必须提示用户输入下一个已输入的令牌。示例:
customer_info -> "My name is " name_expression " and I'm " %age " years old."
name_expression -> %name %name
| %name
name_expression
允许您输入名字和姓氏,或仅输入一个名字。字符串常量将由提示自动填充。该规范将为假设的用户编写以下示例体验:
My name is (enter %name):
>> john
My name is john (1 for "%lastname", 2 for " and I'm "):
>> 2
My name is john and I'm (enter a number):
>> 39
My name is john and I'm [39] years old.
Prompt complete, exiting.
我已经阅读了一些有关“逆解析器”的内容,其思想是在交互式对话期间,您所有潜在的响应都将在对话的每个步骤中进行布局。(请考虑使用RPG风格的视频游戏对话NPC)。在线上有关此技术的信息似乎很少,我不确定它能否完全满足我的要求。
我已经研究了Earley解析器,预测性LL解析器以及其他一些解析器,但是学习每个候选者只是为了找出是否适合这种情况似乎是不合理的。我的问题是,在输入句子不完整的情况下,哪种解析技术最能使我提示用户输入有效令牌的列表?
尽管我对递归下降解析和使用各种解析器生成器很满意,但我只研究了大约一年的内容,所以请原谅我的无知。
谢谢。
答案 0 :(得分:1)
只要可以使用该方案解析语言,那么任何不超过一个预告令牌的从左到右解析方案都可以正常工作。表驱动的实现可能更易于使用,前提是可以访问并记录解析表(不幸的是,大多数解析器生成器都没有这种情况),但是您可以使用任何具有“推送”界面和可复制状态的黑盒解析器,通过简单地循环遍历所有可能的令牌类型并记录哪些不会产生错误。
使用LL(1)语法比使用LR(1)语法更容易预测逻辑,因为LL解析器状态始终是唯一项。 LR解析器状态通常是多个项目的并集,因此如何描述当前的解析上下文可能并不十分明显。另一方面,LR解析器可以处理更大的语法集。
答案 1 :(得分:1)
LRSTAR中已经存在此技术,我认为它已内置于ANTLR和Bison / Yacc生成的解析器中。输入中遇到错误时将激活它。然后,它列出了所有预期的有效令牌。
有人将其称为自动完成或句子完成。它很少用于您要询问的目的。但是,使用修改后的解析器是可行的。解析器必须生成问题“我的名字是”,然后从用户读取预期的令牌“
这实际上是解析器可以做什么的简化。对这种简单的事情使用LR解析器是过大的。
语法可能看起来像这样:
Goal -> Questions <eof>
Questions -> FirstName LastName Street City State Zipcode Age
FirstName -> first name <first_name>
LastName -> last name <last_name>
Street -> street <street>
City -> city <city>
State -> state <state>
Zipcode -> zipcode <zipcode>
Age -> age <age>
这是自动创建问卷的有效方法。解析器将生成不在尖括号中的单词,并要求用户输入变量信息。或者只是将尖括号中的单词放在语法中,以避免重复,并向用户询问
最好和最可靠的方法是创建Canonical LR(1)解析器。 这种解析器在每个状态下都具有所有预期的令牌。无需通过默认缩减来查看其他状态。只要语法不是很大,就应该尝试CLR(1)解析器。
LRSTAR可以生成CLR(1)解析器,该解析器已经内置了列出所需令牌的代码。