【发布时间】:2011-01-02 17:50:42
【问题描述】:
我正在努力为一种简单的标记语言编写解析器。目前,我在使用无限循环和嵌套元素时遇到了一些问题。
我的标记语言基本上由两种元素组成,一种用于“普通”文本,另一种用于粗体/强调文本。
data Markup
= MarkupText String
| MarkupEmph [Markup]
例如,像Foo *bar* 这样的文本应该被解析为[MarkupText "Foo ", MarkupEmph [MarkupText "bar"]]。
该示例的词法分析工作正常,但解析它会导致无限循环 - 我不明白为什么。这是我目前的做法:
-- The main parser: Parsing a list of "Markup"
Markups :: { [Markup] }
: Markups Markup { $1 ++ [$2] }
| Markup { [$1] }
-- One single markup element
Markup :: { Markup }
: '*' Markups1 '*' { MarkupEmph $2 }
| Markup1 { $1 }
-- The nested list inside *..*
Markups1 :: { [Markup] }
: Markups1 Markup1 { $1 ++ [$2] }
| Markup1 { [$1] }
-- Markup which is always available:
Markup1 :: { Markup }
: String { MarkupText $1 }
这种方法有什么问题?怎么解决?
更新:抱歉。 Lexing 没有按预期工作。无限循环在词法分析器内部。对不起。 :)
更新 2: 应要求,我将其用作词法分析器:
lexer :: String -> [Token]
lexer [] = []
lexer str@(c:cs)
| c == '*' = TokenSymbol "*" : lexer cs
-- ...more rules...
| otherwise = TokenString val : lexer rest
where (val, rest) = span isValidChar str
isValidChar = (/= '*')
发生无限递归是因为我在'*' 的第一条规则中使用了lexer str 而不是lexer cs。没有看到它,因为我的实际代码有点复杂。 :)
【问题讨论】:
-
为了确保这个问题的完整性,您可以发布词法分析器的前后。这样其他人就可以看到出了什么问题。谢谢。