Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在使用Happy/Haskell进行解析时,我们如何保持多个语义值_Haskell_Parser Generator_Alex_Happy - Fatal编程技术网

在使用Happy/Haskell进行解析时,我们如何保持多个语义值

在使用Happy/Haskell进行解析时,我们如何保持多个语义值,haskell,parser-generator,alex,happy,Haskell,Parser Generator,Alex,Happy,我正试图用Alex/Happy在Haskell中构建一个简单的lexer/parser,我想 将文本文件中的一些本地化信息保存到我的最终AST中 我设法使用Alex构建了一个lexer,该lexer构建了一个带有本地化的令牌列表: data Token = Token AlexPosn Foo Bar lexer :: String -> [Token] 在我的快乐文件中,当声明%令牌部分时,我可以声明 带有$$符号的标记的语义部分 %token FOO { Token _ $$ _

我正试图用Alex/Happy在Haskell中构建一个简单的lexer/parser,我想 将文本文件中的一些本地化信息保存到我的最终AST中

我设法使用Alex构建了一个lexer,该lexer构建了一个带有本地化的令牌列表:

data Token = Token AlexPosn Foo Bar
lexer :: String -> [Token]
在我的快乐文件中,当声明%令牌部分时,我可以声明 带有$$符号的标记的语义部分

%token FOO  { Token _ $$ _ }
在解析规则中,$i将引用这个$$

foo_list: FOO  { [$1] }
        | foo_list FOO { $2 : $1 }
有没有一种方法可以引用Foo令牌的AlexPosn部分和Foo部分? 现在我只知道如何引用其中一个。我可以找到有关“添加若干$$”的方法的信息,并在以后参考它们

有没有办法做到这一点


V.

最后,我确实找到了两种解决方案:

  • 将所有意义数据打包到一个元组中,以便$$指向该元组,然后提取 预测数据:

    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
    


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

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

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
上生成模式匹配的代码,使得
pos
foo
Ast pos foo

中可用。事实上,即使在C flex/bison中,它似乎也不可能,因此在haskell或caml中不应该直接实现。但是,我可以使用tuple data Token=Token(AlexPosn,Foo,Bar))而不是几个参数。我将把这个问题保留几天,但我想我很快就会结束它。+1回答你自己的问题-这帮我省去了很多麻烦!