语法:
rule: (a b)? a c ;
输入:
a d
问题:给定输入的位置2哪条错误消息正确?
1. expected "b", "c".
2. expected "c".
P.S。
我写解析器,我有选择(困境)考虑到" b"期待或不参加。
#1错误(预期" b"," c")想要输入" a b"预期,但因为它是可选的,它可能没有预期但可能。
我不知道可能与预期相同吗?
哪个错误信息更好,更正确#1或#2?
感谢您的回答。
P.S。
在第一种情况下,我将testing
的标记定义为位置限制。
if(_inputPos > testing) {
_failure(_inputPos, _code[cp + {{OFFSET_RESULT}}]);
}
在可选表达式中移动限制:
OPTIONAL_EXPRESSION:
testing = _inputPos;
" b"表达式移动_inputPos
高于testing
pos并在_inputPos
添加失败。
在第二种情况下,我可以将testing
的标记定义为布尔标记。
if(!testing) {
_failure(_inputPos, _code[cp + {{OFFSET_RESULT}}]);
}
" b"在这种情况下,表达式不会因为测试而导致失败(内部表示可选表达式)。
您认为哪些更好更正确?
测试被定义为特定位置,如果表达式高于此位置(_inputPos>测试),则会增加失败(即使它在可选表达式中)。
测试定义为标志,如果此标志设置失败未考虑。执行可选表达式后,它会恢复(不重置!)以前的测试值(true或false)。
如果规则没有失败,也不会考虑故障。他们只报告解析是否失败。
P.S。
2014年1月6日的变更
提出这个问题是因为它涉及两个不同的问题。
第一个问题:
解析表达式语法(PEG)仅描述输入的三个原子项:
这种语法不提供词法预处理等操作,因此它不提供令牌这样的元素。
第二个问题:
什么是语法?如果两个语法接受相同的输入但产生不同的结果,那么这两个语法是否可以被认为相等?
假设我们有两个语法:
语法1
规则< - 类型?标识符
语法2
规则< - 类型标识符/标识符
他们都接受相同的输入,但产生(在PEG中)不同的结果。
语法1结果:
语法2结果:
Quetions:
我对这两个问题的回答都是否定的。不平等,不痛苦。
但你可能会问。 "但为什么会这样?"。
我可以回答你。 "因为这不是问题。这是一个功能"。
在PEG解析器表达式中,ALWAYS由这些部分组成。
ORDERED_CHOICE => SEQUENCE =>表达
这个解释是我对问题的答案"但为什么会这样呢?"。
另一个问题。
PEG解析器无法识别WHITESPACES,因为它没有令牌和令牌分隔符。
现在看看这个语法(简而言之):
程序< - WHITESPACE expr EOF
expr< - ruleX
ruleX< - ' X' WHITESPACE
WHITESPACE< ' '?
EOF< - !
所有PEG语法都以这种方式描述。
第一个WHITESPACE在开始时和其他WHITESPACE(经常)在规则结束时。
在这种情况下,在PEG中,必须假设WHITESPACE符合预期。
但WHITESPACE并不仅仅意味着空间。它可能更复杂[\ t \ n \ r]甚至评论。
但错误消息的主要规则如下。
如果无法显示所有预期的元素(或者不能显示所有预期元素中的至少一个),在这种情况下更正确,不显示任何内容。
更精确地要求显示"意外"错误消息。
你在PEG中如何展示预期的WHITESPACE?
如何开始评论?在一些语法中,它们也可能是WHITESPACE的一部分。
在这种情况下,可选的WHITESPACE将拒绝所有其他潜在的预期元素,因为无法正确显示错误消息中的WHITESPACE,因为WHITESPACE太复杂而无法显示。
这是好还是坏?
我认为这并不错,需要一些技巧来隐藏PEG解析器的这种性质。
在我的PEG解析器中,我不认为必须按预期处理可选(可选& zero_or_more)表达式的第一个位置的内部表达式。 但所有其他内部(除了在第一个位置)必须按预期处理。
示例1:
List<int list; // type? ident
Here "List<int" is a "type". But missing ">" is not at the first position in optional "type?".
此失败会考虑并报告为&#34;预期&#39;&gt;&#39;&#34;&#34; 这是因为我们不会跳过&#34;键入&#34;但进入&#34;键入&#34;经过真正的选择&#34; List&#34;我们将头寸从第一个移到下一个真实的&#34;预期&#34; (已经在测试位置之外)元素。
&#34;列表&#34;在&#34;测试&#34;位置。
如果内部表达(在可选表达式内)&#34;符合限制&#34;不继续在下一个位置,然后它不被假定为预期的输入。
从这个假设中提出了一个主要问题。
您必须考虑到我们正在讨论PEG解析器及其错误消息。
答案 0 :(得分:3)
这是你的语法:
这里清楚的是,在第一个a
之后,有两个可能的输入:b
或c
。您的错误消息不应该优先于另一个。
为无效输入生成错误消息的基本思路是找到失败的最远位置(如果您的语法d | (a b)? a c
,d
不会成为错误的一部分)并且确定哪些可能的输入可以让你前进并说出"expected '...' but got '...'"
。还有其他方法可以尝试恢复解析器并强制它继续。如果只有一个可能的预期令牌,让我们暂时将其插入令牌流中,并继续,就像它从那里一样。这将导致更好的错误检测,因为您可以找到超出解析器首次停止点的错误。