1
1
import gleeunit/should
2
2
import parz . { run }
3
- import parz/combinators . { label_error , left , map , separator1 , sequence }
3
+ import parz/combinators . {
4
+ choice , label_error , left , map , separator1 , sequence , try_map ,
5
+ }
4
6
import parz/parsers . { letters , regex , str }
5
7
import parz/types . { ParserState }
6
8
7
9
type Kind {
8
10
StringKind
9
11
BooleanKind
10
12
NumberKind
11
- UnknownKind
12
13
}
13
14
14
15
type Identifier {
15
16
Identifier ( name : String )
16
17
}
17
18
18
19
type Node {
19
- UnknownNode
20
20
Node ( name : Identifier , kind : Kind )
21
21
}
22
22
23
23
type NodePart {
24
- K ( kind : Kind )
25
- I ( identifier : Identifier )
24
+ NodeKind ( kind : Kind )
25
+ NodeIdentifier ( identifier : Identifier )
26
26
}
27
27
28
- type AST {
29
- AST ( List ( Node ) )
28
+ type Ast {
29
+ Ast ( List ( Node ) )
30
30
}
31
31
32
32
const input = "name:string;
@@ -36,35 +36,31 @@ active:boolean;"
36
36
const custom_error = "Expected : but found something else"
37
37
38
38
fn parser ( ) {
39
- let name =
40
- left ( letters ( ) , str ( ":" ) |> label_error ( custom_error ) )
39
+ let identifier =
40
+ letters ( )
41
41
|> map ( Identifier )
42
- |> map ( I )
43
42
44
- let kind =
45
- left ( letters ( ) , str ( ";" ) )
46
- |> map ( fn ( ok ) {
47
- case ok {
48
- "string" -> StringKind
49
- "number" -> NumberKind
50
- "boolean" -> BooleanKind
51
- _ -> UnknownKind
52
- }
53
- } )
54
- |> map ( K )
43
+ let string_kind = str ( "string" ) |> map ( fn ( _ ) { StringKind } )
44
+ let number_kind = str ( "number" ) |> map ( fn ( _ ) { NumberKind } )
45
+ let boolean_kind = str ( "boolean" ) |> map ( fn ( _ ) { BooleanKind } )
55
46
47
+ let kind = choice ( [ string_kind , number_kind , boolean_kind ] )
56
48
let node =
57
- sequence ( [ name , kind ] )
58
- |> map ( fn ( ok ) {
49
+ sequence ( [
50
+ left ( identifier , str ( ":" ) |> label_error ( custom_error ) )
51
+ |> map ( NodeIdentifier ) ,
52
+ left ( kind , str ( ";" ) ) |> map ( NodeKind ) ,
53
+ ] )
54
+ |> try_map ( fn ( ok ) {
59
55
case ok {
60
- [ I ( i ) , K ( k ) ] -> Node ( i , k )
61
- _ -> UnknownNode
56
+ [ NodeIdentifier ( i ) , NodeKind ( k ) ] -> Ok ( Node ( i , k ) )
57
+ _ -> Error ( "Failed to match identifier:kind" )
62
58
}
63
59
} )
64
60
65
61
let whitespace = regex ( "\\ s*" )
66
62
67
- let parser = separator1 ( node , whitespace ) |> map ( AST )
63
+ let parser = separator1 ( node , whitespace ) |> map ( Ast )
68
64
69
65
parser
70
66
}
@@ -73,7 +69,7 @@ pub fn simple_parser_test() {
73
69
run ( parser ( ) , input )
74
70
|> should . be_ok
75
71
|> should . equal ( ParserState (
76
- AST ( [
72
+ Ast ( [
77
73
Node ( Identifier ( "name" ) , StringKind ) ,
78
74
Node ( Identifier ( "age" ) , NumberKind ) ,
79
75
Node ( Identifier ( "active" ) , BooleanKind ) ,
0 commit comments