Merge: Nit Actor Model, with some examples
[nit.git] / contrib / re_parser / src / re_app.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
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
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 module re_app
16
17 import re_parser
18 import popcorn
19 import popcorn::pop_config
20
21 class REHandler
22 super Handler
23
24 redef fun get(req, res) do
25 res.html new RETemplate
26 end
27
28 redef fun post(req, res) do
29 # TODO Retrieve re from post body
30 var re = req.string_arg("re")
31
32 var tpl = new RETemplate
33
34 if re == null or re.is_empty then
35 tpl.error = "Error: empty regexp"
36 res.html tpl
37 return
38 end
39
40 tpl.re = re
41
42 # Parse re
43 var re_parser = new REParser
44 var node = re_parser.parse_re(re)
45
46 if node == null then
47 tpl.error = re_parser.last_error.as(not null)
48 res.html tpl
49 return
50 end
51
52 # Build nfa and dfa
53 var nfa = re_parser.make_nfa(node)
54 tpl.nfa = automaton_to_svg(nfa)
55 tpl.dfa = automaton_to_svg(nfa.to_dfa)
56
57 res.html tpl
58 end
59
60 private fun automaton_to_svg(automaton: Automaton): String do
61 automaton.to_dot(false).write_to_file "dot.tmp"
62 sys.system "dot -Tsvg -osvg.tmp dot.tmp"
63 var svg = "svg.tmp".to_path.read_all
64 sys.system "rm -f dot.tmp svg.tmp"
65 return svg
66 end
67 end
68
69 class RETemplate
70 super Template
71
72 var re = "a*(b|cd?)+"
73 var nfa: nullable String = null
74 var dfa: nullable String = null
75 var error: nullable String = null
76
77 redef fun rendering do
78 add """
79 <!DOCTYPE html>
80 <html lang="en">
81 <head>
82 <meta charset="utf-8" />
83 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
84 <meta name="viewport" content="width=device-width, initial-scale=1" />
85 <title>REParser</title>
86 <link rel="stylesheet"
87 href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
88 </head>
89 <body>
90 <div class="container">
91 <h1>Regular Expressions to NFA and DFA</h1>
92 <br><br>
93 <label for="re">Enter a regular expression:</label>
94 <form action="/" method="POST" class="input-group">
95 <input id="re" name="re" type="text" class="form-control" value="{{{re}}}">
96 <span class="input-group-btn">
97 <input type="submit" class="btn btn-default" value="Convert" />
98 </span>
99 </form>
100 <br><br>"""
101
102 var error = self.error
103 if error != null then
104 add """<p class="text-danger">{{{error}}}</p>"""
105 end
106
107 var nfa = self.nfa
108 if nfa != null then
109 add """
110 <h2>NFA</h2>
111 <div>{{{nfa}}}</div><br><br>"""
112 end
113
114 var dfa = self.dfa
115 if dfa != null then
116 add """
117 <h2>DFA</h2>
118 <div>{{{dfa}}}</div><br><br>"""
119 end
120
121 add """</div>
122 <div class="text-center text-muted">
123 <p>Powered by <a href="http://nitlanguage.org">nit</a>!</p>
124 </div>
125 </body>
126 </html>"""
127 end
128 end
129
130 var config = new AppConfig
131 config.parse_options(args)
132
133 var app = new App
134 app.use("/", new REHandler)
135 app.listen(config.app_host, config.app_port)