2

我正在尝试在haskell中实现js解析器。但我坚持使用自动分号插入。我创建了测试项目来解决问题,但我不知道如何解决问题。

在我的测试项目程序中是一个表达式列表(一元或二元):

data Program = Program [Expression]

data Expression
    = UnaryExpression Number
    | PlusExpression Number Number

输入流是令牌列表:

data Token
    = SemicolonToken
    | NumberToken Number
    | PlusToken

我想解析这样的输入:
1;- 一元表达式
1 + 2;- 二进制表达式
1; 2 + 3;- 两个表达式(一元和二进制)
1 2 + 3;- 与之前的输入相同,但缺少第一个分号。因此解析器使用标记 1,但任何语法生成都不允许标记 2(下一个预期标记是分号或加号)。自动分号插入规则表示,在这种情况下,分号会自动插入到标记 2 之前。

那么,实现这种解析器行为的最优雅的方式是什么。

4

1 回答 1

1

你有

expression = try unaryExpression <|> plusExpression

但这不起作用,因为 aUnaryExpression是 a 的前缀PlusExpression。因此对于

input2 = [NumberToken Number1, PlusToken, NumberToken Number1, SemicolonToken]

解析器愉快地解析第一个NumberToken并自动添加分号,因为下一个标记是 aPlusToken而不是 a SemicolonToken。然后它尝试解析下一个Expression,但下一个是 a PlusTokenExpression不能从那个开始。

更改尝试解析器的顺序,

expression = try plusExpression <|> unaryExpression

并且它会首先尝试解析 a PlusExpression,并且只有在失败时才使用较短的解析 a UnaryExpression

于 2013-01-06T18:41:23.623 回答