Skip to content

Commit

Permalink
Merge branch 'bootstrup'
Browse files Browse the repository at this point in the history
  • Loading branch information
tanakh committed Sep 25, 2011
2 parents 61cc653 + 8d56d12 commit 4def43b
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 167 deletions.
9 changes: 4 additions & 5 deletions Main.hs
@@ -1,14 +1,13 @@
{-# Language TemplateHaskell, QuasiQuotes #-} {-# Language TemplateHaskell, QuasiQuotes, FlexibleContexts #-}
{-# Language FlexibleContexts #-}


module Main (main) where module Main (main) where


import Text.Peggy import Text.Peggy


genParser [("qqexpr", "top")] [peggy| genParser [] [peggy|
-- Simple Arithmetic Expression Parser -- Simple Arithmetic Expression Parser


top :: Double = expr !. top :: Double = expr


expr :: Double expr :: Double
= expr "+" fact { $1 + $2 } = expr "+" fact { $1 + $2 }
Expand All @@ -29,4 +28,4 @@ number ::: Double
|] |]


main :: IO () main :: IO ()
main = print . parse top (SrcPos "<stdin>" 0 1 1) =<< getContents main = print . parseString top "<stdin>" =<< getContents
420 changes: 270 additions & 150 deletions Text/Peggy/Parser.hs

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions Text/Peggy/Quote.hs
Expand Up @@ -9,10 +9,9 @@ module Text.Peggy.Quote (


import Language.Haskell.TH import Language.Haskell.TH
import Language.Haskell.TH.Quote import Language.Haskell.TH.Quote
import Text.Parsec
import Text.Parsec.Pos


import Text.Peggy.Parser import Text.Peggy.Parser
import Text.Peggy.Prim
import Text.Peggy.Syntax import Text.Peggy.Syntax
import Text.Peggy.SrcLoc import Text.Peggy.SrcLoc
import Text.Peggy.CodeGen.TH import Text.Peggy.CodeGen.TH
Expand All @@ -22,20 +21,20 @@ peggy = QuasiQuoter { quoteDec = qDecs, quoteExp = qExp, quotePat = undefined, q


peggyFile :: FilePath -> Q Exp peggyFile :: FilePath -> Q Exp
peggyFile filename = do peggyFile filename = do
txt <- runIO $ readFile filename res <- runIO $ parseFile syntax filename
case parse syntax filename txt of case res of
Left err -> error $ show err Left err -> error $ show err
Right syn -> dataToExpQ (const Nothing) syn Right syn -> dataToExpQ (const Nothing) syn


qDecs :: String -> Q [Dec] qDecs :: String -> Q [Dec]
qDecs txt = do qDecs txt = do
loc <- location loc <- location
genDecs $ parseSyntax (SrcPos (loc_filename loc) 0 (fst $ loc_start loc) (snd $ loc_start loc)) txt genDecs $ parseSyntax (locToPos loc) txt


qExp :: String -> Q Exp qExp :: String -> Q Exp
qExp txt = do qExp txt = do
loc <- location loc <- location
dataToExpQ (const Nothing) $ parseSyntax (SrcPos (loc_filename loc) 0 (fst $ loc_start loc) (snd $ loc_start loc)) txt dataToExpQ (const Nothing) $ parseSyntax (locToPos loc) txt


genParser :: [(String, String)] -> Syntax -> Q [Dec] genParser :: [(String, String)] -> Syntax -> Q [Dec]
genParser qqs syn = do genParser qqs syn = do
Expand All @@ -46,7 +45,11 @@ genParser qqs syn = do
-- --


parseSyntax :: SrcPos -> String -> Syntax parseSyntax :: SrcPos -> String -> Syntax
parseSyntax (SrcPos fname _ lno cno) txt = parseSyntax pos txt =
case parse (setPosition (newPos fname lno cno) >> syntax) fname txt of case parse syntax pos txt of
Left err -> error $ "peggy syntax-error: " ++ show err Left err -> error $ "peggy syntax-error: " ++ show err
Right defs -> defs Right defs -> defs

locToPos :: Loc -> SrcPos
locToPos loc =
SrcPos (loc_filename loc) 0 (fst $ loc_start loc) (snd $ loc_start loc)
8 changes: 4 additions & 4 deletions Text/Peggy/Syntax.hs
Expand Up @@ -17,7 +17,7 @@ type Syntax = [Definition]


data Definition data Definition
= Definition Identifier HaskellType Expr = Definition Identifier HaskellType Expr
deriving (Show, Typeable, Data) deriving (Show, Eq, Typeable, Data)


data Expr data Expr
= Terminals Bool Bool String = Terminals Bool Bool String
Expand All @@ -43,19 +43,19 @@ data Expr
| Token Expr | Token Expr


| Semantic Expr CodeFragment | Semantic Expr CodeFragment
deriving (Show, Typeable, Data) deriving (Show, Eq, Typeable, Data)


data CharRange data CharRange
= CharRange Char Char = CharRange Char Char
| CharOne Char | CharOne Char
deriving (Show, Typeable, Data) deriving (Show, Eq, Typeable, Data)


type CodeFragment = [CodePart] type CodeFragment = [CodePart]


data CodePart data CodePart
= Snippet String = Snippet String
| Argument Int | Argument Int
deriving (Show, Typeable, Data) deriving (Show, Eq, Typeable, Data)


type Identifier = String type Identifier = String
type HaskellType = String type HaskellType = String
39 changes: 39 additions & 0 deletions bootstrup/Bootstrup.hs
@@ -0,0 +1,39 @@
{-# Language TemplateHaskell, QuasiQuotes, FlexibleContexts #-}

import Data.Char
import Numeric
import Language.Haskell.TH
import Language.Haskell.Meta.Utils

import qualified Stage2

import Text.Peggy.Prim
import Text.Peggy.Quote
import Text.Peggy.CodeGen.TH
import Text.Peggy.Syntax
import Text.Peggy.SrcLoc

header :: String
header =
unlines
[ "{-# Language RankNTypes #-}"
, "{-# Language FlexibleContexts #-}"
, "module Text.Peggy.Parser (syntax) where"
, "import Control.Applicative"
, "import Data.ListLike.Base hiding (head)"
, "import Data.HashTable.ST.Basic"
, "import Numeric"
, "import Data.Char"
, "import Text.Peggy.Prim"
, "import Text.Peggy.Syntax"
]

main :: IO ()
main = do
res <- parseFile Stage2.syntax "peggy.peggy"
case res of
Left err -> error $ show err
Right defs -> do
code <- runQ $ genDecs defs
putStrLn header
putStrLn $ pp code
10 changes: 10 additions & 0 deletions bootstrup/README.md
@@ -0,0 +1,10 @@
# Bootstrup Instructions #

# Pre-requirement

Previous version of peggy (>= 0.1.1) required.

# Bootstrup

$ cd bootstrup
$ runhaskell Bootstrup.hs > ../Text/Peggy/Parser.hs
10 changes: 10 additions & 0 deletions bootstrup/Stage1.hs
@@ -0,0 +1,10 @@
{-# Language TemplateHaskell, QuasiQuotes, FlexibleContexts #-}

module Stage1 where

import Data.Char
import Language.Haskell.TH.Quote
import Numeric
import Text.Peggy

genParser [] $(peggyFile "peggy.peggy")
13 changes: 13 additions & 0 deletions bootstrup/Stage2.hs
@@ -0,0 +1,13 @@
{-# Language TemplateHaskell, QuasiQuotes, FlexibleContexts #-}

module Stage2 where

import qualified Stage1

import Data.Char
import Numeric
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Text.Peggy

genParser [] $(runIO (parseFile Stage1.syntax "peggy.peggy") >>= \res -> case res of Left err -> error $ show err; Right syn -> dataToExpQ (const Nothing) syn)
95 changes: 95 additions & 0 deletions bootstrup/peggy.peggy
@@ -0,0 +1,95 @@
-- A Parser for peggy itself.

syntax :: Syntax
= definition* !(skip* .)

definition ::: Definition
= ident ":::" haskellType "=" expr { Definition $1 $2 (Token $3) }
/ ident "::" haskellType "=" expr { Definition $1 $2 $3 }

expr :: Expr
= choiceExpr

choiceExpr :: Expr
= (semanticExpr, "/") { Choice $1 }

semanticExpr :: Expr
= sequenceExpr "{" codeFragment "}" { Semantic $1 $2 }
/ sequenceExpr

sequenceExpr :: Expr
= (suffixExpr !"::" !"=")+ { Sequence $1 }

suffixExpr :: Expr
= suffixExpr "*" { Many $1 }
/ suffixExpr "+" { Some $1 }
/ suffixExpr "?" { Optional $1 }
/ prefixExpr

prefixExpr :: Expr
= "&" primExpr { And $1 }
/ "!" primExpr { Not $1 }
/ primExpr

primExpr ::: Expr
= '\"' charLit* '\"' { Terminals True True $1 }
/ '\'' charLit* '\'' { Terminals False False $1 }
/ '[^' range* ']' { TerminalCmp $1 }
/ '[' range* ']' { TerminalSet $1 }
/ "." { TerminalAny }
/ ident { NonTerminal $1 }
/ "(" expr "," expr ")" { SepBy $1 $2 }
/ "(" expr ";" expr ")" { SepBy1 $1 $2 }
/ "(" expr ")"

charLit :: Char
= '\\' escChar
/ ![\'\"] .

escChar :: Char
= 'n' { '\n' }
/ 'r' { '\r' }
/ 't' { '\t' }
/ '\\' { '\\' }
/ '\"' { '\"' }
/ '\'' { '\'' }
/ 'x' hexDigit hexDigit { chr . fst . head . readHex $ [$1, $2] }

range :: CharRange
= rchar '-' rchar { CharRange $1 $2 }
/ rchar { CharOne $1 }

rchar :: Char
= '\\' escChar
/ '\\]' {']'} / '\\[' { '[' } / '\\^' { '^' } / '\\-' { '-' }
/ [^\]]

haskellType :: HaskellType
= [^=]+

codeFragment :: CodeFragment
= codePart*

codePart :: CodePart
= argument
/ (!'}' !argument .)+ { Snippet $1 }

argument :: CodePart
= '$' digit+ { Argument $ read $1 }

digit :: Char = [0-9]
hexDigit :: Char = [0-9a-fA-F]

ident ::: String = [a-zA-Z_] [0-9a-zA-Z_]* { $1 : $2 }

skip :: ()
= [ \r\n\t] { () } / comment

comment :: ()
= lineComment / regionComment

lineComment :: ()
= '--' (!'\n' .)* '\n' { () }

regionComment :: ()
= '{-' (regionComment / !'-}' . { () } )* '-}' { () }

0 comments on commit 4def43b

Please sign in to comment.