Skip to content

Commit 1f30332

Browse files
committed
Rewritten to use std::list
1 parent 8d2fa3d commit 1f30332

File tree

10 files changed

+161
-114
lines changed

10 files changed

+161
-114
lines changed

regex-graphviz/Node.h

+15-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,27 @@
22
#define Node_h
33

44
#include <string>
5-
#include <set>
5+
#include <vector>
6+
#include <list>
7+
#include <algorithm>
68

79
class Node {
810
std::string name;
911
int id;
10-
std::set<int> edges;
12+
std::vector<std::list<Node>::iterator> edges;
1113
public:
1214
Node(const std::string& name, int id) : name{ name }, id{ id } {}
13-
void addEdgeTo(int id) { edges.insert(id); }
15+
void addEdgeTo(std::list<Node>::iterator& node) {
16+
if (std::find(edges.begin(), edges.end(), node) == edges.end()) {
17+
edges.push_back(node);
18+
}
19+
}
20+
void removeEdgeTo(std::list<Node>::iterator& node) {
21+
if (auto iter = std::find(edges.begin(), edges.end(), node); iter != edges.end()) {
22+
edges.erase(iter);
23+
}
24+
}
25+
void setName(const std::string& n) { name = n; }
1426
const auto& getName() const { return name; }
1527
int getId() const { return id; }
1628
const auto& getEdges() const { return edges; }

regex-graphviz/Parser.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ class Parser: public ParserBase
1313

1414
public:
1515
Parser() = delete;
16-
Parser(Scanner& scanner, std::vector<Node>& nodes) : scanner{ scanner }, nodes{ nodes } {}
16+
Parser(Scanner& scanner, std::list<Node>& nodes) : scanner{ scanner }, nodes{ nodes } {}
1717
int parse();
1818

1919
private:
2020
Scanner& scanner;
21-
std::vector<Node>& nodes;
21+
std::list<Node>& nodes;
22+
std::list<Node>::iterator nextNode;
23+
int nodeId{};
2224
void error(); // called on (syntax) errors
2325
int lex(); // returns the next token from the
2426
// lexical scanner.

regex-graphviz/Parser.ih

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
// Include this file in the sources of the class Parser.
44

55
// $insert class.h
6+
#include <list>
7+
#include "Node.h"
68
#include "Parser.h"
79

8-
910
inline void Parser::error()
1011
{
1112
std::cerr << "Bad regex.\n";

regex-graphviz/Parserbase.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Generated by Bisonc++ V6.05.00 on Wed, 14 Aug 2024 14:34:14 +0100
1+
// Generated by Bisonc++ V6.05.00 on Sat, 17 Aug 2024 11:04:46 +0100
22

33
// hdr/includes
44
#ifndef ParserBase_h_included
@@ -32,7 +32,7 @@ class ParserBase: public Tokens
3232

3333
// $insert tokens
3434
// $insert STYPE
35-
using STYPE_ = std::pair<int,int>;
35+
using STYPE_ = std::pair<std::list<Node>::iterator,std::list<Node>::iterator>;
3636

3737

3838
private:

regex-graphviz/Scannerbase.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Generated by Flexc++ V2.14.00 on Wed, 14 Aug 2024 14:30:28 +0100
1+
// Generated by Flexc++ V2.14.00 on Sat, 17 Aug 2024 10:39:48 +0100
22

33
#ifndef ScannerBASE_H_INCLUDED
44
#define ScannerBASE_H_INCLUDED

regex-graphviz/Tokens.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ struct Tokens
77
enum Tokens_
88
{
99
CHAR = 257,
10-
PLUS,
11-
STAR,
12-
QUESTION,
13-
BAR,
1410
LPAREN,
1511
RPAREN,
1612
ERROR,
13+
BAR,
14+
CONCAT,
15+
PLUS,
16+
STAR,
17+
QUESTION,
1718
};
1819

1920
};

regex-graphviz/grammar.y

+42-20
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,72 @@
11
%scanner-token-function scanner.lex()
2-
%stype std::pair<int,int>
2+
%stype std::pair<std::list<Node>::iterator,std::list<Node>::iterator>
33
%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
59

610
%%
711

812
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);
1117
}
1218
regex EOF {
13-
nodes.emplace_back("Accept", nodes.size());
19+
nextNode->setName("Accept");
1420
}
1521
;
1622

1723
regex : regex STAR {
1824
$$ = $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;
2128
}
2229
| regex QUESTION {
2330
$$ = $1;
24-
nodes.at($$.first - 1).addEdgeTo(nodes.size());
31+
(--$$.first)->addEdgeTo(nextNode);
32+
++$$.first;
2533
}
2634
| regex PLUS {
2735
$$ = $1;
28-
nodes.at($$.second).addEdgeTo($$.first);
36+
$$.second->addEdgeTo($$.first);
2937
}
30-
| regex regex {
38+
| regex regex
39+
%prec CONCAT {
3140
$$ = { $1.first, $2.second };
32-
nodes.at($1.second).addEdgeTo($2.first);
33-
nodes.at($2.second).addEdgeTo(nodes.size());
3441
}
3542
| 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);
4261
}
4362
| LPAREN regex RPAREN {
4463
$$ = $2;
4564
}
4665
| 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);
4971
}
5072
;

regex-graphviz/lex.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Generated by Flexc++ V2.14.00 on Wed, 14 Aug 2024 14:30:28 +0100
1+
// Generated by Flexc++ V2.14.00 on Sat, 17 Aug 2024 10:39:48 +0100
22

33
#include <iostream>
44
#include <fstream>

regex-graphviz/main.cc

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1+
#include "Node.h"
12
#include "Scanner.h"
23
#include "Parser.h"
3-
#include "Node.h"
4-
#include <vector>
5-
#include <string>
64
#include <sstream>
75
#include <iostream>
86

@@ -15,7 +13,7 @@ int main() {
1513
return 0;
1614
}
1715
std::istringstream input(str);
18-
std::vector<Node> nodes;
16+
std::list<Node> nodes;
1917
Scanner scanner(input);
2018
Parser parser(scanner, nodes);
2119
if (!parser.parse()) {
@@ -28,15 +26,15 @@ int main() {
2826
std::cout << '\n';
2927
for (const auto& node : nodes) {
3028
for (const auto& edge : node.getEdges()) {
31-
std::cout << " q" << node.getId() << " -> q" << edge << " [label=\"";
32-
if (nodes.at(edge).getName().size() == 1) {
33-
std::cout << nodes.at(edge).getName();
29+
std::cout << " q" << node.getId() << " -> q" << edge->getId() << " [label=\"";
30+
if (edge->getName().size() == 1) {
31+
std::cout << edge->getName();
3432
}
3533
else {
3634
std::cout << "ε";
3735
}
3836
std::cout << "\"";
39-
if (node.getId() == edge) {
37+
if (node.getId() == edge->getId()) {
4038
std::cout << " dir=back";
4139
}
4240
std::cout << "];\n";

0 commit comments

Comments
 (0)