Haskell - Использование State с Альтернативой
У меня есть тип данных, который выглядит следующим образом:
type Parser a = ExceptT ParseError (State [Token]) a
А также функции манипулирования состоянием:
consumeToken :: Parser Token
consumeToken = do
toks <- lift get
if null toks
then throwE OutOfTokensError
else
do
lift $ put (tail toks)
return $ head toks
peekToken :: Parser Token
peekToken = do
toks <- lift get
if null toks
then throwE OutOfTokensError
else
do
return $ head toks
Я пытаюсь использовать эти функции, чтобы помочь проверить правила производства в грамматике:
charList :: Parser CharList
charList =
(return CharListCharacter <*> isToken (Character "<char>") <*> charList)
<|> (return CharListSpace <*> isToken (Space " ") <*> charList)
<|> (return EmptyCharList)
Кажется, что isToken
необходимо использовать текущий токен (используя consumeToken
) так что рекурсивные вызовы charList
тогда разберитесь со следующим токеном. Однако это означает, что альтернативные варианты не будут начинаться с того же токена, что и первый вариант.
Есть ли стандартный способ решения этой проблемы?
1 ответ
Следуя совету из комментариев, я переделал свой синтаксический анализатор, чтобы использовать тот факт, что моя грамматика - LL(1). Это означало, что мне не нужно Alternative
,
Это финальная версия charList
функция (с isToken
с помощью consumeToken
):
charList :: Parser CharList
charList = do
tok <- peekToken
case tok of Character _ -> return CharListCharacter <*> isToken (Character "<char>") <*> charList
Space _ -> return CharListSpace <*> isToken (Space " ") <*> charList
_ -> return EmptyCharList