简体   繁体   English

Haskell - 使用状态与替代

[英]Haskell - Using State with Alternative

I have a datatype that looks like the following:我有一个如下所示的数据类型:

type Parser a = ExceptT ParseError (State [Token]) a

As well as state manipulation functions:以及状态操作函数:

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

I'm trying to use these functions to help validate production rules in a grammar:我正在尝试使用这些函数来帮助验证语法中的产生式规则:

charList :: Parser CharList
charList =
    (return CharListCharacter <*> isToken (Character "<char>") <*> charList)
    <|> (return CharListSpace <*> isToken (Space " ") <*> charList)
    <|> (return EmptyCharList)

It seems that isToken needs to consume the current token (using consumeToken ) so that the recursive calls to charList then deal with the following token.似乎isToken需要消耗当前令牌(使用consumeToken ),以便对charList的递归调用然后处理以下令牌。 However, doing so means that the alternative cases will not start from the same token as the first case.但是,这样做意味着替代案例将不会从与第一个案例相同的标记开始。

Is there a standard way to deal with this problem?有没有标准的方法来处理这个问题?

Following the advice from the comments, I remodeled my parser to take advantage of the fact that my grammar is LL(1).根据评论中的建议,我改造了我的解析器以利用我的语法是 LL(1) 的事实。 Doing this meant I had no need for Alternative .这样做意味着我不需要Alternative

This is the final version of the charList function (with isToken using consumeToken ):这是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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM