1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Transformation of regular expression to NFA
22 # Build the NFA of the regular expression
23 fun make_nfa
: Automaton do
28 # The real value of the string
36 redef fun value
do return text
.substring
(1, text
.length-2
).unescape_nit
39 var a
= new Automaton.epsilon
40 for c
in self.value
.chars
do
41 var b
= new Automaton.atom
(c
.code_point
)
49 redef fun value
do return text
.substring_from
(1).to_i
.code_point
.to_s
52 var a
= new Automaton.atom
(self.value
.chars
.first
.code_point
)
58 redef fun value
do return text
.substring_from
(2).to_hex
.code_point
.to_s
61 var a
= new Automaton.atom
(self.value
.chars
.first
.code_point
)
69 assert children
.length
== 1 else print
"no make_nfa for {self}"
70 return children
.first
.make_nfa
77 var a
= children
[0].make_nfa
78 var b
= children
[2].make_nfa
87 var a
= children
[0].make_nfa
88 var b
= children
[2].make_nfa
.to_dfa
89 for t
in b
.start
.outs
do
90 if not t
.to
.outs
.is_empty
then
91 # `b` is not a single char, so just use except
92 # "a - b == a Except (Any* b Any*)"
93 var any1
= new Automaton.cla
(0, null)
95 var any2
= new Automaton.cla
(0, null)
103 a
.minus_sym
(t
.symbol
.as(not null))
112 print
"{children.first.position.to_s}: NOT YET IMPLEMENTED: token `End`; replaced with an empty string"
113 return new Automaton.epsilon
120 var a
= children
[0].make_nfa
121 var ta
= new Token("1")
123 var b
= children
[2].make_nfa
124 var tb
= new Token("2")
127 var c
= new Automaton.empty
132 for s
in c
.retrotags
[ta
] do
133 if c
.tags
[s
].has
(tb
) then
143 redef class Nre_except
146 var a
= children
[0].make_nfa
147 var b
= children
[2].make_nfa
152 redef class Nre_shortest
155 var a
= children
[2].make_nfa
158 for t
in s
.outs
.to_a
do t
.delete
164 redef class Nre_longest
167 var a
= children
[2].make_nfa
169 for s
in a
.accept
.to_a
do
170 if not s
.outs
.is_empty
then a
.accept
.remove
(s
)
176 redef class Nre_prefixes
179 var a
= children
[2].make_nfa
181 a
.accept
.add_all a
.states
189 var a
= children
[0].make_nfa
190 var b
= children
[1].make_nfa
199 var a
= children
[0].make_nfa
208 var a
= children
[0].make_nfa
217 var a
= children
[0].make_nfa
226 return children
[1].make_nfa
230 redef class Nre_class
233 var c1
= children
[0].children
[0].value
234 var c2
= children
[3].children
[0].value
235 if c1
.length
!= 1 or c2
.length
!= 1 then
236 print
"Classes expect a single char"
240 var a
= new Automaton.cla
(c1
.chars
.first
.code_point
, c2
.chars
.first
.code_point
)
245 redef class Nre_openclass
248 var c1
= children
[0].children
[0].value
249 if c1
.length
!= 1 then
250 print
"Classes expect a single char"
254 var a
= new Automaton.cla
(c1
.chars
.first
.code_point
, null)
262 var a
= new Automaton.cla
(0, null)