2

作为参考,这是我的代码:http ://hpaste.org/86949

我正在尝试解析以下表达式:if (a[1].b[2].c.d[999].e[1+1].f > 3) { }. 播放的方法是varExpr,它解析变量成员链。

语境

在我正在解析的语言中,点可以指定访问成员变量。由于成员变量可以是另一个对象,因此可以生成链,即:a.b.c或本质上(a.b).c。不要假设这些点是功能组合。

执行

逻辑是这样的:

  • 首先,before <- many vocc收集 的所有实例varname .及其可选数组表达式,只留下一个标识符

  • this <- vtrm收集剩余的标识符加上数组表达式——唯一没有以点开头的标识符

问题

我有两个问题:

首先,第一个术语 [出于我无法确定的原因] 似乎总是要求将其括在括号中以便解析器接受它,即:(a[1]).b[2].c...-- 后续术语不需要这个。

其次,many vocc不会停止解析。它总是需要另一个标识符和另一个点,我无法终止表达式来捕捉最后一个vtrm.

我正在寻找可以帮助我解决问题/头痛的提示或解决方案。谢谢。

4

1 回答 1

4

运行时varExpr,它检查下一位输入是否与voccor匹配vtrm

varExpr = do before <- many vocc  -- Zero or more occurrences
             this <- vtrm
             return undefined

问题是任何与 匹配的输入vtrm也与 的第一步匹配vocc。运行时varExpr,它运行vocc,它运行vobj,它运行vtrm

vocc = vobj <* symbol "."
vobj = choice [try vtrm, try $ parens vtrm]

在不消耗输入的情况下失败时解析many vocc结束。vocc当两者都vtrm失败parens vtrm时会发生这种情况。然而,many vocc结束后,下一个要运行的解析器是vtrm——而且这个解析器肯定会失败!

如果在输入中找不到 a,您希望vocc在不消耗输入的情况下失败"."。为此,您需要使用try.

vocc = try $ vobj <* symbol "."

或者,如果vobjvtrm真的应该是相同的语法,您可以将 varExpr 定义为vobj `sepBy1` symbol ".".

于 2013-05-01T02:08:29.007 回答