source: icGREP/icgrep-devel/icgrep/pbix_compiler.cpp @ 3994

Last change on this file since 3994 was 3994, checked in by cameron, 5 years ago

Delete old pablos_printer files, use printer_pablos instead

File size: 13.6 KB
Line 
1/*
2 *  Copyright (c) 2014 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include "pbix_compiler.h"
8#include "printer_pablos.h"
9
10Pbix_Compiler::Pbix_Compiler(std::map<std::string, std::string> name_map)
11{
12    m_name_map = name_map;
13    symgen = SymbolGenerator();
14}
15
16CodeGenState Pbix_Compiler::compile_subexpressions(const std::map<std::string, RE*>& re_map)
17{
18    CodeGenState cg_state;
19
20    for (auto it =  re_map.rbegin(); it != re_map.rend(); ++it)
21    {
22        //This is specifically for the utf8 multibyte character classes.
23        if (Seq* seq = dynamic_cast<Seq*>(it->second))
24        {
25            if (seq->getType() == Seq::Byte)
26            {
27                std::string gs_retVal = symgen.gensym("start_marker");
28                cg_state.stmtsl.push_back(new Assign(gs_retVal, new All(1)));
29                cg_state.newsym = gs_retVal;
30
31                std::list<RE*>::iterator endit;
32                endit = seq->GetREList()->end();
33                --endit;
34                std::list<RE*>::iterator it;
35                for (it = seq->GetREList()->begin(); it != seq->GetREList()->end(); ++it)
36                {
37                    Name* name = dynamic_cast<Name*>(*it);
38                    if (it != endit)
39                    {
40                        gs_retVal = symgen.gensym("marker");
41                        cg_state.stmtsl.push_back(new Assign(gs_retVal, new Advance(new And(new Var(cg_state.newsym), new CharClass(name->getName())))));
42                        cg_state.newsym = gs_retVal;
43                    }
44                    else
45                    {
46                        cg_state.stmtsl.push_back(new Assign(seq->getName(), new And(new Var(cg_state.newsym), new CharClass(name->getName()))));
47                    }
48                }
49            }
50        }
51    }
52
53    return cg_state;
54}
55
56CodeGenState Pbix_Compiler::compile(RE *re)
57{   
58    CodeGenState cg_state;
59
60    std::string gs_m0 = symgen.gensym("start_marker");
61    cg_state.stmtsl.push_back(new Assign(gs_m0, new All(1)));
62
63    if (unicode_re(re))
64    {
65        cg_state.newsym = gs_m0;
66        //Set the 'internal.initial' bit stream for the utf-8 multi-byte encoding.
67        std::string gs_initial = symgen.gensym("internal.initial");
68        m_name_map.insert(make_pair("internal.initial", gs_initial));
69        cg_state.stmtsl.push_back(new Assign(gs_initial, new Or(new Or( new Or( new And(new Var(m_name_map.find("UTF8-Prefix2")->second),
70            new Var(cg_state.newsym)),  new And(new Var(m_name_map.find("UTF8-SingleByte")->second), new Var(cg_state.newsym))),
71            new And(new Var(m_name_map.find("UTF8-Prefix3")->second), new Var(cg_state.newsym))),
72            new And(new Var(m_name_map.find("UTF8-Prefix4")->second), new Var(cg_state.newsym)))));
73        cg_state.newsym = gs_initial;
74
75        //Set the 'internal.nonfinal' bit stream for the utf-8 multi-byte encoding.
76        cg_state.newsym = gs_m0;
77        std::string gs_nonfinal = symgen.gensym("internal.nonfinal");
78        m_name_map.insert(make_pair("internal.nonfinal", gs_nonfinal));
79        cg_state.stmtsl.push_back(new Assign(gs_nonfinal, new Or(new Or(new Or(new Or(new Or( new And(new Var(m_name_map.find("UTF8-Prefix3")->second),
80            new Var(cg_state.newsym)),  new And(new Var(m_name_map.find("UTF8-Prefix2")->second), new Var(cg_state.newsym))),
81            new Advance( new And(new Var(m_name_map.find("UTF8-Prefix3")->second), new Var(cg_state.newsym)))),
82            new And(new Var(m_name_map.find("UTF8-Prefix4")->second), new Var(cg_state.newsym))), new Advance(
83            new And(new Var(m_name_map.find("UTF8-Prefix4")->second), new Var(cg_state.newsym)))), new Advance(
84            new Advance( new And(new Var(m_name_map.find("UTF8-Prefix4")->second), new Var(cg_state.newsym)))))));
85        cg_state.newsym = gs_nonfinal;
86    }
87
88    cg_state.newsym = gs_m0;
89    cg_state = re2pablo_helper(re, cg_state);
90
91    //These three lines are specifically for grep.
92    std::string gs_retVal = symgen.gensym("marker");
93    cg_state.stmtsl.push_back(new Assign(gs_retVal, new And(new MatchStar(new Var(cg_state.newsym),
94        new Not(new Var(m_name_map.find("LineFeed")->second))), new Var(m_name_map.find("LineFeed")->second))));
95    cg_state.newsym = gs_retVal;
96
97    return cg_state;
98}
99
100CodeGenState Pbix_Compiler::re2pablo_helper(RE *re, CodeGenState cg_state)
101{
102    if (Name* name = dynamic_cast<Name*>(re))
103    {
104        std::string gs_retVal = symgen.gensym("marker");
105        PabloE* markerExpr = new Var(cg_state.newsym);
106        if (name->getType() != Name::FixedLength) {
107            // Move the markers forward through any nonfinal UTF-8 bytes to the final position of each character.
108            markerExpr = new ScanThru(markerExpr, new CharClass(m_name_map.find("internal.nonfinal")->second));
109        }       
110        PabloE* ccExpr;
111        if (name->getType() == Name::UnicodeCategory)
112        {
113            ccExpr = new Call(name->getName());
114        }
115        else 
116        {
117            ccExpr = new CharClass(name->getName());
118        }
119        if (name->isNegated()) {
120            ccExpr = new Not(new Or(ccExpr, new CharClass(m_name_map.find("LineFeed")->second)));
121        }
122        cg_state.stmtsl.push_back(new Assign(gs_retVal, new Advance(new And(ccExpr, markerExpr))));
123        cg_state.newsym = gs_retVal;
124
125        std::cout << "\n" << "(" << StatementPrinter::PrintStmts(cg_state) << ")" << "\n" << std::endl;
126    }
127    else if (Start* start = dynamic_cast<Start*>(re))
128    {
129        std::string gs_retVal = symgen.gensym("start_of_line_marker");
130        cg_state.stmtsl.push_back(new Assign(gs_retVal, new And(new Var(cg_state.newsym), new Not(new Advance(new Not(new CharClass(m_name_map.find("LineFeed")->second)))))));
131        cg_state.newsym = gs_retVal;
132    }
133    else if (End* end = dynamic_cast<End*>(re))
134    {
135        std::string gs_retVal = symgen.gensym("end_of_line_marker");
136        cg_state.stmtsl.push_back(new Assign(gs_retVal, new And(new Var(cg_state.newsym), new CharClass(m_name_map.find("LineFeed")->second))));
137        cg_state.newsym = gs_retVal;
138    }
139    else if (Seq* seq = dynamic_cast<Seq*>(re))
140    {
141        std::list<RE*>::iterator it = seq->GetREList()->begin();
142        if (it != seq->GetREList()->end())
143        {
144            cg_state = Seq_helper(seq->GetREList(), it, cg_state);
145        }
146    //cout << "\n" << "Seq => (" << StatementPrinter::PrintStmts(cg_state) << ")" << "\n" << endl;
147    }
148    else if (Alt* alt = dynamic_cast<Alt*>(re))
149    {
150        if (alt->GetREList() == 0)
151        {
152
153            std::string gs_retVal = symgen.gensym("always_fail_marker");
154            cg_state.stmtsl.push_back(new Assign(gs_retVal, new All(0)));
155            cg_state.newsym = gs_retVal;
156        }
157        else
158        {
159            if (alt->GetREList()->size() == 1)
160            {
161                cg_state = re2pablo_helper(alt->GetREList()->front(), cg_state);
162            }
163            else
164            {
165                std::list<RE*>::iterator it = alt->GetREList()->begin();
166                cg_state = Alt_helper(alt->GetREList(), it, cg_state);
167            }
168        }
169    //cout << "\n" << "Alt => (" << StatementPrinter::PrintStmts(cg_state) << ")" << "\n" << endl;
170    }
171    else if (Rep* rep = dynamic_cast<Rep*>(re))
172    {
173        if ((dynamic_cast<Name*>(rep->getRE()) != 0) && (rep->getLB() == 0) && (rep->getUB()== unboundedRep))
174        {
175            Name* rep_name = dynamic_cast<Name*>(rep->getRE());
176            std::string gs_retVal = symgen.gensym("marker");
177
178std::cout << "MatchStar pattern found!" << std::endl;
179            PabloE* ccExpr;
180            if (name->getType() == Name::UnicodeCategory)
181            {
182std::cout << "MatchStar pattern External!" << std::endl;
183                ccExpr = new Call(name->getName());
184            }
185            else 
186            {
187std::cout << "MatchStar pattern internal!" << std::endl;
188                ccExpr = new CharClass(name->getName());
189            }
190
191            if (name->isNegated()) {
192std::cout << "MatchStar pattern Negated!" << std::endl;               
193                ccExpr = new Not(new Or(ccExpr, new CharClass(m_name_map.find("LineFeed")->second)));
194            }
195            if (rep_name->getType() == Name::FixedLength)
196            {
197                cg_state.stmtsl.push_back(new Assign(gs_retVal, new MatchStar(new Var(cg_state.newsym), ccExpr)));
198            }
199            else //Name::Unicode and Name::UnicodeCategory
200            {
201std::cout << "MatchStar pattern Unicode!" << std::endl;               
202                cg_state.stmtsl.push_back(new Assign(gs_retVal,
203                    new And(new MatchStar(new Var(cg_state.newsym), new Or(new CharClass(m_name_map.find("internal.nonfinal")->second),
204                    ccExpr)), new CharClass(m_name_map.find("internal.initial")->second))));
205            }
206
207            cg_state.newsym = gs_retVal;
208        }
209        else if (rep->getUB() == unboundedRep)
210        {
211            if (rep->getLB() == 0)
212            {
213                //std::cout << "While, no lb." << std::endl;
214
215                std::string while_test_gs_retVal = symgen.gensym("while_test");
216                std::string while_accum_gs_retVal = symgen.gensym("while_accum");
217                CodeGenState while_test_state;
218                while_test_state.newsym = while_test_gs_retVal;
219                CodeGenState t1_cg_state = re2pablo_helper(rep->getRE(), while_test_state);
220                cg_state.stmtsl.push_back(new Assign(while_test_gs_retVal, new Var(cg_state.newsym)));
221                cg_state.stmtsl.push_back(new Assign(while_accum_gs_retVal, new Var(cg_state.newsym)));
222                std::list<PabloS*> stmtList;
223                stmtList = t1_cg_state.stmtsl;
224                stmtList.push_back(new Assign(while_test_gs_retVal, new And(new Var(t1_cg_state.newsym), new Not(new Var(while_accum_gs_retVal)))));
225                stmtList.push_back(new Assign(while_accum_gs_retVal, new Or(new Var(while_accum_gs_retVal), new Var(t1_cg_state.newsym))));
226                cg_state.stmtsl.push_back( new While(new Var(while_test_gs_retVal), stmtList));
227                cg_state.newsym = while_accum_gs_retVal;
228            }
229            else //if (rep->getLB() > 1)
230            {
231                CodeGenState t1_cg_state = re2pablo_helper(rep->getRE(), cg_state);
232                rep->setLB(rep->getLB() - 1);
233                cg_state = re2pablo_helper(rep, t1_cg_state);
234            }
235        }
236        else if (rep->getUB() != unboundedRep)
237        {
238            if ((rep->getLB() == 0) && (rep->getUB() == 0))
239            {
240                //Just fall through...do nothing.
241            }
242            else if ((rep->getLB() == 0) && (rep->getUB() > 0))
243            {
244                CodeGenState t1_cg_state = re2pablo_helper(rep->getRE(), cg_state);
245                rep->setUB(rep->getUB() - 1);
246                CodeGenState t2_cg_state = re2pablo_helper(re, t1_cg_state);
247                std::string gs_retVal = symgen.gensym("alt_marker");
248                cg_state.stmtsl = t2_cg_state.stmtsl;
249                cg_state.stmtsl.push_back(new Assign(gs_retVal, new Or(new Var(cg_state.newsym), new Var(t2_cg_state.newsym))));
250                cg_state.newsym = gs_retVal;
251            }
252            else //if ((rep->getLB() > 0) && (rep->getUB() > 0))
253            {
254                CodeGenState t1_cg_state = re2pablo_helper(rep->getRE(), cg_state);
255                rep->setLB(rep->getLB() - 1);
256                rep->setUB(rep->getUB() - 1);
257                cg_state = re2pablo_helper(rep, t1_cg_state);
258            }
259        }
260    }
261
262    return cg_state;
263}
264
265CodeGenState Pbix_Compiler::Seq_helper(std::list<RE*>* lst, std::list<RE*>::const_iterator it, CodeGenState cg_state)
266{
267    if (it != lst->end())
268    {
269        cg_state = re2pablo_helper(*it, cg_state);
270        cg_state = Seq_helper(lst, ++it, cg_state);
271    }
272
273    return cg_state;
274}
275
276CodeGenState Pbix_Compiler::Alt_helper(std::list<RE*>* lst, std::list<RE*>::const_iterator it, CodeGenState cg_state)
277{
278    CodeGenState t1_cg_state = re2pablo_helper(*it, cg_state);
279    cg_state.stmtsl = t1_cg_state.stmtsl;
280    ++it;
281    if (it != lst->end())
282    {
283        CodeGenState t2_cg_state = Alt_helper(lst, it, cg_state);
284        cg_state.stmtsl = t2_cg_state.stmtsl;
285        std::string gs_retVal = symgen.gensym("alt_marker");
286        cg_state.stmtsl.push_back(new Assign(gs_retVal, new Or(new Var(t1_cg_state.newsym), new Var(t2_cg_state.newsym))));
287        cg_state.newsym = gs_retVal;
288    }
289    else
290    {
291        cg_state.newsym = t1_cg_state.newsym;
292    }
293
294    return cg_state;
295}
296
297bool Pbix_Compiler::unicode_re(RE *re)
298{
299    bool found = false;
300
301    return unicode_re_helper(re, found);
302}
303
304bool Pbix_Compiler::unicode_re_helper(RE *re, bool found)
305{
306    if (!found)
307    {
308        if (Name* name = dynamic_cast<Name*>(re))
309        {
310            if ((name->getType() == Name::UnicodeCategory) || (name->getType() == Name::Unicode))
311            {
312                found = true;
313            }
314        }
315        else if (Seq* re_seq = dynamic_cast<Seq*>(re))
316        {
317            std::list<RE*>::iterator it;
318            for (it = re_seq->GetREList()->begin(); it != re_seq->GetREList()->end(); ++it)
319            {
320                found = unicode_re_helper(*it, found);
321                if (found) break;
322            }
323        }
324        else if (Alt* re_alt = dynamic_cast<Alt*>(re))
325        {
326            std::list<RE*>::iterator it;
327            for (it = re_alt->GetREList()->begin(); it != re_alt->GetREList()->end(); ++it)
328            {
329                found = unicode_re_helper(*it, found);
330                if (found) break;
331            }
332        }
333        else if (Rep* rep = dynamic_cast<Rep*>(re))
334        {
335            found = unicode_re_helper(rep->getRE(), found);
336        }
337    }
338
339    return found;
340}
Note: See TracBrowser for help on using the repository browser.