2

当你写一个快乐的描述时,你必须定义所有可能出现的令牌类型。但是您只能匹配令牌类型,而不是单个令牌......

这有点问题。例如,考虑data关键字。根据 Haskell 报告,这个令牌是一个“reservedid”。所以我的标记器识别它并标记它。但是,请考虑as关键字。现在事实证明这不是一个reservedid;这是一个普通的变量。它仅在一种情况下是特殊的。您完全可以声明一个名为 的普通变量as,这很好。

所以这里有一个问题:我如何as具体解析?

起初我并没有真正考虑过。我刚刚定义了一个新的令牌类型,它代表文本恰好是的任何可变令牌as

...然后我花了大约 2 个小时试图弄清楚为什么我的语法实际上不起作用。是的,事实证明,由于此令牌类型与现有令牌类型重叠,因此声明顺序很重要。(!!!) 从字面上看,更改声明的顺序使语法解析完美。

但现在我很担心。我担心它as永远不会被匹配为一个变量,只会匹配它自己。所以所有说 varid 的语法规则都会拒绝这个as标记——这是完全错误的!

解决此问题的正确方法是什么?

4

1 回答 1

5

GHC 所做的Parser.y是定义一个非终结标记类型,其中special_id列出了许多特殊的非关键字as,如在我看来,它们也应该被放入)。tyvaridvaridVARIDspecial_id

摘录:

varid :: { Located RdrName }
        : VARID            { sL1 $1 $! mkUnqual varName (getVARID $1) }
        | special_id       { sL1 $1 $! mkUnqual varName (unLoc $1) }
        | 'unsafe'         { sL1 $1 $! mkUnqual varName (fsLit "unsafe") }
        ...

special_id :: { Located FastString }
special_id
        : 'as'                  { sL1 $1 (fsLit "as") }
        | 'qualified'           { sL1 $1 (fsLit "qualified") }
        | 'hiding'              { sL1 $1 (fsLit "hiding") }
        | 'export'              { sL1 $1 (fsLit "export") }
        ...
于 2015-11-01T21:53:57.147 回答