2013-10-07 63 views
2

全部,Parsec:在一條線上的多個可能的選項

我想用parsec編寫一個解析器。目標是最終能夠解析玩具語言。

現在我努力讓parsec識別兩種不同的可能選項,例如賦值和函數調用。

如何將一個寫有 「parseCode」 功能解析如下:

x = 3 
y = 4 
plus(x,y) 

到:

(Assignment "x" "3") 
(Assignment "y" "4") 
(Invocation "plus" ["x","y"]) 

感謝

編輯:

**略去了**

編輯2:

我建立了一點您的建議,現在有以下問題 運行parse parseTester "bla" "{plus(3,4)\nmin(2,3)\nx=3\n"給出了預期的解決方案:Right (Body [Invocation "plus",Invocation "min",Assignment "x" "3"])

但在運行功能(幾乎)相當於parse parseBody "bla" "{plus(3,4)\nmin(2,3)\nx=3\n}"導致錯誤:

Left "bla" (line 4, column 2): 
unexpected end of input 
expecting white space or "=" 

我沒有看到這個問題。解析器是否突然尋找一個應該在尋找調用的任務?有什麼建議麼?

代碼:

data Body = Body [Statement] 
    deriving (Show) 

data Arguments = Arguments [String] 
    deriving (Show) 

data Statement = Assignment String String 
       | Invocation String 
    deriving (Show) 


parseBody :: Parser Body 
parseBody = do 
    char '{' 
    statements <- many1 parseStatement 
    char '}' 
    return $ Body statements 

parseTester :: Parser Body 
parseTester = do 
    char '{' 
    x <- many1 parseStatement 
    return $ Body x 

parseStatement :: Parser Statement 
parseStatement = do 
     x <- try parseInvocation <|> parseAssignment <?> "statement" 
     return x 

parseInvocation :: Parser Statement 
parseInvocation = do 
    spaces 
    name <- many1 (noneOf " (") 
    spaces 
    char '(' 
    spaces 
    bla <- many1 (noneOf ")") 
    spaces 
    char ')' 
    char '\n' 
    return $ Invocation name 

parseAssignment :: Parser Statement 
parseAssignment = do 
    spaces 
    var <- many1 (noneOf " =") 
    spaces 
    char '=' <?> "equal in assignment" 
    spaces 
    value <- many1 (noneOf "\n") 
    char '\n' 
    spaces 
    return $ Assignment var value 
+0

什麼迄今已試過嗎? – bheklilr

+0

我已經添加了我現在的代碼。基本上,parseBody應該解析語句,但我真的不知道從哪裏開始...... – ddccffvv

+0

我看到你的第一個大問題。你試圖重新定義內置的'Maybe'類型。只需使用它作爲'類型參數=可能字符串',不要自己重新定義它。您還必須更改'parseArguments = return Nothing'才能重新編譯它。 – bheklilr

回答

2

如果我們需要分析一些選擇,你可以使用choiceText.ParserCombinators.Parsec.Combinator

choice [parseInvocation, parseAssignmen] 

或多少simplier:try parseInvocation <|> try parseAssignmen

附:

你可以使用表格Text.ParserCombinators.Parsec.Char

many (oneOf " ") == spaces 

oneOf " " == space 
相關問題