-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsentence-parser.ts
81 lines (73 loc) · 2.57 KB
/
sentence-parser.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// A Custom Parser for creating an Abstract Syntax Tree
import IAbstractExpression from './iabstract-expression';
import Add from './add';
import Numeral from './numeral';
import RomanNumeral from './roman-numeral';
import Subtract from './subtract';
export default class Parser {
// Dynamically create the Abstract Syntax Tree
static parse(sentence: string): IAbstractExpression | undefined {
// Create the AST from the sentence
const tokens = sentence.split(' ');
const tree: IAbstractExpression[] = []; // Abstract Syntax Tree
while (tokens.length > 1) {
const leftExpression = Parser.decideLeftExpression(tree, tokens);
// get the operator, make the token list shorter
const operator = tokens.shift();
const right = tokens[0];
if (!Number(right)) {
tree.push(new RomanNumeral(right));
if (operator === '-') {
tree.push(new Subtract(leftExpression, tree[tree.length - 1]));
}
if (operator === '+') {
tree.push(new Add(leftExpression, tree[tree.length - 1]));
}
} else {
const rightExpression = new Numeral(right);
if (!tree.length) {
// Empty Data Structures return False by default
if (operator === '-') {
tree.push(new Subtract(leftExpression, rightExpression));
}
if (operator === '+') {
tree.push(new Add(leftExpression, rightExpression));
}
} else {
if (operator === '-') {
tree.push(new Subtract(tree[tree.length - 1], rightExpression));
}
if (operator === '+') {
tree.push(new Add(tree[tree.length - 1], rightExpression));
}
}
}
}
return tree.pop();
}
static decideLeftExpression(
tree: IAbstractExpression[],
tokens: string[]
): IAbstractExpression {
// On the First iteration, the left expression can be either a
// number or roman numeral.Every consecutive expression is
// reference to an existing AST row
const left = tokens.shift();
let leftExpression: IAbstractExpression;
if (!tree.length) {
// only applicable if first round
if (!Number(left)) {
// if 1st token a roman numeral
tree = [];
tree.push(new RomanNumeral(left as string));
leftExpression = tree[tree.length - 1] as IAbstractExpression;
} else {
leftExpression = new Numeral(left as string);
}
return leftExpression;
} else {
leftExpression = tree[tree.length - 1] as IAbstractExpression;
return leftExpression;
}
}
}