在使用Happy/Haskell进行解析时,我们如何保持多个语义值
我正试图用Alex/Happy在Haskell中构建一个简单的lexer/parser,我想 将文本文件中的一些本地化信息保存到我的最终AST中 我设法使用Alex构建了一个lexer,该lexer构建了一个带有本地化的令牌列表:在使用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 _ $$ _
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回答你自己的问题-这帮我省去了很多麻烦!