2017-04-09 13 views
0

私はPro言語用のパーサーを作成しようとしていますが、これはWhile言語の拡張バージョンです。Proc Parserで予想される型に一致しませんでした

"/*fac_loop (p.23)*/\ny:=1;\nwhile !(x=1) do (\n y:=y*x;\n x:=x-1\n)" 

と生産:それはのような入力を取ることができるはずが完了

(Comp (Ass "y" (N 1)) (While (Neg (Eq (V "x") (N 1))) (Comp (Ass "y" 
     (Mult (V "y") (V "x"))) (Ass "x" (Sub (V "x") (N 1)))))) 

私はテンキー、ヴァールの種類と一緒にAexp、BexpおよびSTMのための文法を与えてきました、 Pname、DecV、DecVは変更できません。私のHaskellのコードは以下の通りです:私は2つのタイプのエラーを取得しています

module SecondAttempt where 

import System.IO 
import Control.Monad 
{-# LANGUAGE StandaloneDeriving #-} 
import Text.Megaparsec 
import Text.Megaparsec.String 
import Data.List (intercalate) 


import Prelude hiding (Num) 
import qualified Prelude (Num) 

--- Proc definition 

-- S ::= x:=a 
-- | skip 
-- |S1 ;S2 
-- | if b then S1 else S2 
-- | while b do S 
-- | begin Dv Dv S end 
-- | call p 
-- Dv ::= var x := a ; DV | ε 
-- Dp ::= proc p is S ; DP | ε 

--- Types 

type Num = Integer 
type Var = String 
type Pname = String 
type DecV = [(Var,Aexp)] 
type DecP = [(Pname,Stm)] 

--- Data structures 

data Aexp = N Num 
      | V Var 
      | Mult Aexp Aexp 
      | Add Aexp Aexp 
      | Sub Aexp Aexp 

data Bexp = TRUE 
      | FALSE 
      | Neg Bexp 
      | And Bexp Bexp 
      | Le Aexp Aexp 
      | Eq Aexp Aexp 

data Stm = Skip 
      | Ass Var Aexp 
      | Comp Stm Stm 
      | If Bexp Stm Stm 
      | While Bexp Stm 
      | Block DecV DecP Stm 
      | Call Pname 

--- Parser Preliminaries 

cr :: Parser [Char] 
cr = many (oneOf "\r\n") 

tok :: String -> Parser String 
tok t = string t <* whitespace 

whitespace :: Parser() 
whitespace = many (oneOf " \t") *> pure() 

--- Parser 

aexp :: Parser Aexp 
aexp = N  <$ tok "N" <*> num 
    <|> V  <$ tok "V" <*> var 
    <|> Mult <$ tok "Mult" <*> aexp <* tok "*" <*> aexp 
    <|> Add <$ tok "Add" <*> aexp <* tok "+" <*> aexp 
    <|> Sub <$ tok "Sub" <*> aexp <* tok "-" <*> aexp 

bexp :: Parser Bexp 
bexp = TRUE <$ tok "TRUE" 
    <|> FALSE <$ tok "FALSE" 
    <|> Neg <$ tok "Neg" <* tok "!" <*> bexp 
    <|> And <$ tok "And" <*> bexp <* tok "&" <*> bexp 
    <|> Le <$ tok "Le" <*> aexp <* tok "<=" <*> aexp 
    <|> Eq <$ tok "Eq" <*> aexp <* tok "=" <*> aexp 

stm :: Parser Stm 
stm = Ass <$ tok "Ass" <*> var <* tok ":=" <*> aexp 
    <|> Comp <$ tok "Comp" <*> stm <* tok ";" <*> stm 
    <|> Skip <$ tok "Skip" 
    <|> If <$ tok "If" <*> bexp <* tok "then" <*> stm <* tok "else" <*> stm 
    <|> While <$ tok "While" <*> bexp <* tok "do" <*> stm 
    <|> Block <$ tok "begin" <*> decv <*> decp <*> stm <* tok "end" 
    <|> Call <$ tok "call" <*> pname 

num :: Parser Num 
num = (some (oneOf ['0' .. '9']) >>= return . read) <* whitespace 

var :: Parser Var 
var = tok "\"" *> some (noneOf ("\n\r\"")) <* tok "\"" 

decv :: Parser DecV 
decv = var <* tok ":=" <*> aexp <* tok ";" <*> decv 

decp :: Parser DecP 
decp = pname <* tok "is" <*> stm <* tok ";" <*> decp 

pname :: Parser Pname 
pname = tok "\"" *> some (noneOf ("\n\r\"")) <* tok "\"" 

true :: Bool 
true = True 

false :: Bool 
false = False 

、1それぞれが自分のDECVとDECP機能をどうする:この問題を解決する方法が本当にわからない

Couldn't match type ‘[Char]’ with ‘Aexp -> DecV -> DecV’ 
    Expected type: ParsecT 
        Dec String Data.Functor.Identity.Identity (Aexp -> `DecV -> DecV) 
     Actual type: Parser Var 
    In the first argument of ‘(<*)’, namely ‘var’ 
    In the first argument of ‘(<*>)’, namely ‘var <* tok ":="’ 

Couldn't match type ‘[Char]’ with ‘Stm -> DecP -> DecP’ 
    Expected type: ParsecT 
        Dec String Data.Functor.Identity.Identity (Stm -> DecP -> DecP) 
     Actual type: Parser Pname 
    In the first argument of ‘(<*)’, namely ‘pname’ 
    In the first argument of ‘(<*>)’, namely ‘pname <* tok "is"’ 

を!

+3

:どの程度

decv :: Parser DecV decv = var <* tok ":=" <*> aexp <* tok ";" <*> decv decp :: Parser DecP decp = pname <* tok "is" <*> stm <* tok ";" <*> decp 

。 –

答えて

1

リストのパーサー(DecVDecP)を正しく作成していないという問題があります。

DecVの場合は、先にvaraexpのペアを作成してリストにする必要があります。

の代わりに:これは私のコースの宿題のように見えます

decv :: Parser DecV 
decv = many ((,) <$> var <* tok ":=" <*> aexp <* tok ";") 

decp :: Parser DecP 
decp = many ((,) <$> pname <* tok "is" <*> stm <* tok ";") 
関連する問題