以下语法的回溯递归下降解析器
Backtracking Recursive Descent Parser for the following grammar
我正在尝试弄清楚一些涉及解析表达式语法的细节,并且被困在以下问题上:
对于给定的语法:
a = b Z
b = Z Z | Z
(小写字母表示制作,大写字母表示终端)。
产生式 "a" 是否应该与字符串 "Z Z" 相匹配?
这是我看到上述语法被翻译成的伪代码,其中每个产生式都映射到一个输出两个值的函数。第一个指示解析是否成功。第二个表示解析后在流中的结果位置。
defn parse-a (i:Int) -> [True|False, Int] :
val [r1, i1] = parse-b(i)
if r1 : eat("Z", i1)
else : [false, i]
defn parse-b1 (i:Int) -> [True|False, Int] :
val [r1, i1] = eat("Z", i)
if r1 : eat("Z", i1)
else : [false, i]
defn parse-b2 (i:Int) -> [True|False, Int] :
eat("Z", i)
defn parse-b (i:Int) -> [True|False, Int] :
val [r1, i1] = parse-b1(i)
if r1 : [r1, i1]
else : parse-b2(i)
当尝试解析输入 "Z Z" 上的产生式 "a" 时,上述代码将失败。这是因为 "b" 的解析函数不正确。它会贪婪地消耗输入中的两个 Z 并成功,然后什么都不留给 a 来解析。这是解析表达式语法应该做的吗?福特论文中的伪代码似乎表明了这一点。
非常感谢。
-帕特里克
在 PEG 中,析取(替代)确实是有序的。 Ford的论文中,运算符写成/,称为"ordered choice",以区别于|析取运算符
]
这使得 PEG 从根本上不同于 CFG。特别是,给定 PEG 规则 a -> b Z
和 b -> Z Z / Z
,a
将不匹配 Z Z
.
感谢您的回复 Rici。
我更仔细地重新阅读了 Ford 的论文,它再次证实了你所说的。 PEG / 运算符都是有序的 和 贪婪的。所以上面提出的规则应该会失败。
-帕特里克
我正在尝试弄清楚一些涉及解析表达式语法的细节,并且被困在以下问题上:
对于给定的语法:
a = b Z
b = Z Z | Z
(小写字母表示制作,大写字母表示终端)。 产生式 "a" 是否应该与字符串 "Z Z" 相匹配?
这是我看到上述语法被翻译成的伪代码,其中每个产生式都映射到一个输出两个值的函数。第一个指示解析是否成功。第二个表示解析后在流中的结果位置。
defn parse-a (i:Int) -> [True|False, Int] :
val [r1, i1] = parse-b(i)
if r1 : eat("Z", i1)
else : [false, i]
defn parse-b1 (i:Int) -> [True|False, Int] :
val [r1, i1] = eat("Z", i)
if r1 : eat("Z", i1)
else : [false, i]
defn parse-b2 (i:Int) -> [True|False, Int] :
eat("Z", i)
defn parse-b (i:Int) -> [True|False, Int] :
val [r1, i1] = parse-b1(i)
if r1 : [r1, i1]
else : parse-b2(i)
当尝试解析输入 "Z Z" 上的产生式 "a" 时,上述代码将失败。这是因为 "b" 的解析函数不正确。它会贪婪地消耗输入中的两个 Z 并成功,然后什么都不留给 a 来解析。这是解析表达式语法应该做的吗?福特论文中的伪代码似乎表明了这一点。
非常感谢。
-帕特里克
在 PEG 中,析取(替代)确实是有序的。 Ford的论文中,运算符写成/,称为"ordered choice",以区别于|析取运算符
]这使得 PEG 从根本上不同于 CFG。特别是,给定 PEG 规则 a -> b Z
和 b -> Z Z / Z
,a
将不匹配 Z Z
.
感谢您的回复 Rici。
我更仔细地重新阅读了 Ford 的论文,它再次证实了你所说的。 PEG / 运算符都是有序的 和 贪婪的。所以上面提出的规则应该会失败。
-帕特里克