forked from codeon/cmlex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.sml
118 lines (95 loc) · 3.46 KB
/
parser.sml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
structure Parser
:> PARSER
=
struct
exception Error = Lexer.Error
open Syntax
type pos = int
fun identity x = x
fun lift x () = x
fun null () = []
structure Arg =
struct
type string = string
type int = int
type intlist = int list
type string = string
val ident = identity
type int = int
val number = identity
type numpairs = (int * int) list
val nil_numpairs = null
fun cons_numpairs (first, last, tail) = (first, last) :: tail
type charset = charset
val ident_charset = Svar
val number_charset = Ssymbol
val range_charset = Srange
val empty_charset = lift Sempty
val union_charset = Sunion
val intersect_charset = Sintersection
val diff_charset = Sdifference
val comp_charset = Scomplement
val any_charset = lift Sany
type charsets = charset list
val nil_charsets = null
val cons_charsets = op ::
type regexp = regexp
val ident_regexp = Var
val number_regexp = Symbol
val string_regexp = String
val any_regexp = lift Any
val epsilon_regexp = lift Epsilon
val empty_regexp = lift Empty
val concat_regexp = Concat
val union_regexp = Union
val option_regexp = Optional
val closure_regexp = Closure
val plus_regexp = Plus
val equal_regexp = Exactly
val geq_regexp = AtLeast
val repeat_regexp = Repeat
val eos_regexp = lift Eos
type regexps = regexp list
val nil_regexps = null
val cons_regexps = op ::
type arm = regexp * string
val sole_arm = identity
type arms = arm list
fun sing_arms arm = [arm]
val cons_arms = op ::
type directive = directive
fun name_directive str = Option ("name", str)
val alphabet_directive = Alphabet
val regexp_directive = Regexp
val set_directive = Set
val function_directive = Function
type directives = directive list
val nil_directives = null
val cons_directives = op ::
datatype terminal = datatype Token.token
fun error s =
(case Stream.front s of
Stream.Nil =>
(
print "Syntax error at end of file.\n";
Error
)
| Stream.Cons ((_, pos), _) =>
(
print "Syntax error at ";
print (Int.toString pos);
print ".\n";
Error
))
end
structure StreamWithPos =
CoercedStreamable (structure Streamable = StreamStreamable
type 'a item = 'a * pos
fun coerce (x, _) = x)
structure ParseMain =
ParseMainFun
(structure Streamable = StreamWithPos
structure Arg = Arg)
fun parse s =
#1 (ParseMain.parse (Lexer.lex s))
end