commit
message
[ParseEngine] work-in-progress, creating new parser engine starting with actions, rules, rectioons, and symbols
author
Ben Vogt <[email protected]>
date
2017-12-07 02:58:18
stats
3 file(s) changed,
740 insertions(+),
18 deletions(-)
files
src/Parser/ObjectBuilder.ts
src/Parser/ParseEngine.ts
src/Parser/ParserConstants.ts
1diff --git a/src/Parser/ObjectBuilder.ts b/src/Parser/ObjectBuilder.ts
2new file mode 100644
3index 0000000..6dd3917
4--- /dev/null
5+++ b/src/Parser/ObjectBuilder.ts
6@@ -0,0 +1,24 @@
7+/**
8+ * Utility class to help build objects programmatically. Basically this allows me to have source code where constants
9+ * are keys in objects.
10+ */
11+class ObjectBuilder {
12+ public o : Object = {};
13+
14+ public static add(k, v) : ObjectBuilder {
15+ let m = new ObjectBuilder();
16+ m.o[k.toString()] = v;
17+ return m;
18+ }
19+ public add(k, v) : ObjectBuilder {
20+ this.o[k.toString()] = v;
21+ return this;
22+ }
23+ public build() : Object {
24+ return this.o;
25+ }
26+}
27+
28+export {
29+ ObjectBuilder
30+}
31\ No newline at end of file
32diff --git a/src/Parser/ParseEngine.ts b/src/Parser/ParseEngine.ts
33new file mode 100644
34index 0000000..c10b62d
35--- /dev/null
36+++ b/src/Parser/ParseEngine.ts
37@@ -0,0 +1,712 @@
38+import {
39+ ObjectBuilder
40+} from "./ObjectBuilder";
41+
42+// Rules represent the Regular Expressions that will be used in sequence to match a given input to the Parser.
43+const Rules = {
44+ WHITE_SPACE : /^(?:\s+)/,
45+ DOUBLE_QUOTES : /^(?:"(\\["]|[^"])*")/,
46+ SINGLE_QUOTES : /^(?:'(\\[']|[^'])*')/,
47+ FORMULA_NAME : /^(?:[A-Za-z.]{1,}[A-Za-z_0-9]+(?=[(]))/,
48+ $_A1_CELL : /^(?:\$[A-Za-z]+\$[0-9]+)/,
49+ A1_CELL : /^(?:[A-Za-z]+[0-9]+)/,
50+ FORMULA_NAME_SIMPLE : /^(?:[A-Za-z.]+(?=[(]))/,
51+ VARIABLE : /^(?:[A-Za-z]{1,}[A-Za-z_0-9]+)/,
52+ SIMPLE_VARIABLE : /^(?:[A-Za-z_]+)/,
53+ INTEGER : /^(?:[0-9]+(?:(?:[eE])(?:[\+-])?[0-9]+)?)/,
54+ OPEN_ARRAY: /^(?:\[)/,
55+ CLOSE_ARRAY: /^(?:\])/,
56+ DOLLAR_SIGN : /^(?:\$)/,
57+ AMPERSAND_SIGN : /^(?:&)/,
58+ SINGLE_WHITESPACE : /^(?: )/,
59+ PERIOD : /^(?:[.])/,
60+ COLON : /^(?::)/,
61+ SEMI_COLON : /^(?:;)/,
62+ COMMA : /^(?:,)/,
63+ ASTERISK : /^(?:\*)/,
64+ FORWARD_SLASH : /^(?:\/)/,
65+ MINUS_SIGN : /^(?:-)/,
66+ PLUS_SIGN : /^(?:\+)/,
67+ CARET_SIGN : /^(?:\^)/,
68+ OPEN_PAREN : /^(?:\()/,
69+ CLOSE_PAREN : /^(?:\))/,
70+ GREATER_THAN_SIGN : /^(?:>)/,
71+ LESS_THAN_SIGN : /^(?:<)/,
72+ DOUBLE_QUOTE : /^(?:")/,
73+ SINGLE_QUITE : /^(?:')/,
74+ EXCLAMATION_POINT : /^(?:!)/,
75+ EQUALS_SIGN : /^(?:=)/,
76+ PERCENT_SIGN : /^(?:%)/,
77+ POUND: /^(?:\#)/,
78+ ERROR : /^(?:#N\/A|#NUM\!|#NULL\!|#DIV\/0\!|#VALUE\!|#REF\!|#ERROR)/,
79+ END : /^(?:$)/
80+};
81+
82+
83+// Sequential rules to use when parsing a given input.
84+const RulesSeq = [
85+ Rules.WHITE_SPACE,
86+ Rules.DOUBLE_QUOTES,
87+ Rules.SINGLE_QUOTES,
88+ Rules.FORMULA_NAME,
89+ Rules.$_A1_CELL,
90+ Rules.A1_CELL,
91+ Rules.FORMULA_NAME_SIMPLE,
92+ Rules.VARIABLE,
93+ Rules.SIMPLE_VARIABLE,
94+ Rules.INTEGER,
95+ Rules.OPEN_ARRAY,
96+ Rules.CLOSE_ARRAY,
97+ Rules.DOLLAR_SIGN,
98+ Rules.AMPERSAND_SIGN,
99+ Rules.SINGLE_WHITESPACE,
100+ Rules.PERIOD,
101+ Rules.COLON,
102+ Rules.SEMI_COLON,
103+ Rules.COMMA,
104+ Rules.ASTERISK,
105+ Rules.FORWARD_SLASH,
106+ Rules.MINUS_SIGN,
107+ Rules.PLUS_SIGN,
108+ Rules.CARET_SIGN,
109+ Rules.OPEN_PAREN,
110+ Rules.CLOSE_PAREN,
111+ Rules.GREATER_THAN_SIGN,
112+ Rules.LESS_THAN_SIGN,
113+ Rules.DOUBLE_QUOTE,
114+ Rules.SINGLE_QUITE,
115+ Rules.EXCLAMATION_POINT,
116+ Rules.EQUALS_SIGN,
117+ Rules.PERCENT_SIGN,
118+ Rules.POUND,
119+ Rules.ERROR,
120+ Rules.END
121+];
122+
123+
124+enum Symbol {
125+ ACCEPT = 0,
126+ END = 1,
127+ ERROR = 2,
128+ EXPRESSIONS = 3,
129+ EXPRESSION = 4,
130+ EOF = 5,
131+ VARIABLE = 6,
132+ VARIABLE_SEQUENCE = 7,
133+ NUMBER = 8,
134+ STRING = 9,
135+ FORMULA = 10,
136+ BOOLEAN = 11,
137+ CELL_REF = 12,
138+ FIXED_CELL_REF = 13,
139+ CELL = 14,
140+ OPEN_ARRAY = 15,
141+ CLOSE_ARRAY = 16,
142+ PERIOD = 17,
143+ AMPERSAND = 18,
144+ EQUALS = 19,
145+ PLUS = 20,
146+ OPEN_PAREN = 21,
147+ CLOSE_PAREN = 22,
148+ LESS_THAN = 23,
149+ GREATER_THAN = 24,
150+ MINUS = 25,
151+ ASTERISK = 26,
152+ DIVIDE = 27,
153+ CARROT = 28,
154+ COLON = 29,
155+ SEMI_COLON = 30,
156+ COMMA = 31,
157+ PERCENT = 32,
158+ POUND = 33,
159+ EXCLAMATION_POINT = 34,
160+ WHITE_SPACE = 35
161+}
162+
163+const SYMBOL_NAME_TO_INDEX = {
164+ "ACCEPT": Symbol.ACCEPT,
165+ "END": Symbol.END,
166+ "ERROR": Symbol.ERROR,
167+ "EXPRESSIONS": Symbol.EXPRESSIONS,
168+ "EXPRESSION": Symbol.EXPRESSION,
169+ "EOF": Symbol.EOF,
170+ "VARIABLE": Symbol.VARIABLE,
171+ "VARIABLE_SEQUENCE": Symbol.VARIABLE_SEQUENCE,
172+ "NUMBER": Symbol.NUMBER,
173+ "STRING": Symbol.STRING,
174+ "FORMULA": Symbol.FORMULA,
175+ "CELL_REF": Symbol.CELL_REF,
176+ "FIXED_CELL_REF": Symbol.FIXED_CELL_REF,
177+ "CELL": Symbol.CELL,
178+ "OPEN_ARRAY": Symbol.OPEN_ARRAY,
179+ "CLOSE_ARRAY": Symbol.CLOSE_ARRAY,
180+ "PERIOD": Symbol.PERIOD,
181+ "&": Symbol.AMPERSAND,
182+ "=": Symbol.EQUALS,
183+ "+": Symbol.PLUS,
184+ "(": Symbol.OPEN_PAREN,
185+ ")": Symbol.CLOSE_PAREN,
186+ "<": Symbol.LESS_THAN,
187+ ">": Symbol.GREATER_THAN,
188+ "-": Symbol.MINUS,
189+ "*": Symbol.ASTERISK,
190+ "/": Symbol.DIVIDE,
191+ "^": Symbol.CARROT,
192+ ":": Symbol.COLON,
193+ ";": Symbol.SEMI_COLON,
194+ ",": Symbol.COMMA,
195+ "%": Symbol.PERCENT,
196+ "#": Symbol.POUND,
197+ "!": Symbol.EXCLAMATION_POINT,
198+ "WHITE_SPACE": Symbol.WHITE_SPACE
199+};
200+
201+
202+
203+/**
204+ * Actions to take when processing tokens one by one. We're always either taking the next token, reducing our current
205+ * tokens, or accepting and returning.
206+ */
207+const SHIFT = 1;
208+const REDUCE = 2;
209+const ACCEPT = 3;
210+
211+const enum ReduceActions {
212+ NO_ACTION = 0,
213+ RETURN_LAST = 1,
214+ CALL_VARIABLE = 2,
215+ AS_NUMBER = 3,
216+ AS_STRING = 4,
217+ AMPERSAND = 5,
218+ EQUALS = 6,
219+ PLUS = 7,
220+ LAST_NUMBER = 8,
221+ LTE = 9,
222+ GTE = 10,
223+ NOT_EQ = 11,
224+ NOT = 12,
225+ GT = 13,
226+ LT = 14,
227+ MINUS = 15,
228+ MULTIPLY = 16,
229+ DIVIDE = 17,
230+ TO_POWER = 18,
231+ AS_ERROR = 19,
232+ TO_NUMBER_NAN_AS_ZERO = 20,
233+ CALL_FUNCTION_LAST_BLANK = 21,
234+ FIXED_CELL_VAL = 22,
235+ FIXED_CELL_RANGE_VAL = 23,
236+ CELL_VALUE = 24,
237+ CELL_RANGE_VALUE = 25,
238+ PERCENT = 26
239+}
240+
241+/**
242+ * Represents the length to reduce the stack by, and the token index value that will replace those tokens in the stack.
243+ */
244+class ReductionPair {
245+ private lengthToReduceStackBy : number;
246+ private replacementTokenIndex : number;
247+ constructor(replacementTokenIndex : number, length : number) {
248+ this.lengthToReduceStackBy = length;
249+ this.replacementTokenIndex = replacementTokenIndex;
250+ }
251+
252+ /**
253+ * Get the number representing the length to reduce the stack by.
254+ * @returns {number}
255+ */
256+ getLengthToReduceStackBy() : number {
257+ return this.lengthToReduceStackBy;
258+ }
259+
260+ /**
261+ * Get the replacement token index.
262+ * @returns {number}
263+ */
264+ getReplacementTokenIndex() : number {
265+ return this.replacementTokenIndex;
266+ }
267+}
268+
269+/**
270+ * Productions is used to look up both the number to use when reducing the stack (productions[x][1]) and the semantic
271+ * value that will replace the tokens in the stack (productions[x][0]).
272+ * @type {Array<ReductionPair>}
273+ *
274+ * Maps a ProductionRule to the appropriate number of previous tokens to use in a reduction action.
275+ */
276+let productions : Array<ReductionPair> = [];
277+productions[ReduceActions.NO_ACTION] = null;
278+productions[ReduceActions.RETURN_LAST] = new ReductionPair(3, 2);
279+productions[ReduceActions.CALL_VARIABLE] = new ReductionPair(4, 1);
280+productions[ReduceActions.AS_NUMBER] = new ReductionPair(4, 1);
281+productions[ReduceActions.AS_STRING] = new ReductionPair(4, 1);
282+productions[ReduceActions.AMPERSAND] = new ReductionPair(4, 3);
283+productions[ReduceActions.EQUALS] = new ReductionPair(4, 3);
284+productions[ReduceActions.PLUS] = new ReductionPair(4, 3);
285+productions[ReduceActions.LAST_NUMBER] = new ReductionPair(4, 3);
286+productions[ReduceActions.LTE] = new ReductionPair(4, 4);
287+productions[ReduceActions.GTE] = new ReductionPair(4, 4);
288+productions[ReduceActions.NOT_EQ] = new ReductionPair(4, 4);
289+productions[ReduceActions.NOT] = new ReductionPair(4, 3);
290+productions[ReduceActions.GT] = new ReductionPair(4, 3);
291+productions[ReduceActions.LT] = new ReductionPair(4, 3);
292+productions[ReduceActions.MINUS] = new ReductionPair(4, 3);
293+productions[ReduceActions.MULTIPLY] = new ReductionPair(4, 3);
294+productions[ReduceActions.DIVIDE] = new ReductionPair(4, 3);
295+productions[ReduceActions.TO_POWER] = new ReductionPair(4, 3);
296+productions[ReduceActions.TO_NUMBER_NAN_AS_ZERO] = new ReductionPair(4, 2);
297+productions[ReduceActions.CALL_FUNCTION_LAST_BLANK] = new ReductionPair(4, 3);
298+productions[ReduceActions.FIXED_CELL_VAL] = new ReductionPair(25, 1);
299+productions[ReduceActions.FIXED_CELL_RANGE_VAL] = new ReductionPair(25, 3);
300+productions[ReduceActions.CELL_VALUE] = new ReductionPair(25, 1);
301+productions[ReduceActions.CELL_RANGE_VALUE] = new ReductionPair(25, 3);
302+productions[ReduceActions.PERCENT] = new ReductionPair(24, 3);
303+productions[ReduceActions.AS_ERROR] = new ReductionPair(4, 1);
304+const PRODUCTIONS = productions;
305+
306+
307+const enum Tree {
308+ START = 0,
309+ FOLLOWS_NUMBER = 1,
310+ FOLLOWS_STRING = 2,
311+ FOLLOWS_BOOL = 3,
312+ FOLLOWS_ERROR = 4,
313+ FOLLOWS_FORMULA = 5,
314+ FOLLOWS_PLUS = 6,
315+ FOLLOWS_MINUS = 7,
316+ FOLLOWS_ASTERISK = 8,
317+ FOLLOWS_SLASH = 9,
318+ FOLLOWS_CARROT = 10,
319+ FOLLOWS_AMPERSAND = 11,
320+ FOLLOWS_PERCENT = 12,
321+ FOLLOWS_PERIOD = 13,
322+ FOLLOWS_LESS_THAN = 14,
323+ FOLLOWS_GREATER_THAN = 15,
324+ FOLLOWS_EQUALS = 16,
325+ FOLLOWS_COMMA = 17,
326+ FOLLOWS_OPEN_PAREN = 18,
327+ FOLLOWS_CLOSE_PAREN = 19,
328+ FOLLOWS_CELL_REF = 20,
329+ FOLLOWS_FIXED_CELL_REF = 21,
330+ FOLLOWS_CELL_RANGE_REF = 22,
331+ FOLLOWS_FIXED_CELL_RANGE_REF = 23,
332+ FOLLOWS_OPEN_ARRAY = 24,
333+ FOLLOWS_CLOSE_ARRAY = 25,
334+ TERMINATE = 26
335+}
336+
337+/**
338+ * Array of to map rules to to LexActions and other rules. A single index in the object (e.g. `{2: 13}`) indicates the
339+ * rule object to follow for the next token, while an array (e.g. `{23: [1, ReduceActions.LTE]}`) indicates the action to be taken,
340+ * and the rule object to follow after the action.
341+ */
342+let table = [];
343+// All functions in the spreadsheet start with a 0-token.
344+table[Tree.START] = ObjectBuilder
345+ .add(Symbol.NUMBER, Tree.FOLLOWS_NUMBER)
346+ .add(Symbol.STRING, null)
347+ .add(Symbol.BOOLEAN, null)
348+ .add(Symbol.FORMULA, null)
349+ .add(Symbol.CELL_REF, null)
350+ .add(Symbol.FIXED_CELL_REF, null)
351+ .add(Symbol.POUND, null)
352+ .add(Symbol.OPEN_ARRAY, null)
353+ .add(Symbol.OPEN_PAREN, null)
354+ .add(Symbol.PLUS, null)
355+ .add(Symbol.MINUS, null)
356+ .add(Symbol.PERIOD, null)
357+ .add(Symbol.WHITE_SPACE, null)
358+ .add(Symbol.END, null)
359+ .build();
360+table[Tree.FOLLOWS_NUMBER] = ObjectBuilder
361+ .add(Symbol.PLUS, null)
362+ .add(Symbol.MINUS, null)
363+ .add(Symbol.ASTERISK, null)
364+ .add(Symbol.DIVIDE, null)
365+ .add(Symbol.CARROT, null)
366+ .add(Symbol.PERCENT, null)
367+ .add(Symbol.AMPERSAND, null)
368+ .add(Symbol.GREATER_THAN, null)
369+ .add(Symbol.LESS_THAN, null)
370+ .add(Symbol.EQUALS, null)
371+ .add(Symbol.COMMA, null)
372+ .add(Symbol.CLOSE_PAREN, null)
373+ .add(Symbol.CLOSE_ARRAY, null)
374+ .add(Symbol.WHITE_SPACE, null)
375+ .add(Symbol.END, null)
376+ .build();
377+table[Tree.FOLLOWS_STRING] = ObjectBuilder
378+ .add(Symbol.PLUS, null)
379+ .add(Symbol.MINUS, null)
380+ .add(Symbol.ASTERISK, null)
381+ .add(Symbol.DIVIDE, null)
382+ .add(Symbol.CARROT, null)
383+ .add(Symbol.PERCENT, null)
384+ .add(Symbol.AMPERSAND, null)
385+ .add(Symbol.GREATER_THAN, null)
386+ .add(Symbol.LESS_THAN, null)
387+ .add(Symbol.EQUALS, null)
388+ .add(Symbol.COMMA, null)
389+ .add(Symbol.CLOSE_PAREN, null)
390+ .add(Symbol.CLOSE_ARRAY, null)
391+ .add(Symbol.WHITE_SPACE, null)
392+ .add(Symbol.END, null)
393+ .build();
394+table[Tree.FOLLOWS_BOOL] = ObjectBuilder
395+ .add(Symbol.PLUS, null)
396+ .add(Symbol.MINUS, null)
397+ .add(Symbol.ASTERISK, null)
398+ .add(Symbol.DIVIDE, null)
399+ .add(Symbol.CARROT, null)
400+ .add(Symbol.PERCENT, null)
401+ .add(Symbol.AMPERSAND, null)
402+ .add(Symbol.GREATER_THAN, null)
403+ .add(Symbol.LESS_THAN, null)
404+ .add(Symbol.EQUALS, null)
405+ .add(Symbol.COMMA, null)
406+ .add(Symbol.CLOSE_PAREN, null)
407+ .add(Symbol.CLOSE_ARRAY, null)
408+ .add(Symbol.WHITE_SPACE, null)
409+ .add(Symbol.END, null)
410+ .build();
411+table[Tree.FOLLOWS_ERROR] = ObjectBuilder
412+ .add(Symbol.PLUS, null)
413+ .add(Symbol.MINUS, null)
414+ .add(Symbol.ASTERISK, null)
415+ .add(Symbol.DIVIDE, null)
416+ .add(Symbol.CARROT, null)
417+ .add(Symbol.PERCENT, null)
418+ .add(Symbol.AMPERSAND, null)
419+ .add(Symbol.GREATER_THAN, null)
420+ .add(Symbol.LESS_THAN, null)
421+ .add(Symbol.EQUALS, null)
422+ .add(Symbol.WHITE_SPACE, null)
423+ .add(Symbol.END, null)
424+ .build();
425+table[Tree.FOLLOWS_FORMULA] = ObjectBuilder
426+ .add(Symbol.NUMBER, null)
427+ .add(Symbol.STRING, null)
428+ .add(Symbol.BOOLEAN, null)
429+ .add(Symbol.FORMULA, null)
430+ .add(Symbol.CELL_REF, null)
431+ .add(Symbol.FIXED_CELL_REF, null)
432+ .add(Symbol.PERIOD, null) // TODO: Do we really need period? Why can't we capture this as a number w/ the rule-regex?
433+ .add(Symbol.ERROR, null)
434+ .add(Symbol.POUND, null)
435+ .add(Symbol.PLUS, null)
436+ .add(Symbol.MINUS, null)
437+ .add(Symbol.OPEN_PAREN, null)
438+ .add(Symbol.OPEN_ARRAY, null)
439+ .add(Symbol.WHITE_SPACE, null)
440+ .add(Symbol.END, null)
441+ .build();
442+table[Tree.FOLLOWS_PLUS] = ObjectBuilder
443+ .add(Symbol.NUMBER, null)
444+ .add(Symbol.STRING, null)
445+ .add(Symbol.BOOLEAN, null)
446+ .add(Symbol.PLUS, null)
447+ .add(Symbol.MINUS, null)
448+ .add(Symbol.PERIOD, null)
449+ .add(Symbol.CELL_REF, null)
450+ .add(Symbol.FIXED_CELL_REF, null)
451+ .add(Symbol.POUND, null)
452+ .add(Symbol.FORMULA, null)
453+ .add(Symbol.OPEN_PAREN, null)
454+ .add(Symbol.OPEN_ARRAY, null)
455+ .add(Symbol.WHITE_SPACE, null)
456+ .build();
457+table[Tree.FOLLOWS_MINUS] = ObjectBuilder
458+ .add(Symbol.NUMBER, null)
459+ .add(Symbol.STRING, null)
460+ .add(Symbol.BOOLEAN, null)
461+ .add(Symbol.PLUS, null)
462+ .add(Symbol.MINUS, null)
463+ .add(Symbol.PERIOD, null)
464+ .add(Symbol.CELL_REF, null)
465+ .add(Symbol.FIXED_CELL_REF, null)
466+ .add(Symbol.POUND, null)
467+ .add(Symbol.FORMULA, null)
468+ .add(Symbol.OPEN_PAREN, null)
469+ .add(Symbol.OPEN_ARRAY, null)
470+ .add(Symbol.WHITE_SPACE, null)
471+ .build();
472+table[Tree.FOLLOWS_ASTERISK] = ObjectBuilder
473+ .add(Symbol.NUMBER, null)
474+ .add(Symbol.STRING, null)
475+ .add(Symbol.BOOLEAN, null)
476+ .add(Symbol.PLUS, null)
477+ .add(Symbol.MINUS, null)
478+ .add(Symbol.PERIOD, null)
479+ .add(Symbol.CELL_REF, null)
480+ .add(Symbol.FIXED_CELL_REF, null)
481+ .add(Symbol.POUND, null)
482+ .add(Symbol.FORMULA, null)
483+ .add(Symbol.OPEN_PAREN, null)
484+ .add(Symbol.OPEN_ARRAY, null)
485+ .add(Symbol.WHITE_SPACE, null)
486+ .build();
487+table[Tree.FOLLOWS_SLASH] = ObjectBuilder
488+ .add(Symbol.NUMBER, null)
489+ .add(Symbol.STRING, null)
490+ .add(Symbol.BOOLEAN, null)
491+ .add(Symbol.PLUS, null)
492+ .add(Symbol.MINUS, null)
493+ .add(Symbol.PERIOD, null)
494+ .add(Symbol.CELL_REF, null)
495+ .add(Symbol.FIXED_CELL_REF, null)
496+ .add(Symbol.POUND, null)
497+ .add(Symbol.FORMULA, null)
498+ .add(Symbol.OPEN_PAREN, null)
499+ .add(Symbol.OPEN_ARRAY, null)
500+ .add(Symbol.WHITE_SPACE, null)
501+ .build();
502+table[Tree.FOLLOWS_CARROT] = ObjectBuilder
503+ .add(Symbol.NUMBER, null)
504+ .add(Symbol.STRING, null)
505+ .add(Symbol.BOOLEAN, null)
506+ .add(Symbol.PLUS, null)
507+ .add(Symbol.MINUS, null)
508+ .add(Symbol.PERIOD, null)
509+ .add(Symbol.CELL_REF, null)
510+ .add(Symbol.FIXED_CELL_REF, null)
511+ .add(Symbol.POUND, null)
512+ .add(Symbol.FORMULA, null)
513+ .add(Symbol.OPEN_PAREN, null)
514+ .add(Symbol.OPEN_ARRAY, null)
515+ .add(Symbol.WHITE_SPACE, null)
516+ .build();
517+table[Tree.FOLLOWS_AMPERSAND] = ObjectBuilder
518+ .add(Symbol.NUMBER, null)
519+ .add(Symbol.STRING, null)
520+ .add(Symbol.BOOLEAN, null)
521+ .add(Symbol.PLUS, null)
522+ .add(Symbol.MINUS, null)
523+ .add(Symbol.PERIOD, null)
524+ .add(Symbol.CELL_REF, null)
525+ .add(Symbol.FIXED_CELL_REF, null)
526+ .add(Symbol.POUND, null)
527+ .add(Symbol.FORMULA, null)
528+ .add(Symbol.OPEN_PAREN, null)
529+ .add(Symbol.OPEN_ARRAY, null)
530+ .add(Symbol.WHITE_SPACE, null)
531+ .build();
532+table[Tree.FOLLOWS_PERCENT] = ObjectBuilder
533+ .add(Symbol.PLUS, null)
534+ .add(Symbol.MINUS, null)
535+ .add(Symbol.ASTERISK, null)
536+ .add(Symbol.DIVIDE, null)
537+ .add(Symbol.CARROT, null)
538+ .add(Symbol.AMPERSAND, null)
539+ .add(Symbol.COMMA, null)
540+ .add(Symbol.OPEN_PAREN, null)
541+ .add(Symbol.OPEN_ARRAY, null)
542+ .add(Symbol.WHITE_SPACE, null)
543+ .add(Symbol.END, null)
544+ .build();
545+table[Tree.FOLLOWS_PERIOD] = ObjectBuilder
546+ .add(Symbol.PLUS, null)
547+ .add(Symbol.MINUS, null)
548+ .add(Symbol.ASTERISK, null)
549+ .add(Symbol.DIVIDE, null)
550+ .add(Symbol.CARROT, null)
551+ .add(Symbol.PERCENT, null)
552+ .add(Symbol.AMPERSAND, null)
553+ .add(Symbol.GREATER_THAN, null)
554+ .add(Symbol.LESS_THAN, null)
555+ .add(Symbol.EQUALS, null)
556+ .add(Symbol.WHITE_SPACE, null)
557+ .add(Symbol.END, null)
558+ .build();
559+table[Tree.FOLLOWS_LESS_THAN] = ObjectBuilder
560+ .add(Symbol.NUMBER, Tree.FOLLOWS_NUMBER)
561+ .add(Symbol.STRING, null)
562+ .add(Symbol.BOOLEAN, null)
563+ .add(Symbol.FORMULA, null)
564+ .add(Symbol.CELL_REF, null)
565+ .add(Symbol.FIXED_CELL_REF, null)
566+ .add(Symbol.ERROR, null)
567+ .add(Symbol.OPEN_ARRAY, null)
568+ .add(Symbol.OPEN_PAREN, null)
569+ .add(Symbol.PLUS, null)
570+ .add(Symbol.MINUS, null)
571+ .add(Symbol.PERIOD, null)
572+ .add(Symbol.WHITE_SPACE, null)
573+ .add(Symbol.END, null)
574+ .build();
575+table[Tree.FOLLOWS_GREATER_THAN] = ObjectBuilder
576+ .add(Symbol.NUMBER, Tree.FOLLOWS_NUMBER)
577+ .add(Symbol.STRING, null)
578+ .add(Symbol.BOOLEAN, null)
579+ .add(Symbol.FORMULA, null)
580+ .add(Symbol.CELL_REF, null)
581+ .add(Symbol.FIXED_CELL_REF, null)
582+ .add(Symbol.ERROR, null)
583+ .add(Symbol.OPEN_ARRAY, null)
584+ .add(Symbol.OPEN_PAREN, null)
585+ .add(Symbol.PLUS, null)
586+ .add(Symbol.MINUS, null)
587+ .add(Symbol.PERIOD, null)
588+ .add(Symbol.WHITE_SPACE, null)
589+ .add(Symbol.END, null)
590+ .build();;
591+table[Tree.FOLLOWS_EQUALS] = ObjectBuilder
592+ .add(Symbol.NUMBER, Tree.FOLLOWS_NUMBER)
593+ .add(Symbol.STRING, null)
594+ .add(Symbol.BOOLEAN, null)
595+ .add(Symbol.FORMULA, null)
596+ .add(Symbol.CELL_REF, null)
597+ .add(Symbol.FIXED_CELL_REF, null)
598+ .add(Symbol.ERROR, null)
599+ .add(Symbol.OPEN_ARRAY, null)
600+ .add(Symbol.OPEN_PAREN, null)
601+ .add(Symbol.PLUS, null)
602+ .add(Symbol.MINUS, null)
603+ .add(Symbol.PERIOD, null)
604+ .add(Symbol.WHITE_SPACE, null)
605+ .add(Symbol.END, null)
606+ .build();;
607+table[Tree.FOLLOWS_COMMA] = ObjectBuilder
608+ .add(Symbol.NUMBER, Tree.FOLLOWS_NUMBER)
609+ .add(Symbol.STRING, null)
610+ .add(Symbol.BOOLEAN, null)
611+ .add(Symbol.FORMULA, null)
612+ .add(Symbol.CELL_REF, null)
613+ .add(Symbol.FIXED_CELL_REF, null)
614+ .add(Symbol.ERROR, null)
615+ .add(Symbol.PLUS, null)
616+ .add(Symbol.MINUS, null)
617+ .add(Symbol.PERIOD, null)
618+ .add(Symbol.OPEN_PAREN, null)
619+ .add(Symbol.OPEN_ARRAY, null)
620+ .add(Symbol.WHITE_SPACE, null)
621+ .add(Symbol.END, null)
622+ .build();
623+table[Tree.FOLLOWS_OPEN_PAREN] = ObjectBuilder
624+ .add(Symbol.NUMBER, Tree.FOLLOWS_NUMBER)
625+ .add(Symbol.STRING, null)
626+ .add(Symbol.BOOLEAN, null)
627+ .add(Symbol.FORMULA, null)
628+ .add(Symbol.CELL_REF, null)
629+ .add(Symbol.FIXED_CELL_REF, null)
630+ .add(Symbol.ERROR, null)
631+ .add(Symbol.PLUS, null)
632+ .add(Symbol.MINUS, null)
633+ .add(Symbol.PERIOD, null)
634+ .add(Symbol.OPEN_PAREN, null)
635+ .add(Symbol.OPEN_ARRAY, null)
636+ .add(Symbol.WHITE_SPACE, null)
637+ .build();
638+table[Tree.FOLLOWS_CLOSE_PAREN] = ObjectBuilder
639+ .add(Symbol.PLUS, null)
640+ .add(Symbol.MINUS, null)
641+ .add(Symbol.ASTERISK, null)
642+ .add(Symbol.DIVIDE, null)
643+ .add(Symbol.PERCENT, null)
644+ .add(Symbol.CARROT, null)
645+ .add(Symbol.COMMA, null)
646+ .add(Symbol.CLOSE_ARRAY, null)
647+ .add(Symbol.WHITE_SPACE, null)
648+ .add(Symbol.END, null)
649+ .build();
650+table[Tree.FOLLOWS_CELL_REF] = ObjectBuilder
651+ .add(Symbol.PLUS, null)
652+ .add(Symbol.MINUS, null)
653+ .add(Symbol.ASTERISK, null)
654+ .add(Symbol.DIVIDE, null)
655+ .add(Symbol.CARROT, null)
656+ .add(Symbol.PERCENT, null)
657+ .add(Symbol.AMPERSAND, null)
658+ .add(Symbol.GREATER_THAN, null)
659+ .add(Symbol.LESS_THAN, null)
660+ .add(Symbol.EQUALS, null)
661+ .add(Symbol.COMMA, null)
662+ .add(Symbol.CLOSE_PAREN, null)
663+ .add(Symbol.CLOSE_ARRAY, null)
664+ .add(Symbol.WHITE_SPACE, null)
665+ .add(Symbol.END, null)
666+ .build();
667+table[Tree.FOLLOWS_FIXED_CELL_REF] = ObjectBuilder
668+ .add(Symbol.PLUS, null)
669+ .add(Symbol.MINUS, null)
670+ .add(Symbol.ASTERISK, null)
671+ .add(Symbol.DIVIDE, null)
672+ .add(Symbol.CARROT, null)
673+ .add(Symbol.PERCENT, null)
674+ .add(Symbol.AMPERSAND, null)
675+ .add(Symbol.GREATER_THAN, null)
676+ .add(Symbol.LESS_THAN, null)
677+ .add(Symbol.EQUALS, null)
678+ .add(Symbol.COMMA, null)
679+ .add(Symbol.CLOSE_PAREN, null)
680+ .add(Symbol.CLOSE_ARRAY, null)
681+ .add(Symbol.WHITE_SPACE, null)
682+ .add(Symbol.END, null)
683+ .build();
684+table[Tree.FOLLOWS_CELL_RANGE_REF] = ObjectBuilder
685+ .add(Symbol.PLUS, null)
686+ .add(Symbol.MINUS, null)
687+ .add(Symbol.ASTERISK, null)
688+ .add(Symbol.DIVIDE, null)
689+ .add(Symbol.CARROT, null)
690+ .add(Symbol.PERCENT, null)
691+ .add(Symbol.AMPERSAND, null)
692+ .add(Symbol.GREATER_THAN, null)
693+ .add(Symbol.LESS_THAN, null)
694+ .add(Symbol.EQUALS, null)
695+ .add(Symbol.COMMA, null)
696+ .add(Symbol.CLOSE_PAREN, null)
697+ .add(Symbol.CLOSE_ARRAY, null)
698+ .add(Symbol.WHITE_SPACE, null)
699+ .add(Symbol.END, null)
700+ .build();
701+table[Tree.FOLLOWS_FIXED_CELL_RANGE_REF] = ObjectBuilder
702+ .add(Symbol.PLUS, null)
703+ .add(Symbol.MINUS, null)
704+ .add(Symbol.ASTERISK, null)
705+ .add(Symbol.DIVIDE, null)
706+ .add(Symbol.CARROT, null)
707+ .add(Symbol.PERCENT, null)
708+ .add(Symbol.AMPERSAND, null)
709+ .add(Symbol.GREATER_THAN, null)
710+ .add(Symbol.LESS_THAN, null)
711+ .add(Symbol.EQUALS, null)
712+ .add(Symbol.COMMA, null)
713+ .add(Symbol.CLOSE_PAREN, null)
714+ .add(Symbol.CLOSE_ARRAY, null)
715+ .add(Symbol.WHITE_SPACE, null)
716+ .add(Symbol.END, null)
717+ .build();
718+table[Tree.FOLLOWS_OPEN_ARRAY] = ObjectBuilder
719+ .add(Symbol.NUMBER, Tree.FOLLOWS_NUMBER)
720+ .add(Symbol.STRING, null)
721+ .add(Symbol.BOOLEAN, null)
722+ .add(Symbol.FORMULA, null)
723+ .add(Symbol.CELL_REF, null)
724+ .add(Symbol.FIXED_CELL_REF, null)
725+ .add(Symbol.ERROR, null)
726+ .add(Symbol.PLUS, null)
727+ .add(Symbol.MINUS, null)
728+ .add(Symbol.PERIOD, null)
729+ .add(Symbol.OPEN_PAREN, null)
730+ .add(Symbol.OPEN_ARRAY, null)
731+ .add(Symbol.CLOSE_ARRAY, null)
732+ .add(Symbol.WHITE_SPACE, null)
733+ .build();
734+table[Tree.FOLLOWS_CLOSE_ARRAY] = ObjectBuilder
735+ .add(Symbol.PLUS, null)
736+ .add(Symbol.MINUS, null)
737+ .add(Symbol.ASTERISK, null)
738+ .add(Symbol.DIVIDE, null)
739+ .add(Symbol.PERCENT, null)
740+ .add(Symbol.CARROT, null)
741+ .add(Symbol.COMMA, null)
742+ .add(Symbol.CLOSE_PAREN, null)
743+ .add(Symbol.CLOSE_ARRAY, null)
744+ .add(Symbol.WHITE_SPACE, null)
745+ .add(Symbol.END, null)
746+ .build();
747+
748+
749+table[Tree.TERMINATE] = undefined; // Terminate the end.
750\ No newline at end of file
751diff --git a/src/Parser/ParserConstants.ts b/src/Parser/ParserConstants.ts
752index 07a908e..31bd4b4 100644
753--- a/src/Parser/ParserConstants.ts
754+++ b/src/Parser/ParserConstants.ts
755@@ -1,3 +1,6 @@
756+import {
757+ ObjectBuilder
758+} from "./ObjectBuilder";
759
760 // Rules represent the Regular Expressions that will be used in sequence to match a given input to the Parser.
761 const WHITE_SPACE_RULE = /^(?:\s+)/; // rule 0
762@@ -318,7 +321,7 @@ symbolIndexToName[Symbol.ASTERISK] = "*";
763 symbolIndexToName[Symbol.DIVIDE] = "/";
764 symbolIndexToName[Symbol.CARROT] = "^";
765 symbolIndexToName[Symbol.FUNCTION] = "FUNCTION";
766-symbolIndexToName[Symbol.FIXEDCELL] = "FIXEDCELL";
767+symbolIndexToName[Symbol.FIXEDCELL] = "FIXED_CELL_REF";
768 symbolIndexToName[Symbol.COLON] = ";";
769 symbolIndexToName[Symbol.COMMA] = ",";
770 symbolIndexToName[Symbol.VARIABLE] = "VARIABLE";
771@@ -332,23 +335,6 @@ const SYMBOL_INDEX_TO_NAME = symbolIndexToName;
772
773
774
775-class ObjectBuilder {
776- public o : Object = {};
777-
778- public static add(k, v) : ObjectBuilder {
779- let m = new ObjectBuilder();
780- m.o[k.toString()] = v;
781- return m;
782- }
783- public add(k, v) : ObjectBuilder {
784- this.o[k.toString()] = v;
785- return this;
786- }
787- public build() : Object {
788- return this.o;
789- }
790-}
791-
792 /**
793 * Array of to map rules to to LexActions and other rules. A single index in the object (e.g. `{2: 13}`) indicates the
794 * rule object to follow for the next token, while an array (e.g. `{23: [1, ReduceActions.LTE]}`) indicates the action to be taken,