parser stuff

This commit is contained in:
rhiannon morris 2022-05-08 20:03:05 +02:00
parent 8a955eebb3
commit 50a2ec02cb
2 changed files with 38 additions and 27 deletions

View file

@ -87,9 +87,23 @@ find _ _ = Nothing
export export
bound : (what : String) -> Vars k -> Grammar True (Var k) checkAvoid1 : Vars n -> String -> Grammar False ()
bound what vs = terminal "bound \{what} variable" $ checkAvoid1 avoid y =
\case Name x => find1 vs x; _ => Nothing when (isJust $ find1 avoid y) $
fail "wrong type of bound variable: \{show y}"
export
checkAvoid : Vars n -> Name -> Grammar False ()
checkAvoid avoid (MakeName [<] (UN y)) = checkAvoid1 avoid y
checkAvoid _ _ = pure ()
export
bound : (what : String) -> (bound : Vars k) -> (avoid : Vars n) ->
Grammar True (Var k)
bound what vs avoid = do
x <- terminal "bound \{what} variable" $ \case Name x => Just x; _ => Nothing
checkAvoid1 avoid x
maybe (fail "not in scope: \{x}") pure $ find1 vs x
export export
sname : Grammar True String sname : Grammar True String
@ -106,24 +120,23 @@ nameWith : (bound : Vars k) -> (avoid : Vars n) ->
Grammar True (Either (Var k) Name) Grammar True (Either (Var k) Name)
nameWith bound avoid = do nameWith bound avoid = do
y <- qname y <- qname
when (isJust $ find avoid y) $ checkAvoid avoid y
fail "wrong type of bound variable: \{show y}"
pure $ maybe (Right y) Left $ find bound y pure $ maybe (Right y) Left $ find bound y
export export
dimension : Vars d -> Grammar True (Dim d) dimension : (dvars : Vars d) -> (tvars : Vars n) -> Grammar True (Dim d)
dimension vs = dimension dvars tvars =
K Zero <$ zero K Zero <$ zero
<|> K One <$ one <|> K One <$ one
<|> B <$> bound "dimension" vs <|> B <$> bound "dimension" {bound = dvars, avoid = tvars}
mutual mutual
export export
term : (dvars : Vars d) -> (tvars : Vars n) -> Grammar True (Term d n) term : (dvars : Vars d) -> (tvars : Vars n) -> Grammar True (Term d n)
term dvars tvars = term dvars tvars =
E <$> squares (elim dvars tvars) E <$> squares (elim {dvars, tvars})
export export
elim : (dvars : Vars d) -> (tvars : Vars n) -> Grammar True (Elim d n) elim : (dvars : Vars d) -> (tvars : Vars n) -> Grammar True (Elim d n)

View file

@ -61,7 +61,7 @@ parameters {c : Bool} (grm : Grammar c a) (note : String) (input : String)
Left err => Left $ Parser err Left err => Left $ Parser err
rejectsNote : Show a => Test rejectsNote : Show a => Test
rejectsNote = test "\"\{input}\"\{note} (reject)" $ do rejectsNote = test "\"\{input}\"\{note} reject" $ do
case lexParseAll grm input of case lexParseAll grm input of
Left err => Right () Left err => Right ()
Right val => Left $ ShouldFail val Right val => Left $ ShouldFail val
@ -74,7 +74,6 @@ parameters {c : Bool} (grm : Grammar c a) (input : String)
rejects = rejectsNote grm "" input rejects = rejectsNote grm "" input
tests = "parser" :- [ tests = "parser" :- [
skip $
"numbers" :- "numbers" :-
let parses = parses number let parses = parses number
in [ in [
@ -83,20 +82,19 @@ tests = "parser" :- [
parses "1000" 1000 parses "1000" 1000
], ],
skip $ "bound vars (x, y, z | a ⊢)" :-
"bound vars (x, y, z ⊢)" :- let grm = bound "test" {bound = [< "x", "y", "z"], avoid = [< "a"]}
let grm = bound "test" [< "x", "y", "z"] parses = parses grm; rejects = rejects grm; rejectsNote = rejectsNote grm
parses = parses grm; rejects = rejects grm
in [ in [
parses "x" (V 2), parses "x" (V 2),
parses "y" (V 1), parses "y" (V 1),
parses "z" (V 0), parses "z" (V 0),
rejects "M.x", rejects "M.x",
rejects "x.a", rejects "x.a",
rejects "a" rejectsNote " (avoid)" "a",
rejectsNote " (not in scope)" "c"
], ],
skip $
"bound or free vars (x, y, z ⊢)" :- "bound or free vars (x, y, z ⊢)" :-
let parses = parses $ nameWith {bound = [< "x", "y", "z"], avoid = [<]} let parses = parses $ nameWith {bound = [< "x", "y", "z"], avoid = [<]}
in [ in [
@ -110,16 +108,16 @@ tests = "parser" :- [
parses "x.a" (Right (MakeName [< "x"] (UN "a"))) parses "x.a" (Right (MakeName [< "x"] (UN "a")))
], ],
skip $ "dimension (i, j | x, y, z ⊢)" :-
"dimension (x, y, z | · ⊢)" :- let grm = dimension {dvars = [< "i", "j"], tvars = [< "x", "y", "z"]}
let grm = dimension [< "x", "y", "z"] parses = parses grm; rejects = rejects grm; rejectsNote = rejectsNote grm
parses = parses grm; rejects = rejects grm
in [ in [
parses "0" (K Zero), parses "0" (K Zero),
parses "1" (K One), parses "1" (K One),
rejects "2", rejects "2",
parses "x" (B (V 2)), parses "i" (B (V 1)),
rejects "a" rejectsNote " (tvar)" "x",
rejectsNote " (not in scope)" "a"
], ],
"terms & elims (i, j | x, y, z ⊢)" :- "terms & elims (i, j | x, y, z ⊢)" :-