我正在尝试从happy生成GLR解析器,但是一旦生成文件我就会收到错误。
这是一个例子,ABC.y,所以我很清楚我在尝试什么:
{
module Main where
}
%name ps1 s1
%tokentype { ABC }
%error { parseError }
%token
a { A }
b { B }
c { C }
%%
s1: a a a b {} | b s2 a {}
s2: b a b s2 {} | c {}
{
data ABC = A | B | C
parseError _ = error "bad"
main = getContents >>= print . ps1 . lexer
lexer ('a':xs) = A : lexer xs
ETC
}
此示例适用于
happy ABC.y
然而,对于-glr感到高兴,我无法构建结果。我想知道我做错了。确切地说,快乐--glr,产生两个输出,ABC.hs.但是,ABCData.hs
ghc --make ABC.hs ABCData.hs
现在失败了。我得到的错误是找不到模块'系统',它是haskell-98的隐藏成员...我尝试添加包haskell98,并且得到了模糊的前奏问题。我也尝试将语法编码为BNFC并使用它们的-glr选项,但我仍然得到其他错误,例如依赖于Data.FiniteMap,这显然已被弃用。有没有办法进行编译?
答案 0 :(得分:1)
happy --glr
正常工作 - 只需要在输出中手动更改一件事。但请注意,它与在典型的 _ .y文件中使用Happy不同。
基本上,您必须考虑一些差异。预期词法分析器结果的类型是不同的。解析器的返回类型不太可控并且不同。你使用解析器的方式略有不同。必要的信息可以在以下网址找到: http://www.haskell.org/happy/doc/html/sec-glr-using.html 理解网页正确使用glr选项非常重要。
以下是如何使用Happy with glr选项生成独立解析器;我们所关心的只是解析是否成功 - 您可以在上面的页面上阅读有关解析结果以及如何解释它们的更多信息。我们将为上面的解析器ABC执行此操作。首先,创建一个名为ABCMain.hs的文件:
module Main where
import ABC
import ABCData
main = do
inp <- getContents
case happyParse (lexer inp) of
ParseOK _ _ -> putStrLn "success"
_ -> putStrLn " success"
lexer ('a':xs) = [A] : lexer xs
ETC -- note that it is [[Token]] instead of [Token]
而ABC.y文件只是:
%tokentype { ABC }
%error { parseError }
%token
a { A }
b { B }
c { C }
%%
s1 : a a a b {} | b s2 a {}
s2: b a b s2 {} | c {}
{
data ABC = A | B | C deriving (Eq,Ord,Show) -- you must have Eq and Ord
parseError _ = error "bad"
}
运行
happy --glr ABC.y
制作两个文件。现在,有一点我希望有人评论 - 基本上你必须在生成的文件ABC.hs中手动更改行
import System
到
import System.IO
然后,以下内容适用于我:
ghc --make ABCMain.hs
所有内容都编译,解析器按预期工作。如果我做得对,请随时告诉我。