Parsec和用户定义的状态

时间:2013-01-06 17:22:32

标签: parsing haskell parsec

我正在尝试在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之前会自动插入分号。

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

1 个答案:

答案 0 :(得分:1)

你有

expression = try unaryExpression <|> plusExpression

但这不起作用,因为UnaryExpressionPlusExpression的前缀。

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

解析器愉快地解析第一个NumberToken并自动添加分号,因为下一个标记是PlusToken而不是SemicolonToken。然后它会尝试解析下一个Expression,但下一个是PlusToken,没有Expression可以从那开始。

更改解析器的尝试顺序,

expression = try plusExpression <|> unaryExpression

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