1 {-# LANGUAGE ConstrainedClassMethods #-}
2 {-# LANGUAGE ConstraintKinds #-}
3 {-# LANGUAGE DataKinds #-}
4 {-# LANGUAGE DefaultSignatures #-}
5 {-# LANGUAGE DeriveFunctor #-}
6 {-# LANGUAGE FlexibleContexts #-}
7 {-# LANGUAGE FlexibleInstances #-}
8 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
9 {-# LANGUAGE LambdaCase #-}
10 {-# LANGUAGE MultiParamTypeClasses #-}
11 {-# LANGUAGE NamedFieldPuns #-}
12 {-# LANGUAGE NoMonomorphismRestriction #-}
13 {-# LANGUAGE OverloadedStrings #-}
14 {-# LANGUAGE PolyKinds #-}
15 {-# LANGUAGE Rank2Types #-}
16 {-# LANGUAGE StandaloneDeriving #-}
17 {-# LANGUAGE TypeFamilies #-}
18 {-# LANGUAGE TypeOperators #-}
19 {-# OPTIONS_GHC -fno-warn-tabs #-}
20 {-# OPTIONS_GHC -fno-warn-orphans #-}
21 -- | This module defines symantics
22 -- for regular or context-free grammars.
23 -- It is intended to be imported qualified.
24 module Parsing.Grammar.Test where
26 import Control.Applicative (Applicative(..), Alternative(..))
29 -- import Control.Comonad
30 import qualified Data.Char as Char
31 import Data.Foldable hiding (any)
32 import Data.Functor.Identity
33 import qualified Data.List as List
34 import Data.Semigroup ((<>))
36 import Data.Text (Text)
37 import Data.String (IsString(..))
38 import qualified Data.Text as Text
39 import qualified Data.Text.IO as Text
40 import Prelude hiding (any, (^))
41 import qualified Text.Megaparsec as P
42 import qualified Text.Megaparsec.Lexer as L
44 import qualified Language.Symantic.Compiling as Sym
45 import qualified Language.Symantic.Typing as Sym
46 import qualified Language.Symantic.Parsing as Sym
47 import Language.Symantic.Parsing.Grammar
50 type ParsecC e s = (P.Token s ~ Char, P.Stream s, P.ErrorComponent e)
51 instance ParsecC e s => IsString (P.ParsecT e s m [Char]) where
53 instance ParsecC e s => Gram_Rule (P.ParsecT e s m) where
54 rule = P.label . Text.unpack
55 instance ParsecC e s => Gram_Term (P.ParsecT e s m) where
60 unicat cat = P.satisfy $ (`List.elem` cats) . Char.generalCategory
61 where cats = unicode_categories cat
62 range (l, h) = P.satisfy $ \c -> l <= c && c <= h
63 instance ParsecC e s => Alter (P.ParsecT e s m) where
64 x <+> y = P.try x <|> y
65 instance ParsecC e s => Gram_RegR (P.ParsecT e s m) where
66 Term f .*> Reg x = Reg $ f <*> x
67 instance ParsecC e s => Gram_RegL (P.ParsecT e s m) where
68 Reg f <*. Term x = Reg $ f <*> x
69 instance ParsecC e s => App (P.ParsecT e s m)
70 instance ParsecC e s => Alt (P.ParsecT e s m)
71 instance ParsecC e s => Gram_CF (P.ParsecT e s m) where
72 CF f <& Reg p = CF $ P.lookAhead f <*> p
73 Reg f &> CF p = CF $ P.lookAhead f <*> p
74 but (CF f) (Reg p) = CF $ P.notFollowedBy (P.try p) *> f
75 instance ParsecC e s => Gram_Context (P.ParsecT e s m) where
76 type Context (P.ParsecT e s m) = P.SourcePos
77 context = (P.getPosition >>=)
78 instance ParsecC e s => Gram_Lexer (P.ParsecT e s m)
79 instance ParsecC e s => Sym.Gram_Type (P.ParsecT e s m)
82 => P.ParsecT P.Dec s m a -> s
83 -> m (Either (P.ParseError (P.Token s) P.Dec) a)
84 runParserT p = P.runParserT p ""
87 :: P.ParsecT P.Dec s Identity a -> s
88 -> Either (P.ParseError (P.Token s) P.Dec) a
89 runParser p = P.runParser p ""
95 g1 = (<>) <$> string "0" <*> string "1"
96 g2 = (<>) <$> string "0" <* string "X" <*> string "1"
97 g3 = (<>) <$> (string "0" <|> string "1") <*> string "2"
98 g4 = string "0" <|> string "1" <|> string "2"
99 g5 = choice [string "0", string "1", string "2"]
100 g6 = (<>) <$> choice [(<>) <$> string "0" <*> string "1", string "2" <|> string "3", string "4"] <*> string "5"
101 g7 = concat <$> many (string "0")
102 g8 = (concat <$>) $ (<>) <$> many (string "0" <|> string "1") <*> some (string "2")
103 g9 = (<>) <$> string "0" .*> someR (char '1')
104 g10 = (<>) <$> someL (char '1') <*. string "0"
105 g11 = string "0" `but` g9 `but` g10
106 g12 = (<>) <$> string "0" <& g9
107 g13 = string "abé\"to"
110 g16 = many $ unicat [Unicat_Letter]
111 g17 = many $ range ('a', 'z')
112 g18 = ("" <$) $ commentable (void g1) (void g2) (void g3)
113 g19 = ("" <$) $ choice [g5]
114 g20 = "" <$ char 'a' <* char 'b' <* char 'c'
115 g21 = "" <$ comment_line "--"
116 g22 = "" <$ lexeme (string "A")
124 [ g1, g2, g3, g4, g5, g6, g7, g8
125 , g11, g12, g13, g14, g15, g16, g17, g18
126 , g19, g20, g21, g22, cf_of_reg g23
128 Text.putStrLn $ runEBNF RuleMode_Def $ unCF g
131 [ "" <$ comment_line (rule_arg "prefix")
132 , "" <$ comment_block (rule_arg "start") (rule_arg "end" :: Reg 'L RuleDef String)
133 , "" <$ commentable (void $ rule_arg "space") (void $ rule_arg "line") (void $ rule_arg "block")
134 , "" <$ lexeme (rule_arg "p")
135 , "" <$ parens (rule_arg "p")
136 , "" <$ inside id (rule_arg "begin") (rule_arg "i") (rule_arg "end") (rule_arg "next")
137 , "" <$ infixrP const (rule_arg "next") (rule_arg "sep") (rule_arg "root")
148 Text.putStrLn $ runEBNF $ unRuleDef $ unCF g
158 , "((Bool, Int), Char)"
159 , "(Bool, Int) -> Char"
161 , "((Bool, Int), Char)"
169 , "(Bool -> Int) -> Char"
170 , "(Bool -> Int) Char"
171 , "Bool -> (Int -> Char)"
172 , "Bool -> Int -> Char"
174 putStr (show (s::Text))
176 print $ (compile_type <$>) $ runIdentity $ runParser (unCF (typeP <* eof)) s