Nested parsers in happy / infinite loop?

Posted by McManiaC on Stack Overflow See other posts from Stack Overflow or by McManiaC
Published on 2011-01-02T17:50:42Z Indexed on 2011/01/02 23:53 UTC
Read the original article Hit count: 272

Filed under:
|

I'm trying to write a parser for a simple markup language with happy. Currently, I'm having some issues with infinit loops and nested elements.

My markup language basicly consists of two elements, one for "normal" text and one for bold/emphasized text.

data Markup
    = MarkupText   String
    | MarkupEmph   [Markup]

For example, a text like Foo *bar* should get parsed as [MarkupText "Foo ", MarkupEmph [MarkupText "bar"]].

Lexing of that example works fine, but the parsing it results in an infinite loop - and I can't see why. This is my current approach:

-- 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 }

What's wrong with that approach? How could the be resolved?

Update: Sorry. Lexing wasn't working as expected. The infinit loop was inside the lexer. Sorry. :)

Update 2: On request, I'm using this as lexer:

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 = (/= '*')

The infinit recursion occured because I had lexer str instead of lexer cs in that first rule for '*'. Didn't see it because my actual code was a bit more complex. :)

© Stack Overflow or respective owner

Related posts about haskell

Related posts about happy