2010-04-29 4 views
1

articles Haskell Parsec de numération

J'utilise Text.ParserCombinators.Parsec et Text.XHtml pour analyser une entrée comme ceci:

 
- First type A\n 
-- First type B\n 
- Second type A\n 
-- First type B\n 
--Second type B\n 

Et ma sortie devrait être:

 

<h1>1 First type A\n</h1> 
<h2>1.1 First type B\n</h2> 
<h1>2 Second type A\n</h2> 
<h2>2.1 First type B\n</h2> 
<h2>2.2 Second type B\n</h2> 
 

Je suis venu à cette partie, mais je ne peux pas obtenir plus loin:

 

title1= do{  
       ;(count 1 (char '-')) 
       ;s <- many1 anyChar newline 
       ;return (h1 << s) 
    } 

title2= do{  
       ;(count 2 (char '--')) 
       ;s <- many1 anyChar newline 
       ;return (h1 << s) 
    } 

text=do { 
     ;many (choice [try(title1),try(title2)]) 
} 

main :: IO() 
main = do t putStr "Error: " >> print err 
      Right x -> putStrLn $ prettyHtml x 

 

Ceci est correct, mais il n'inclut pas la numérotation.

Des idées?

Merci!

Répondre

6

Vous voulez probablement utiliser GenParser avec un état contenant les numéros de section en cours comme une liste dans l'ordre inverse, si la section 1.2.3 sera représentée comme [3,2,1], et peut-être la longueur de la liste évitez de le compter à plusieurs reprises. Quelque chose comme

data SectionState = SectionState {nums :: [Int], depth :: Int} 

Faites ensuite vos actions de l'analyseur type de retour est "GenParser Char SectionState un". Vous pouvez accéder à l'état actuel dans vos actions de l'analyseur en utilisant « getState » et « setState ». Lorsque vous obtenez une série de « - » au début d'une ligne les compter et le comparer avec la « profondeur » dans l'état, de manipuler la liste « nums » de façon appropriée, puis émettre « nums » dans l'ordre inverse (je suggère garder nums dans l'ordre inverse parce que la plupart du temps que vous voulez accéder au moins élément important, afin de le mettre à la tête de la liste est à la fois plus facile et plus efficace).

Voir Text.ParserCombinators.Parsec.Prim pour plus de détails de GenParser. Plus type habituel de Parser est juste "type Parser a = GenParser Char() un" Vous voulez sans doute dire

type MyParser a = GenParser Char SectionState a 

quelque part au début de votre code.