2013-10-07 2 views
2

Все,Parsec: несколько возможных опций на одной линии

Я пытаюсь написать парсер с использованием парсера. Цель состоит в том, чтобы в конечном итоге смогла разобрать игрушечный язык.

Прямо сейчас я изо всех сил стараюсь, чтобы parsec распознал два разных возможных варианта, например назначение и вызов функции.

Как бы один написать функцию "parseCode" разобрать следующее:

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

в:

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

Благодарности

EDIT:

** опущено для краткости **

EDIT 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'. Просто используйте его как 'type Arguments = Maybe String', не переопределяйте его самостоятельно. Вам также придется изменить 'parseArguments = return Nothing', чтобы он снова скомпилировался. – bheklilr

ответ

2

Если нужно проанализировать несколько вариантов, вы можете использовать choice из Text.ParserCombinators.Parsec.Combinator

choice [parseInvocation, parseAssignmen] 

или много проще: try parseInvocation <|> try parseAssignmen

P.S.

Вы можете использовать форму Text.ParserCombinators.Parsec.Char:

many (oneOf " ") == spaces 

oneOf " " == space 
Смежные вопросы