Skip to content

Commit 138fc73

Browse files
committed
Recursive parser
1 parent 10958fb commit 138fc73

File tree

5 files changed

+491
-159
lines changed

5 files changed

+491
-159
lines changed

ecr/command.h

Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
// A single element in a Command
2+
3+
class Command;
4+
5+
class Element {
6+
7+
private:
8+
9+
Text* element = nullptr;
10+
Command* command = nullptr;
11+
12+
public:
13+
14+
///////////////////////////////////////////////////////////////////////
15+
// Initialize this element
16+
void init(Text* t) {
17+
int length = strlen(t->getText());
18+
char* temp = new char[length + 1];
19+
strcpy(temp, t->getText());
20+
temp[length] = '\0';
21+
element = new Text(temp);
22+
}
23+
24+
///////////////////////////////////////////////////////////////////////
25+
// Get the element
26+
Text* getElement() {
27+
return element;
28+
}
29+
30+
///////////////////////////////////////////////////////////////////////
31+
// Set the element text
32+
void setElement(Text* t) {
33+
if (element != nullptr) {
34+
delete element;
35+
init(t);
36+
}
37+
}
38+
39+
///////////////////////////////////////////////////////////////////////
40+
// Get the command
41+
Command* getCommand() {
42+
return command;
43+
}
44+
45+
///////////////////////////////////////////////////////////////////////
46+
// Set the command
47+
// void setCommand(Command* cmd) {
48+
// if (element != nullptr) {
49+
// delete element;
50+
// }
51+
// if (command != nullptr) {
52+
// delete command;
53+
// }
54+
// command = cmd;
55+
// }
56+
57+
///////////////////////////////////////////////////////////////////////
58+
// Find the position of a character inside this element
59+
// Calls the same function in Text
60+
int positionOf(char c) {
61+
if (element != nullptr) {
62+
return element->positionOf(c);
63+
}
64+
printf("Element->positionOf: No element\n");
65+
exit(1);
66+
return -1;
67+
}
68+
69+
///////////////////////////////////////////////////////////////////////
70+
// Test if this element is identical to some Text
71+
// Calls the same function in Text
72+
bool is(const char* s) {
73+
return element->is(s);
74+
}
75+
76+
///////////////////////////////////////////////////////////////////////
77+
// Get the leftmost N characters as a new Text
78+
// Calls the same function in Text
79+
Text* left(int n) {
80+
return element->left(n);
81+
}
82+
83+
///////////////////////////////////////////////////////////////////////
84+
// Get from character N to the end as a new Text
85+
// Calls the same function in Text
86+
Text* from(int n) {
87+
return element->from(n);
88+
}
89+
90+
///////////////////////////////////////////////////////////////////////
91+
// Constructor
92+
Element(const char* t) {
93+
element = new Text(t);
94+
}
95+
96+
///////////////////////////////////////////////////////////////////////
97+
// Constructor
98+
Element(Text* t) {
99+
element = t;
100+
}
101+
102+
///////////////////////////////////////////////////////////////////////
103+
// Constructor
104+
Element(Command* cmd) {
105+
command = cmd;
106+
}
107+
108+
///////////////////////////////////////////////////////////////////////
109+
// Destructor
110+
~Element() {
111+
delete element;
112+
}
113+
};
114+
115+
/*
116+
Command is an array of items, held initially in a linked list and then in an array.
117+
There are two lists and two arrays; one is of Elements and the other of Commands.
118+
When either is added, an empty one is also added to the other list, so the lists stay in step.
119+
Command is therefore a recursive data structure similar to a directory tree.
120+
*/
121+
122+
class Command {
123+
124+
private:
125+
int line;
126+
int size = 0; // the number of items
127+
Element** elements = nullptr; // an array of Element objects
128+
LinkedList* list; // A list to hold new Element items as they are added
129+
130+
public:
131+
132+
///////////////////////////////////////////////////////////////////////
133+
// Get the size (the number of elements in the array and list combined)
134+
int getSize() {
135+
return this->size + list->getSize();
136+
}
137+
138+
///////////////////////////////////////////////////////////////////////
139+
// Get a specified Element.
140+
// If the index is greater than the array size but not greater than
141+
// the combined size of array and list, return the item from the list.
142+
Element* get(int n) {
143+
if (n < size) {
144+
return elements[n];
145+
}
146+
else if (n < size + list->getSize()) {
147+
return (Element*)list->get(n - size);
148+
}
149+
return nullptr;
150+
}
151+
152+
///////////////////////////////////////////////////////////////////////
153+
// Add an element. This goes into the linked list.
154+
void add(Element* element) {
155+
list->add(element);
156+
}
157+
158+
///////////////////////////////////////////////////////////////////////
159+
// Flatten this item by creating a single array to hold all the data.
160+
void flatten() {
161+
Element** oldElements = elements;
162+
int oldSize = size;
163+
// Create a new array big enough for the old array and the list
164+
int total = oldSize + list->getSize();
165+
if (total > 0) {
166+
elements = new Element*[total];
167+
// Copy the old array to the new
168+
size = 0;
169+
while (size < oldSize) {
170+
elements[size] = oldElements[size];
171+
size++;
172+
}
173+
if (oldElements != nullptr) {
174+
delete oldElements;
175+
}
176+
// Copy the list to the new array
177+
for (int n = 0; n < list->getSize(); n++) {
178+
elements[size++] = (Element*)list->get(n);
179+
}
180+
list->clear();
181+
}
182+
}
183+
184+
///////////////////////////////////////////////////////////////////////
185+
// Build a command recursively
186+
void parse(TextArray* tt) {
187+
int n = 0;
188+
while (n < tt->getSize()) {
189+
n++;
190+
}
191+
}
192+
193+
///////////////////////////////////////////////////////////////////////
194+
// Print all the values in the array
195+
void dump() {
196+
for (int n = 0; n < size; n++) {
197+
Element* el = get(n);
198+
if (el->getElement() == nullptr) {
199+
print("Command ");
200+
el->getCommand()->dump();
201+
} else {
202+
print("%s ", el->getElement()->getText());
203+
}
204+
}
205+
print("end ");
206+
}
207+
208+
///////////////////////////////////////////////////////////////////////
209+
// Provide info about the object
210+
void info() {
211+
print("Commands: list size=%d, array size=%d\n", list->getSize(), size);
212+
}
213+
214+
///////////////////////////////////////////////////////////////////////
215+
// Default constructor
216+
Command() {
217+
list = new LinkedList();
218+
}
219+
220+
///////////////////////////////////////////////////////////////////////
221+
// Destructor
222+
~Command() {
223+
delete elements;
224+
elements = nullptr;
225+
delete list;
226+
list = nullptr;
227+
}
228+
};
229+
230+
/*
231+
TextArray is a memory-efficient class for managing arrays of strings.
232+
A typically usage is to break a piece of text into lines and have them
233+
available by line number.
234+
*/
235+
236+
class CommandArray {
237+
238+
private:
239+
const char* name;
240+
int size = 0; // the number of items
241+
Command** array = nullptr; // the array of items
242+
LinkedList* list; // A list to hold new data items as they are added
243+
244+
public:
245+
246+
///////////////////////////////////////////////////////////////////////
247+
// Get the size (the number of elements in the array and list combined)
248+
int getSize() {
249+
return this->size + list->getSize();
250+
}
251+
252+
///////////////////////////////////////////////////////////////////////
253+
// Get a specified item.
254+
// If the index is greater than the array size but not greater than
255+
// the combined size of array and list, return the item from the list.
256+
Command* get(int n) {
257+
if (n < size) {
258+
return array[n];
259+
}
260+
else if (n < size + list->getSize()) {
261+
return (Command*)list->get(n - size);
262+
}
263+
return nullptr;
264+
}
265+
266+
///////////////////////////////////////////////////////////////////////
267+
// Add a command. This goes into the linked list.
268+
void add(Command* command) {
269+
list->add(command);
270+
}
271+
272+
///////////////////////////////////////////////////////////////////////
273+
// Flatten this item by creating a single array to hold all the data.
274+
void flatten() {
275+
Command** oldArray = array;
276+
int oldSize = size;
277+
// Create a new array big enough for the old array and the list
278+
int total = oldSize + list->getSize();
279+
if (total > 0) {
280+
array = new Command*[total];
281+
// Copy the old array to the new
282+
size = 0;
283+
while (size < oldSize) {
284+
array[size] = oldArray[size];
285+
size++;
286+
}
287+
if (oldArray != nullptr) {
288+
delete oldArray;
289+
}
290+
// Copy the list to the new array
291+
int n = 0;
292+
while (n < list->getSize()) {
293+
array[size++] = (Command*)list->get(n++);
294+
}
295+
list->clear();
296+
}
297+
}
298+
299+
///////////////////////////////////////////////////////////////////////
300+
// Provide info about the object
301+
void info() {
302+
print("CommandArray: list size=%d, array size=%d\n", list->getSize(), size);
303+
}
304+
305+
///////////////////////////////////////////////////////////////////////
306+
// Print all the values in the array
307+
void dump() {
308+
for (int n = 0; n < size; n++) {
309+
print("Command %d: ", n);
310+
get(n)->dump();
311+
print("\n");
312+
}
313+
}
314+
315+
///////////////////////////////////////////////////////////////////////
316+
// Named constructor
317+
CommandArray(const char* name) {
318+
this->name = name;
319+
list = new LinkedList(name);
320+
}
321+
322+
///////////////////////////////////////////////////////////////////////
323+
// Default constructor
324+
CommandArray() {
325+
list = new LinkedList("<noname>");
326+
}
327+
328+
///////////////////////////////////////////////////////////////////////
329+
// Destructor
330+
~CommandArray() {
331+
delete array;
332+
array = nullptr;
333+
delete list;
334+
list = nullptr;
335+
#if DESTROY
336+
print("CommandArray: Delete %s\n", name);
337+
#endif
338+
}
339+
};

ecr/ecr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "keyword.h"
1515
#include "value.h"
1616
#include "symbol.h"
17+
#include "command.h"
1718
#include "runtime.h"
1819
#include "domain/core/core-keywords.h"
1920
#include "domain/core/core-values.h"

0 commit comments

Comments
 (0)