[英]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.