2016-07-25 17 views
0

Die Parsec Dokumentation einen LEXER aufzubauen hat:Wiederholung in lexing vermeiden, wenn ein Beispiel der Verwendung <code>makeTokenParser</code> Verwendung Parsek

module Main where 

import Text.Parsec 
import qualified Text.Parsec.Token as P 
import Text.Parsec.Language (haskellDef) 

-- The parser 
... 

expr = parens expr 
     <|> identifier 
     <|> ... 


-- The lexer 
lexer  = P.makeTokenParser haskellDef  

parens  = P.parens lexer 
braces  = P.braces lexer 
identifier = P.identifier lexer 
reserved = P.reserved lexer 
... 

In "The LEXER" Block wird jede P.* so zu LEXER aufgebracht, dass eine Wiederholungs vermeiden das in "Der Parser" blockieren. Das für jeden Token zu wiederholen ist jedoch immer noch mühsam. Gibt es einen Weg, die Wiederholung noch mehr zu vermeiden? Ich dachte daran, lexer implizit überall in "The Parser" anzuwenden, aber ich weiß nicht wie.

Antwort

3

Es gibt eine allgemeine syntax for pattern matching on records in Haskell ist (Ich begann zu bemerken, dass alle P.parens, P.braces usw. sind Funktionen Rekord Projektion - Sie, dass an der docs, indem man sehen können.). Sie können hier verwenden, dass

P.TokenParser { P.parens  = parens 
       , P.braces  = braces 
       , P.identifier = identifier 
       , P.reserved = reserved 
       } = P.makeTokenParser haskellDef 

EDIT

Wie ErikR hervorgehoben hat, es Sie nicht nur der Parser einige wollen, aber Sie wollen, dass alle 29 der GenTokenParser Felder gebracht in globalen Bereich können Sie die RecordWildCards Erweiterung aktivieren und nur

P.TokenParser {..} = P.makeTokenParser haskellDef 
+2

schreiben Wenn Sie ermöglichen 'RecordWildCards', können Sie einfach' P.TokenParser verwenden {..} = lexer' auf der obersten Ebene alle Datensatzfelder zu definieren. – ErikR