我正在尝试编写一个PEGjs规则来转换
Return _a_b_c_.至
Return <>a_b_c</>.我的语法是
root = atoms:atom+
{ return atoms.join(''); }
atom = variable
/ normalText
variable = "_" first:variableSegment rest:$("_" variableSegment)* "_"
{ return '<>' + first + rest + '</>'; }
variableSegment = $[^\n_ ]+
normalText = $[^\n]这适用于
Return _a_b_c_ .和
Return _a_b_c_但是有些地方出了问题
Return _a_b_c_.举例说明。
我不太明白为什么这是打破,并希望得到一个解释,为什么它是这样的行为。(我甚至不一定需要解决这个问题;最大的问题是我对PEGjs语法的心智模型存在缺陷。)
发布于 2014-09-14 16:18:50
稍微调整一下语法,使其工作起来:
root = atoms:atom+
{ return atoms.join(''); }
atom = variable
/ normalText
variable = "_" first:$(variableSegment "_") rest:$(variableSegment "_")*
{ return '<>' + first + rest + '</>'; }
variableSegment = seg:$[^\n_ ]+
normalText = normal:$[^\n]我不知道为什么,确切地说。在这个例子中,解析器到达“。并将其匹配为"variableSegment",但在贪婪的“展望”中只回溯一步,决定它有一个“变量”,然后重新解析“。作为“正常人”。(请注意,这会获取尾随的_,如果不需要,可以通过操作中的黑客或类似的方法来剪短它;请参见下面的内容。)
在原始版本中,由于缺少尾下划线而失败后,解析器采取的下一个步骤就是返回前导下划线,选择“正常”解释。
我添加了一些带有console.log()调用的操作代码来跟踪解析器的行为。
编辑-我想交易就是这样。在最初的版本中,解析在表单的规则上失败了
expr1 expr2 expr3 .exprN
第一个子表达式是文字_。下一个是用于第一个变量段。第三个是变量表达式的序列,前面是_,最后一个是尾随的_。在对有问题的输入执行该规则时,最后一个表达式失败。然而,其他人都成功了,因此重新开始的唯一地方是在“原子”规则的替代点。
在修改后的版本中,解析器可以一步解压贪婪的*的操作。然后,它成功地匹配了第三个表达式,所以规则成功了。
因此,与原版本更接近的另一修订本也将起作用:
root = atoms:atom+
{ return atoms.join(''); }
atom = variable
/ normalText
variable = "_" first:variableSegment rest:$("_" variableSegment & "_")* "_"
{ return '<>' + first + rest + '</>'; }
variableSegment = $[^\n_ ]+
normalText = $[^\n]现在,当贪婪的*组无法向前看_时,它就会回溯。
发布于 2014-09-14 16:07:28
解析器将最后一个_.解释为variableSegment。如果将点排除在variableSegment RegExp之外,则代码将按预期工作。
https://stackoverflow.com/questions/25834957
复制相似问题