4

我正在尝试在 Haskell 中使用 Alex/Happy 构建一个简单的词法分析器/解析器,并且我想将文本文件中的一些本地化信息保留到我的最终 AST 中。

我设法使用 Alex 构建了一个词法分析器,它构建了一个具有本地化的令牌列表:

data Token = Token AlexPosn Foo Bar
lexer :: String -> [Token]

在我的 Happy 文件中,当声明 %token 部分时,我可以用 $$ 符号声明令牌的语义部分

%token FOO  { Token _ $$ _ }

在解析规则中,$i 将引用这个 $$。

foo_list: FOO  { [$1] }
        | foo_list FOO { $2 : $1 }

有没有办法引用 AlexPosn 部分FOO 令牌的 Foo 部分?现在我只知道如何只引用其中一个。我可以找到有关“添加多个 $$”的方法的信息,并在之后参考它们。

有没有办法这样做?

五。

4

2 回答 2

4

最后,我确实找到了2个解决方案:

  • 将所有含义数据打包到一个元组中,让$$指向这个元组,然后通过投影提取数据:

    data Token = Token (AlexPosn,Foo) Bar
    %token FOO { Token $$ some_bar }
    rule : FOO  { Ast (fst $1) (snd $1) }
    
  • 根本不要使用 $$:如果你不使用 $$,happy 会在解析过程中给你完整的令牌,所以你可以从这个令牌中提取你真正需要的东西:

    data Token = Token AlexPosn Foo Bar
    %token FOO = { Token _ _ some_bar }
    rule : FOO  { Ast (get_pos $1) (get_foo $1) }
    
    get_pos :: Token -> AlexPosn
    get_foo :: Token -> Foo
    

    ...

我认为第一个是最优雅的。如果您携带大量信息,则第二个在代码行方面可能相当繁重:您将不得不手动构建“投影”(模式匹配等),并且以安全的方式这样做可能会很棘手如果您的令牌类型很大。

于 2010-07-28T08:32:31.200 回答
1

也可以像这样保留多个值:

data Token = Token AlexPosn Foo Bar
%token FOO { Token pos foo some_bar }
rule : FOO { Ast pos foo }

Although I'm not sure if Happy actually guarantees that this will always work. The reason for why it (maybe) works is that happy will generate code that pattern matches on Token pos foo some_bar, making pos and foo available in Ast pos foo.

于 2018-04-20T13:38:16.790 回答