Skip to content

Commit 99cbe38

Browse files
author
Alex Gryzlov
committed
examples and fixes
1 parent dde7d28 commit 99cbe38

File tree

1 file changed

+31
-93
lines changed

1 file changed

+31
-93
lines changed

src/ImpParser.lidr

Lines changed: 31 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
The development of the Imp language in `Imp.lidr` completely ignores issues of
77
concrete syntax -- how an ascii string that a programmer might write gets
8-
translated into abstract syntax trees defined by the datatypes `aexp`, `bexp`,
9-
and `com`. In this chapter, we illustrate how the rest of the story can be
10-
filled in by building a simple lexical analyzer and parser using Idris's
11-
functional programming facilities.
8+
translated into abstract syntax trees defined by the datatypes \idr{AExp},
9+
\idr{BExp}, and \idr{Com}. In this chapter, we illustrate how the rest of the
10+
story can be filled in by building a simple lexical analyzer and parser using
11+
Idris's functional programming facilities.
1212

1313
It is not important to understand all the details here (and accordingly, the
1414
explanations are fairly terse and there are no exercises). The main point is
@@ -26,9 +26,6 @@ very end to get the punchline.
2626

2727
=== Lexical Analysis
2828

29-
> isLowerAlpha : (c : Char) -> Bool
30-
> isLowerAlpha c = isLower c || isDigit c
31-
>
3229
> data Chartype = White | Alpha | Digit | Other
3330
>
3431
> classifyChar : (c : Char) -> Chartype
@@ -100,10 +97,9 @@ more convenient.
10097
>
10198
> Applicative OptionE where
10299
> pure = SomeE
103-
> (SomeE f) <*> (SomeE x) = SomeE (f x)
104-
> (SomeE _) <*> (NoneE e2) = NoneE e2
105-
> (NoneE e1) <*> (SomeE _) = NoneE e1
106-
> (NoneE e1) <*> (NoneE e2) = NoneE (e1 ++ ";" ++ e2)
100+
> (SomeE f) <*> (SomeE x) = SomeE (f x)
101+
> (SomeE _) <*> (NoneE e) = NoneE e
102+
> (NoneE e) <*> _ = NoneE e
107103
>
108104
> Alternative OptionE where
109105
> empty = NoneE ""
@@ -145,14 +141,15 @@ A parser that expects a particular token:
145141
> expect : (t : Token) -> Parser ()
146142
> expect t = firstExpect t (\xs => SomeE ((), xs))
147143
>
144+
148145
==== A Recursive-Descent Parser for Imp
149146

150147
Identifiers:
151148

152149
> parseIdentifier : Parser Id
153150
> parseIdentifier [] = NoneE "Expected identifier"
154151
> parseIdentifier (x::xs) =
155-
> if all isLowerAlpha (unpack x)
152+
> if all isLower (unpack x)
156153
> then SomeE (MkId x, xs)
157154
> else NoneE ("Illegal identifier:'" ++ x ++ "'")
158155
>
@@ -306,85 +303,26 @@ Parsing commands:
306303

307304
== Examples
308305

