Я пытаюсь написать парсер для простого языка разметки с happy.В настоящее время у меня есть некоторые проблемы с бесконечными циклами и вложенными элементами.
Мой язык разметки в основном состоит из двух элементов, один для "обычного" текста и один для выделенного / выделенного текста.
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 }
Что не так с этим подходом?Как можно решить?
Обновление: Извините.Лексинг работал не так, как ожидалось.Бесконечный цикл был внутри лексера.Сожалею.:)
Обновление 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
1027 * в этом первом правиле для '*'
.Не видел, потому что мой настоящий код был немного сложнее.:)