|
1 | 1 | %scanner-token-function scanner.lex()
|
2 |
| -%stype std::pair<int,int> |
| 2 | +%stype std::pair<std::list<Node>::iterator,std::list<Node>::iterator> |
3 | 3 | %token-path Tokens.h
|
4 |
| -%token CHAR PLUS STAR QUESTION BAR LPAREN RPAREN ERROR |
| 4 | +%token CHAR LPAREN RPAREN ERROR |
| 5 | + |
| 6 | +%left BAR |
| 7 | +%left CONCAT |
| 8 | +%right PLUS STAR QUESTION |
5 | 9 |
|
6 | 10 | %%
|
7 | 11 |
|
8 | 12 | start : {
|
9 |
| - nodes.emplace_back("Start", 0); |
10 |
| - nodes.front().addEdgeTo(1); |
| 13 | + nodes.emplace_front("Start", nodeId++); |
| 14 | + nodes.emplace_back("?", nodeId++); |
| 15 | + nextNode = --nodes.end(); |
| 16 | + nodes.front().addEdgeTo(nextNode); |
11 | 17 | }
|
12 | 18 | regex EOF {
|
13 |
| - nodes.emplace_back("Accept", nodes.size()); |
| 19 | + nextNode->setName("Accept"); |
14 | 20 | }
|
15 | 21 | ;
|
16 | 22 |
|
17 | 23 | regex : regex STAR {
|
18 | 24 | $$ = $1;
|
19 |
| - nodes.at($$.first - 1).addEdgeTo(nodes.size()); |
20 |
| - nodes.at($$.second).addEdgeTo($$.first); |
| 25 | + $$.second->addEdgeTo($$.first); |
| 26 | + (--$$.first)->addEdgeTo(nextNode); |
| 27 | + ++$$.first; |
21 | 28 | }
|
22 | 29 | | regex QUESTION {
|
23 | 30 | $$ = $1;
|
24 |
| - nodes.at($$.first - 1).addEdgeTo(nodes.size()); |
| 31 | + (--$$.first)->addEdgeTo(nextNode); |
| 32 | + ++$$.first; |
25 | 33 | }
|
26 | 34 | | regex PLUS {
|
27 | 35 | $$ = $1;
|
28 |
| - nodes.at($$.second).addEdgeTo($$.first); |
| 36 | + $$.second->addEdgeTo($$.first); |
29 | 37 | }
|
30 |
| - | regex regex { |
| 38 | + | regex regex |
| 39 | + %prec CONCAT { |
31 | 40 | $$ = { $1.first, $2.second };
|
32 |
| - nodes.at($1.second).addEdgeTo($2.first); |
33 |
| - nodes.at($2.second).addEdgeTo(nodes.size()); |
34 | 41 | }
|
35 | 42 | | regex BAR regex {
|
36 |
| - $$ = { $1.first, nodes.size() }; |
37 |
| - nodes.at($1.second).addEdgeTo($$.second); |
38 |
| - nodes.at($$.first - 1).addEdgeTo($3.first); |
39 |
| - nodes.at($3.second).addEdgeTo($$.second); |
40 |
| - nodes.emplace_back("", $$.second); |
41 |
| - nodes.at($$.second).addEdgeTo(nodes.size()); |
| 43 | + $$ = { nodes.emplace($1.first, "", nodeId++), nextNode }; |
| 44 | + for (auto& node : nodes) { |
| 45 | + for (auto edge : node.getEdges()) { |
| 46 | + if (edge == $1.first) { |
| 47 | + node.removeEdgeTo(edge); |
| 48 | + node.addEdgeTo($$.first); |
| 49 | + } |
| 50 | + } |
| 51 | + } |
| 52 | + $1.second->removeEdgeTo($3.first); |
| 53 | + nextNode->setName(""); |
| 54 | + $$.first->addEdgeTo($1.first); |
| 55 | + $1.second->addEdgeTo($$.second); |
| 56 | + $$.first->addEdgeTo($3.first); |
| 57 | + $3.second->addEdgeTo($$.second); |
| 58 | + nodes.emplace_back("?", nodeId++); |
| 59 | + nextNode = --nodes.end(); |
| 60 | + $$.second->addEdgeTo(nextNode); |
42 | 61 | }
|
43 | 62 | | LPAREN regex RPAREN {
|
44 | 63 | $$ = $2;
|
45 | 64 | }
|
46 | 65 | | CHAR {
|
47 |
| - $$ = { nodes.size(), nodes.size() }; |
48 |
| - nodes.emplace_back(scanner.matched(), $$.first); |
| 66 | + $$ = { nextNode, nextNode }; |
| 67 | + nextNode->setName(scanner.matched()); |
| 68 | + nodes.emplace_back("?", nodeId++); |
| 69 | + nextNode = --nodes.end(); |
| 70 | + $$.first->addEdgeTo(nextNode); |
49 | 71 | }
|
50 | 72 | ;
|
0 commit comments