309-
```coq
310-
(*
311-
Compute parse "
312-
IF x == y + 1 + 2 - y * 6 + 3 THEN
313-
x := x * 1;;
314-
y := 0
315-
ELSE
316-
SKIP
317-
END ".
318-
====>
319-
SomeE
320-
(IFB BEq (AId (Id 0))
321-
(APlus
322-
(AMinus (APlus (APlus (AId (Id 1)) (ANum 1)) (ANum 2))
323-
(AMult (AId (Id 1)) (ANum 6)))
324-
(ANum 3))
325-
THEN Id 0 ::= AMult (AId (Id 0)) (ANum 1);; Id 1 ::= ANum 0
326-
ELSE SKIP FI, [])
327-
*)
328-
329-
(*
330-
Compute parse "
331-
SKIP;;
332-
z:=x*y*(x*x);;
333-
WHILE x==x DO
334-
IF z <= z*z && not x == 2 THEN
335-
x := z;;
336-
y := z
337-
ELSE
338-
SKIP
339-
END;;
340-
SKIP
341-
END;;
342-
x:=z ".
343-
====>
344-
SomeE
345-
(SKIP;;
346-
Id 0 ::= AMult (AMult (AId (Id 1)) (AId (Id 2)))
347-
(AMult (AId (Id 1)) (AId (Id 1)));;
348-
WHILE BEq (AId (Id 1)) (AId (Id 1)) DO
349-
IFB BAnd (BLe (AId (Id 0)) (AMult (AId (Id 0)) (AId (Id 0))))
350-
(BNot (BEq (AId (Id 1)) (ANum 2)))
351-
THEN Id 1 ::= AId (Id 0);; Id 2 ::= AId (Id 0)
352-
ELSE SKIP FI;;
353-
SKIP
354-
END;;
355-
Id 1 ::= AId (Id 0),
356-
[])
357-
*)
358-
359-
(*
360-
Compute parse "
361-
SKIP;;
362-
z:=x*y*(x*x);;
363-
WHILE x==x DO
364-
IF z <= z*z && not x == 2 THEN
365-
x := z;;
366-
y := z
367-
ELSE
368-
SKIP
369-
END;;
370-
SKIP
371-
END;;
372-
x:=z ".
373-
=====>
374-
SomeE
375-
(SKIP;;
376-
Id 0 ::= AMult (AMult (AId (Id 1)) (AId (Id 2)))
377-
(AMult (AId (Id 1)) (AId (Id 1)));;
378-
WHILE BEq (AId (Id 1)) (AId (Id 1)) DO
379-
IFB BAnd (BLe (AId (Id 0)) (AMult (AId (Id 0)) (AId (Id 0))))
380-
(BNot (BEq (AId (Id 1)) (ANum 2)))
381-
THEN Id 1 ::= AId (Id 0);;
382-
Id 2 ::= AId (Id 0)
383-
ELSE SKIP
384-
FI;;
385-
SKIP
386-
END;;
387-
Id 1 ::= AId (Id 0),
388-
[]).
389-
*)
306+
```idris
307+
λΠ> parse "IF x == y + 1 + 2 - y * 6 + 3 THEN x := x * 1;; y := 0 ELSE SKIP END"
308+
SomeE (CIf (BEq (AId (MkId "x")) (APlus (AMinus (APlus (APlus (AId (MkId "y")) (ANum 1)) (ANum 2)) (AMult (AId (MkId "y")) (ANum 6))) (ANum 3)))
309+
(CSeq (CAss (MkId "x") (AMult (AId (MkId "x")) (ANum 1))) (CAss (MkId "y") (ANum 0)))
310+
CSkip,
311+
[]) : OptionE (Com, List String)
312+
313+
λΠ> parse "SKIP;; z:=x*y*(x*x);; WHILE x==x DO IF z <= z*z && not x == 2 THEN x := z;; y := z ELSE SKIP END;; SKIP END;; x:=z"
314+
```
315+
316+
\todo[inline]{This one is repeated twice in the book for some reason}
317+
318+
```idris
319+
SomeE (CSeq CSkip
320+
(CSeq (CAss (MkId "z") (AMult (AMult (AId (MkId "x")) (AId (MkId "y"))) (AMult (AId (MkId "x")) (AId (MkId "x")))))
321+
(CSeq (CWhile (BEq (AId (MkId "x")) (AId (MkId "x")))
322+
(CSeq (CIf (BAnd (BLe (AId (MkId "z")) (AMult (AId (MkId "z")) (AId (MkId "z")))) (BNot (BEq (AId (MkId "x")) (ANum 2))))
323+
(CSeq (CAss (MkId "x") (AId (MkId "z"))) (CAss (MkId "y") (AId (MkId "z"))))
324+
CSkip)
325+
CSkip))
326+
(CAss (MkId "x") (AId (MkId "z"))))),
327+
[]) : OptionE (Com, List String)
390328
```

0 commit comments

Comments
 (0)