快乐:这不是关键字

Mat*_*hid 2 parsing haskell happy

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

这有点问题.例如,考虑data关键字.根据Haskell报告,这个标记是"保留".所以我的tokeniser识别它并标记它.但是,请考虑as关键字.现在事实证明这不是一个保留; 这是一个普通的varid.它只在一个上下文中特殊.你可以完全声明一个名为的普通变量as,它很好.

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

最初我并没有真正考虑过它.我刚刚定义了一个新的令牌类型,它表示任何文本恰好是的varid令牌as.

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

但现在我很担心.我担心as永远不会匹配varid,只能匹配自己.所以说varid将拒绝as令牌的所有语法规则- 这是完全错误的!

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

Ørj*_*sen 5

GHC在其中所做的Parser.y是定义一个非终结令牌类型special_id,列出许多特殊的非关键词as,然后定义tyvaridvarid(非终端)令牌,将其作为除终端之外的选项VARID(以及其他一些,尽管其中大部分都是在我看来他们应该也被放入special_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") }
        ...
Run Code Online (Sandbox Code Playgroud)