我正在尝试在haskell中实现js解析器。但我坚持使用自动分号插入。我创建test project来解决问题,但我无法弄清楚如何解决问题。
在我的测试项目程序中是一个表达式列表(一元或二元):
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之前会自动插入分号。
那么,实现这种解析器行为的最优雅方式是什么。
答案 0 :(得分:1)
你有
expression = try unaryExpression <|> plusExpression
但这不起作用,因为UnaryExpression
是PlusExpression
的前缀。
input2 = [NumberToken Number1, PlusToken, NumberToken Number1, SemicolonToken]
解析器愉快地解析第一个NumberToken
并自动添加分号,因为下一个标记是PlusToken
而不是SemicolonToken
。然后它会尝试解析下一个Expression
,但下一个是PlusToken
,没有Expression
可以从那开始。
更改解析器的尝试顺序,
expression = try plusExpression <|> unaryExpression
它将首先尝试解析PlusExpression
,并且只有当它失败时才会使用UnaryExpression
的较短解析。