-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.js
More file actions
82 lines (73 loc) · 1.66 KB
/
parser.js
File metadata and controls
82 lines (73 loc) · 1.66 KB
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
82
/**
* An abstract token
*/
class Token {
constructor(valueOf) {
this.valueOf = valueOf;
}
}
/**
* An identifier
*/
class Identifier extends Token {}
/**
* An operator
*/
class Operator extends Token {
static testOperator(candidate) {
return /^[!=<>]{1,3}$/.test(candidate);
}
}
/**
* A value
*/
class Value extends Token {
static testFloat(candidate) {
return /^-?[0-9]+\.[0-9]*$/.test(candidate);
}
static testInteger(candidate) {
return /^-?[0-9]+$/.test(candidate);
}
static testDoubleQuotedString(candidate) {
return candidate[0] === '"' && '"' === candidate[candidate.length - 1];
}
static testSingleQuotedString(candidate) {
return candidate[0] === "'" && "'" === candidate[candidate.length - 1];
}
}
/**
* A lava code parser
*/
class Parser {
static parse(code) {
return code.replace(/\s*;\s*/g, '\n').split('\n').map(
line => line.split(' ').reduce(
(current, segment) => Parser.tokenize(current, segment), []
)
);
}
static tokenize(current, segment) {
if (Operator.testOperator(segment)) {
current.push(new Operator(segment));
}
else if (Value.testFloat(segment)) {
current.push(new Value(parseFloat(segment)));
}
else if (Value.testInteger(segment)) {
current.push(new Value(parseInt(segment)));
}
else if (Value.testDoubleQuotedString(segment) || Value.testSingleQuotedString(segment)) {
current.push(new Value(segment.substr(1, segment.length - 2)));
}
else if (segment.length > 0) {
current.push(new Identifier(segment));
}
return current;
}
}
module.exports = {
Identifier,
Operator,
Value,
Parser
};