Skip to content

Commit 429a322

Browse files
committed
wildcard parser
1 parent 59af646 commit 429a322

File tree

4 files changed

+133
-107
lines changed

4 files changed

+133
-107
lines changed

src/ZM/Parser/Exp.hs

Lines changed: 63 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ module ZM.Parser.Exp where
1414
import Data.Bifunctor
1515
import Data.Text (Text)
1616
import qualified Data.Text as T
17-
import qualified Data.Text.IO as T
17+
18+
-- import qualified Data.Text.IO as T
1819
import Prettyprinter
1920
import Text.Megaparsec
2021
import ZM.Parser.Bracket (Bracket, bracket, prettyBracket)
@@ -24,6 +25,8 @@ import ZM.Parser.Op
2425
import ZM.Parser.Types
2526
import ZM.Parser.Util
2627

28+
-- import ZM.Parser (ADTParts(name))
29+
2730
{- $setup
2831
>>> pr = parseMaybe (doc expr)
2932
>>> p = fmap pretty . pr
@@ -197,29 +200,18 @@ Just (F (InfixApp (F (Lit (LInteger 1))) "+" (F (InfixApp (F (Lit (LInteger 2)))
197200

198201
{-
199202
>>> tt "rec"
203+
204+
>>> tt "parser"
200205
-}
201-
tt mdlName = loadMdl $ concat ["../qq/qq-src/", mdlName, ".qq"]
202-
203-
loadMdl :: FilePath -> IO ()
204-
loadMdl fileName = do
205-
src <- T.readFile fileName
206-
case testPretty src of
207-
Left "no parse" -> parseTest mdl src
208-
Left m -> putStr m
209-
Right src2 -> T.writeFile fileName src2
210-
211-
testPretty :: Text -> Either String Text
212-
testPretty src =
213-
case parseMdl src of
214-
Left e -> Left e
215-
Right syntax ->
216-
let src2 = show . pretty . unAnn $ syntax
217-
syntax1 = unAnn syntax
218-
in case parseMdlF $ T.pack src2 of
219-
Left e -> Left e
220-
Right syntax2
221-
| syntax1 == syntax2 -> Right $ T.pack src2
222-
| otherwise -> Left (unlines ["bad pretty: ", src2, "semantic was", show syntax1, T.unpack src, "now is", show syntax2, src2])
206+
-- tt mdlName = loadMdl $ concat ["../qq/qq-src/", mdlName, ".qq"]
207+
208+
-- loadMdl :: FilePath -> IO ()
209+
-- loadMdl fileName = do
210+
-- src <- T.readFile fileName
211+
-- case testPretty src of
212+
-- Left "no parse" -> parseTest mdl src
213+
-- Left m -> putStr m
214+
-- Right src2 -> T.writeFile fileName src2
223215

224216
parseMdl :: T.Text -> Either String Exp
225217
parseMdl = first errorBundlePretty . runParser mdl ""
@@ -295,12 +287,16 @@ simple =
295287
, pre
296288
, con
297289
, lit
290+
, wld
298291
]
299292

300293
par :: Parser Exp
301294
-- par = located $ Par <$> parenthesis expr
302295
par = parenthesis expr
303296

297+
wld :: Parser Exp
298+
wld = located $ Wild <$> wild
299+
304300
pre :: Parser Exp
305301
pre = located $ Prefix <$> prefixOp
306302

@@ -320,15 +316,18 @@ lit = located $ Lit <$> literal
320316
-- type Expr = Fix ExpR
321317
data ExpR r
322318
= App r r
323-
| InfixApp r Text r
324-
| -- Universal App: App+Infix App + Section
319+
| -- Universal App: App+Infix App + Section (What about functions with a single arg?)
325320

326321
-- | App Text (These r r)
327-
Con Text -- Constructor (e.g. "True")
328-
| Prefix Text
329-
| -- | Infix Text
330-
Field Text
331-
| -- | Par r
322+
-- ?Or App r (These r r)
323+
Prefix Text
324+
| InfixApp r Text r
325+
| Wild Text -- Wildcard (without initial _)
326+
| Con Text -- Constructor (e.g. "True")
327+
| -- \| Par r
328+
329+
-- | Infix Text
330+
-- Field Text
332331
Arr (Bracket r)
333332
| Lit Literal
334333
deriving (Show, Eq, Functor)
@@ -350,7 +349,21 @@ data Arg = NoArg | PreArg | InfArg deriving (Show, Eq)
350349
>>> sup "foo bar + big bop"
351350
Just foo bar + big bop
352351
352+
>>> pr "x = y"
353+
Just (Ann 0 (InfixApp (Ann 0 (Prefix "x")) "=" (Ann 4 (Prefix "y"))))
354+
355+
>>> sup "[[]]"
356+
Just [
357+
[
358+
]
359+
]
360+
361+
>>> sup "Z -> y -> y"
362+
Just Z -> (y -> y)
363+
353364
>>> tt "rec"
365+
366+
>>> tt "add"
354367
-}
355368
instance (PrettyArg r) => PrettyArg (ExpR r) where
356369
prettyArg arg =
@@ -370,29 +383,25 @@ instance (PrettyArg r) => PrettyArg (ExpR r) where
370383
Con name -> pretty name
371384
Arr brk -> prettyBracket no brk
372385
Prefix name -> pretty name
373-
Field name -> pretty name
386+
Wild name -> "_" <> pretty name
387+
-- Field name -> pretty name
374388
Lit l -> pretty l
375389

376-
-- onArg PreArg d = "(" <> d <> ")"
377-
-- onArf InfArg d = d
378-
379-
-- prettyArg :: Pretty r => ExpR r -> Doc ann
380-
-- prettyArg_ e
381-
-- | isSimple e = pretty e
382-
-- | otherwise = "(" <> pretty e <> ")"
383-
384-
-- isSimple :: ExpR r -> Bool
385-
-- isSimple (App _ _) = False
386-
-- isSimple (InfixApp{}) = False
387-
-- isSimple _ = True
388-
389-
-- instance (Pretty (f (Annotate () f))) => Pretty (Annotate () f) where
390-
-- pPrint (Ann () f) = pPrint f
391-
392-
-- instance (Pretty r) => Pretty (ExpR r) where
393-
-- pPrint (App f a) = chr '(' <> hsep [pPrint f, pPrint a] <> chr ')'
394-
-- pPrint (Con name) = txt name
395-
-- pPrint (Prefix name) = txt name
396-
-- pPrint (Infix name) = txt name
397-
-- pPrint (Arr brk) = pPrint brk
398-
-- pPrint (Lit l) = pPrint l
390+
{-
391+
pat => lpat qconop pat (infix constructor)
392+
| lpat
393+
394+
lpat => apat | - (integer | float) (negative literal) | gcon apat1 ... apatk (arity gcon = k, k >= 1)
395+
396+
apat => var [ @ apat] (as pattern)
397+
| gcon (arity gcon = 0)
398+
| qcon { fpat1 ... fpatk } (labeled pattern, k >= 0)
399+
| literal
400+
| _ (wildcard)
401+
| ( pat ) (parenthesized pattern)
402+
| ( pat1 ... patk ) (tuple pattern, k >= 2)
403+
| [ pat1 ... patk ] (list pattern, k >= 1)
404+
| ˜ apat (irrefutable pattern)
405+
406+
fpat => qvar = pat
407+
-}

src/ZM/Parser/Lexer.hs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module ZM.Parser.Lexer (
1313
eof,
1414
lexeme,
1515
-- $lexemes
16-
var,
16+
wild,
1717
identifier,
1818
sym,
1919
constr,
@@ -26,6 +26,7 @@ module ZM.Parser.Lexer (
2626
-- import Data.Word
2727

2828
import Data.Char as C
29+
import Data.Maybe
2930
import Data.Text (Text, pack)
3031
import qualified Data.Text as T
3132
import Text.Megaparsec hiding (Label)
@@ -107,7 +108,6 @@ lineEnd =
107108
-- setOffset o
108109
-- fail msg
109110

110-
111111
localId :: Parser Text
112112
localId = lexeme name
113113

@@ -181,21 +181,28 @@ symChar =
181181
<?> "sym"
182182
{-# INLINE symChar #-}
183183

184-
{- |
185-
>>> parseMaybe var "是不是"
186-
Nothing
184+
{-
185+
>>> let p = parseMaybe wild
187186
188-
>>> parseMaybe var "_"
189-
Just Nothing
187+
>>> p "_"
188+
Just ""
190189
191-
>>> parseMaybe var "_a"
192-
Just (Just "a")
190+
>>> p "__"
191+
Just "_"
193192
194-
>>> parseMaybe var "_是不是"
195-
Just (Just "\26159\19981\26159")
193+
>>> p "___"
194+
Just "__"
195+
196+
>>> p "_a"
197+
Just "a"
198+
199+
>>> p "_是不是"
200+
Nothing
196201
-}
197-
var :: Parser (Maybe Text)
198-
var = lexeme (char '_' *> optional name)
202+
wild :: Parser Text
203+
wild = lexeme $ T.tail <$> wld
204+
where
205+
wld = T.cons <$> char '_' <*> (fromMaybe T.empty <$> optional (name <|> wld))
199206

200207
{- |
201208
Parse a specific string

src/ZM/Parser/Op.hs

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,69 +6,78 @@ module ZM.Parser.Op (
66
) where
77

88
import Data.Char as C
9-
import Data.Text (Text, pack)
9+
import Data.Text (Text)
1010
import qualified Data.Text as T
1111
import Text.Megaparsec
12-
import Text.Megaparsec hiding (Label)
1312
import Text.Megaparsec.Char
1413
import ZM.Parser.Lexer
1514
import ZM.Parser.Types
1615

16+
-- TODO: test that the different syntactical classes (infix,prefix,wild) are mutually exclusive
17+
1718
{- |
1819
Parse a ZM prefixOp (a unicode letter followed by zero or more unicode alphanumeric characters or '_')
1920
20-
>>> parseMaybe prefixOp "*"
21+
>>> let p = parseMaybe prefixOp
22+
23+
>>> p "*"
2124
Nothing
2225
23-
>>> parseMaybe prefixOp "1"
26+
>>> p "1"
2427
Nothing
2528
26-
>>> parseMaybe prefixOp "A"
27-
Just "A"
29+
>>> p "A"
30+
Nothing
2831
29-
>>> parseMaybe prefixOp "Gold金en"
30-
Just "Gold\37329en"
32+
NOTE: no support for non-ascii characters
3133
32-
>>> parseMaybe prefixOp "是不是"
33-
Just "\26159\19981\26159"
34+
>>> p "Gold金en"
35+
Nothing
3436
35-
>>> parseMaybe prefixOp "Bool -- a bool"
36-
Just "Bool"
37+
>>> p "是不是"
38+
Nothing
3739
38-
>>> parseMaybe prefixOp "ant_13_"
40+
>>> p "Bool -- a bool"
41+
Nothing
42+
43+
>>> p "ant_13_"
3944
Just "ant_13_"
45+
46+
>>> p "abc12"
47+
Just "abc12"
48+
49+
>>> p "abc1*"
50+
Nothing
51+
52+
>>> Nothing == p "True"
53+
True
54+
55+
>>> Nothing == p "_"
56+
True
4057
-}
4158

4259
-- TODO: add (+) `add`
4360

4461
prefixOp :: Parser Text
45-
prefixOp = lexeme name
62+
prefixOp = lexeme var
4663

47-
{-
48-
>>> parseMaybe (infixOp >> char '}') "*}"
49-
Just '}'
50-
-}
51-
infixOp :: Parser Text
52-
infixOp = lexeme sym
64+
var :: Parser Text
65+
var = T.cons <$> lowerChar <*> takeWhileP (Just "alpha numeric or _") (\c -> isAlphaNum c || c == '_')
5366

5467
{-
68+
>>> parseMaybe infixOp "++"
69+
Just "++"
5570
56-
FIX THIS?
57-
58-
>>> parseMaybe name "_asd"
59-
Nothing
60-
61-
>>> parseMaybe name "abc12"
62-
Just "abc12"
71+
>>> parseMaybe infixOp "_"
72+
Just "_"
6373
64-
>>> parseMaybe name "abc1*"
74+
>>> parseMaybe infixOp "_xyz"
6575
Nothing
6676
67-
>>> Nothing == parseMaybe name "True"
68-
True
69-
70-
>>> Nothing == parseMaybe name "_"
71-
True
77+
>>> parseMaybe (infixOp >> char '}') "*}"
78+
Just '}'
7279
-}
73-
name :: Parser Text
74-
name = T.cons <$> lowerChar <*> takeWhileP (Just "alpha numeric or _") (\c -> isAlphaNum c || c == '_')
80+
infixOp :: Parser Text
81+
infixOp = lexeme sym
82+
83+
-- wild = char '_' >> return PWild

src/ZM/Parser/Value.hs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ module ZM.Parser.Value (
44
value,
55
pattern,
66
Value,
7-
Pattern
7+
Pattern,
88
)
99
where
1010

1111
import Data.Text (Text)
12+
import qualified Data.Text as T
1213
import Text.Megaparsec
13-
import ZM.Parser.Lexer hiding (constr)
14+
import ZM.Parser.Lexer ( localId, symbol, wild )
1415
import ZM.Parser.Literal
1516
import ZM.Parser.Types
1617
import ZM.Parser.Util
@@ -127,7 +128,9 @@ special =
127128

128129
-- TODO: Add VArray
129130
binds :: Parser (Val lit Binder)
130-
binds = maybe PWild PBind <$> var
131+
-- binds = maybe PWild PBind <$> wild
132+
-- ???
133+
binds = (\w -> if T.null w then PWild else PBind w) <$> wild
131134

132135
nestedValue :: Parser (Val lit binder) -> Parser (Val lit binder)
133136
nestedValue v =
@@ -137,12 +140,10 @@ fieldsV
137140
, unnamedFields ::
138141
Parser (Val lit binder) ->
139142
Parser (Either [Val lit binder] [(Text, Val lit binder)])
140-
141143
-- fields :: Parser ValueFields
142144
fieldsV v = namedFields v <|> unnamedFields v
143145

144146
-- | Parse unnamed fields
145-
146147
unnamedFields v = Left <$> many (nestedValue v)
147148

148149
{- | Parse a set of named fields

0 commit comments

Comments
 (0)