0

我正在尝试从快乐中生成 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 很满意,我无法构建结果。我想知道我是否做错了。准确地说,happy --glr 产生两个输出,ABC.hs。然而,ABCData.hs,

ghc --make ABC.hs ABCData.hs

现在失败了。我得到的错误是找不到模块'System',它是haskell-98的隐藏成员......我尝试添加包haskell98,并得到了模棱两可的前奏问题。我还尝试将语法编码为 BNFC 并使用他们的 -glr 选项,但我仍然遇到其他错误,例如对显然已弃用的 Data.FiniteMap 的依赖。有没有办法得到这个编译?

4

1 回答 1

1
happy --glr

工作正常——只有一件事必须在输出中手动更改。但是请注意,它不同于在典型的_ .y 文件上使用 Happy。

基本上,您必须考虑许多差异。预期的词法分析器结果的类型不同。解析器返回的类型不太可控且不同。而且您使用解析器的方式略有不同。可以在以下网址找到必要的信息: http ://www.haskell.org/happy/doc/html/sec-glr-using.html ,了解该网页以正确使用 glr 选项非常重要。

以下是如何使用 Happy 和 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

一切都编译并且解析器按预期工作。如果我做得正确,请随时告诉我。

于 2014-03-29T23:25:36.967 回答