我不知道什么是错的,但是当我尝试编译它时,它会说"解析输入错误'导出' &#34 ;.当我尝试删除deriving Show
上的type Code
时,错误将消失,但我无法使用翻译功能。为什么是这样?我还是很抱歉。
> module Imp where
>
> import Parsing
>
> type Ide = String
> data Imp
> = Skip
> | Assign Ide Imp
> | Begin Imp
> | Seq Imp Imp
> | Ifz Imp Imp Imp
> | While Imp Imp
> | Num Int
> | Var Ide
> | Add Imp Imp
> | Sub Imp Imp
> | Mul Imp Imp
> | Div Imp Imp
> | Eq Imp Imp
> deriving Show
> type Binding = (String, Int)
> data StackVal = N Int | Bind Binding deriving Show
> type Stack = [StackVal]
> type Env = [Binding]
> data ASM --Abstract Stack Machine
> = Push StackVal
> | Pop StackVal
> | ADD | SUB | MUL | DIV | EQUIV
> | Jmp Int
> | Jnz Int
> | Lab Int
> | Halt
> deriving Show
> type Code = [ASM]
Translator
----------
> translate :: Imp -> Env -> Code
> translate (Num n) m = [Push (N n)]
> translate (Var x) m = [Push (Bind (x, v))] where Just v = lookup x m
> translate (Skip) m = []
> translate (Assign x exp) m = translate exp m ++ [Pop (Bind (x, v))] where Just v = lookup x m
> translate (Seq c1 c2) m = translate c1 m ++ translate c2 m
> translate (Ifz exp c1 c2) m = translate exp m ++ [Jmp 1] ++ translate c1 m ++ [Jnz 2]
> ++ [Lab 1] ++ translate c2 m ++ [Lab 2]
> translate (While exp c) m = [Lab 1] ++ translate exp m ++ [Jmp 2] ++ translate c m ++ [Jnz 1] ++ [Lab 2]
> translate (Add x y) m = translate x m ++ translate y m ++ [ADD]
> translate (Sub x y) m = translate x m ++ translate y m ++ [SUB]
> translate (Mul x y) m = translate x m ++ translate y m ++ [MUL]
> translate (Div x y) m = translate x m ++ translate y m ++ [DIV]
> translate (Eq x y) m = translate x m ++ translate y m ++ [EQUIV]
Grammar
--------
> asgn :: Parser Imp
> asgn = eqimp +++ expr
>
> expr :: Parser Imp
> expr = addimp +++ subimp +++ term
>
> term :: Parser Imp
> term = mulimp +++ divimp +++ factor
>
> factor :: Parser Imp
> factor = (do symbol "("; e <- expr; symbol ")"; return e)
> +++ number +++ idnt
>
> number :: Parser Imp
> number = (do n <- natural; return (Num n))
>
> idnt :: Parser Imp
> idnt = (do i <- identifier; return (Var i))
>
> ide :: Parser Ide
> ide = (do i <- identifier; return (i))
Expressions
-----------
> eqimp :: Parser Imp
> eqimp = (do i <- idnt; symbol "="; a <- asgn; return (Eq i a))
> +++ (do i <- idnt; symbol "="; e <- expr; return (Eq i e))
> +++ (do i <- idnt; symbol "="; i <- idnt; return (Eq i i))
> +++ (do e1 <- expr; symbol "="; e2 <- expr; return (Eq e1 e2))
> addimp :: Parser Imp
> addimp = (do t <- term; symbol "+"; e <- expr; return (Add t e))
> +++ (do i <- idnt; symbol "+"; t <- term; return (Add i t))
> subimp :: Parser Imp
> subimp = (do t <- term; symbol "-"; e <- expr; return (Sub t e))
> +++ (do i <- idnt; symbol "-"; t <- term; return (Sub i t))
> mulimp :: Parser Imp
> mulimp = (do f <- factor; symbol "*"; t <- term; return (Mul f t))
> +++ (do i <- idnt; symbol "*"; f <- factor; return (Mul i f))
> divimp :: Parser Imp
> divimp = (do f <- factor; symbol "/"; t <- term; return (Div f t))
> +++ (do i <- idnt; symbol "/"; f <- factor; return (Div i f))
Commands
---------
>
> skipimp :: Parser Imp
> skipimp = (do symbol "skip"; return Skip)
>
> assignimp :: Parser Imp
> assignimp = (do i <- ide; symbol ":="; e <- expr; return (Assign i e))
>
> assignimp2 :: Parser Imp
> assignimp2 = (do i <- ide; symbol ":="; e <- expr; symbol ";"; return (Assign i e))
> +++ (do i <- ide; symbol ":="; e <- expr; return (Assign i e))
>
> seqimp :: Parser Imp
> seqimp = (do w <- whileimp; symbol ";"; s2 <- seqimp; return (Seq w s2))
> +++ (do w <- whileimp; symbol ";"; c2 <- com3; return (Seq w c2))
> +++ (do i <- ifzimp; symbol ";"; s2 <- seqimp; return (Seq i s2))
> +++ (do i <- ifzimp; symbol ";"; c2 <- com3; return (Seq i c2))
> +++ (do c1 <- com2; symbol ";"; s2 <- seqimp; return (Seq c1 s2))
> +++ (do c1 <- com2; symbol ";"; c2 <- com2; symbol ";"; return (Seq c1 c2))
> +++ (do c1 <- com2; symbol ";"; c2 <- com2; return (Seq c1 c2))
>
> ifzimp :: Parser Imp
> ifzimp = (do symbol "if"; e <- expr; symbol "then"; c1 <- com;
> symbol "else"; symbol "("; c2 <- com; symbol ")"; return (Ifz e c1 c2))
> +++ (do symbol "if"; e <- expr; symbol "then"; c1 <- com;
> symbol "else"; c2 <- com; return (Ifz e c1 c2))
>
> whileimp :: Parser Imp
> whileimp = (do symbol "while"; e <- expr; symbol "do";
> symbol "("; c2 <- com; symbol ")"; return (While e c2))
> +++ (do symbol "while"; e <- expr;
> symbol "do"; c2 <- com; return (While e c2))
>
> beginimp :: Parser Imp
> beginimp = (do symbol "begin"; c <- com; symbol "end"; return (Begin c))
>
>
> com :: Parser Imp
> com = seqimp
> +++ whileimp
> +++ ifzimp
> +++ beginimp
> +++ assignimp
> +++ skipimp
> +++ (do symbol "("; c <- com; symbol ")"; return c)
>
> com2 :: Parser Imp
> com2 = beginimp
> +++ whileimp
> +++ ifzimp
> +++ assignimp
> +++ skipimp
> +++ (do symbol "("; c <- com2; symbol ")"; return c)
>
> com3 :: Parser Imp
> com3 = beginimp
> +++ whileimp
> +++ ifzimp
> +++ assignimp2
> +++ skipimp
> +++ (do symbol "("; c <- com2; symbol ")"; return c)
Parsers
-------
> parse_imp :: String -> Imp
> parse_imp str =
> case parse com str of
> [(result, [])] -> result
> [(_, out)] -> error ("unused input: " ++ out)
> [] -> error ("invalid input: " ++ str)
>
> parse_exp :: String -> Imp
> parse_exp str =
> case parse asgn str of
> [(result, [])] -> result
> [(_, out)] -> error ("unused input: " ++ out)
> [] -> error ("invalid input: " ++ str)
更新:我删除了deriving Show
部分的type Code
。如果解析的输入不涉及变量,则translate
函数似乎有效...例如:translate (parse_exp "1") []
结果[Push (N 1)]
。剩下的问题是,当我尝试类似translate (parse_exp "x + 1")
之类的东西时,因为模式Just v
的无效参数模式会出错。 translate (Assign x exp) m = ... where Just v = lookup x m
上的那一行我猜有问题:
*Imp> translate (parse_exp "1 + 5") [] [Push (N 1), Push (N 5), ADD] *Imp> translate (parse_exp "x + 1") [] [Push (Bind ("x",*** Exception: imp.lhs:50:66-84: Irrefutable pattern failed for pattern Just v
答案 0 :(得分:2)
请注意,代码Just v = lookup x m
仅在地图x
中存在m
引用的变量名称时才有效。但是,您的translate函数从不向环境添加变量,因此m
始终为空,并且您的Assign代码将始终抛出异常。
解决方案?那取决于你的努力的具体细节,但我会添加一种方法来绑定变量,如lambda的。这不会使x +1
解析,因为x
仍然不在环境中,但如果您愿意,可以lambda x. x + 1
进行解析。请注意,您需要弄清楚如何从堆栈中获取变量。