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.
18 import re_parser_lexer
19 import re_parser_parser
21 # Parse regular expression into NFA
24 # # Parse the regular expression
26 # var re_parser = new REParser
27 # var node = re_parser.parse_re(re)
29 # # Check syntax errors
30 # assert node != null else
31 # print re_parser.last_error.as(not null)
35 # var nfa = re_parser.make_nfa(node)
37 # print nfa.to_dfa.to_dot
41 # Parse the regular expression `re` and return the root production node.
43 # Returns `null` in case of syntax error. See `last_error`.
46 # var re_parser = new REParser
48 # # Valid regular expression
49 # assert re_parser.parse_re("(a|b)*") != null
50 # assert re_parser.last_error == null
52 # # Invalid regular expression
53 # assert re_parser.parse_re("a|b)*") == null
54 # assert re_parser.last_error != null
56 fun parse_re
(re
: String): nullable NProd do
57 var l
= new Lexer_re_parser(re
)
60 var p
= new Parser_re_parser
65 if not node
isa NProd then
66 if node
isa NError then
67 last_error
= "{node.position.as(not null).to_s} Syntax Error: {node.message}"
69 last_error
= "Parsing Error: expected `NProd` got `{node.class_name}`"
77 # Contains the error from the last call to `parse_re` or null if no error
80 # var re_parser = new REParser
82 # # Invalid regular expression
83 # assert re_parser.parse_re("a|b)*") == null
84 # assert re_parser.last_error != null
86 var last_error
: nullable String
88 # Build the NFA for `node`
90 # Use `parse_re` to transform a re string into a NProd.
91 fun make_nfa
(node
: NProd): Automaton do
101 var nfa
= new Automaton
103 fun start
(n
: Node) do
107 redef fun visit
(n
) do n
.accept_revisitor
(self)
111 fun accept_revisitor
(v
: REVisitor) do visit_children
(v
)
113 # Build the NFA of the regular expression
114 fun make_nfa
: Automaton do
121 redef fun accept_revisitor
(v
) do
125 redef fun make_nfa
do
126 var a
= new Automaton
127 for child
in children
do
128 if child
== null then continue
129 a
.concat
(child
.make_nfa
)
136 redef fun make_nfa
do
137 return new Automaton.atom
(n_char
.text
.chars
.first
.code_point
)
141 redef class Nre_alter
144 var a
= n_re
.make_nfa
145 var b
= n_re2
.make_nfa
154 var a
= n_re
.make_nfa
155 var b
= n_re2
.make_nfa
164 var a
= n_re
.make_nfa
173 var a
= n_re
.make_nfa
182 var a
= n_re
.make_nfa
196 if args
.is_empty
then
197 print
"usage: re_parser <re>"
203 var re_parser
= new REParser
204 var node
= re_parser
.parse_re
(re
)
207 print re_parser
.last_error
.as(not null)
213 var nfa
= re_parser
.make_nfa
(node
)
214 nfa
.to_dot
(false).write_to_file
("nfa.dot")
215 nfa
.to_dfa
.to_dot
(false).write_to_file
("dfa.dot")
216 print
"Produced files `nfa.dot` and `dfa.dot`"