【问题标题】:How do we keep multiple semantic values during parsing with Happy/Haskell我们如何在使用 Happy/Haskell 进行解析时保留多个语义值
【发布时间】:2010-07-24 10:55:02
【问题描述】:

我正在尝试在 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 部分? 现在我只知道如何只引用其中一个。我可以找到有关“添加多个 $$”的方法的信息,并在之后参考它们。

有办法吗?

V.

【问题讨论】:

  • 事实上,即使在C flex/bison 中似乎也不可能,因此直接在haskell 或caml 中应该是不可能的。但是,我可以使用元组数据 Token = Token (AlexPosn,Foo,Bar)) 而不是几个参数。我将这个问题留了几天,但我想我很快就会关闭它。

标签: haskell parser-generator alex happy


【解决方案1】:

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

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

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

    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
    

    ...

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

【讨论】:

  • +1 用于回答您自己的问题 - 它为我省去了很多麻烦!
【解决方案2】:

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

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

虽然我不确定 Happy 是否真的保证这将永远有效。它(可能)起作用的原因是happy 会生成与Token pos foo some_bar 上的模式匹配的代码,从而使posfooAst pos foo 中可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    相关资源
    最近更新 更多