-
Notifications
You must be signed in to change notification settings - Fork 8
/
parse.js
81 lines (63 loc) · 1.94 KB
/
parse.js
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
module.exports.parse = parse;
/*
This file is part of llang.
llang is MIT licensed. Feel free to use it, contribute or spread the word. Created with love by Petr Nevyhoštěný (Twitter).
*/
function parse(tokens) {
var token;
return process();
function process(operation) {
operation = operation || null;
var args = [];
while (next()) {
if (token.type == 'boundary') {
if (token.value == '(') args.push(process());
else if (token.value == ')') return node(operation, args);
}
else if (token.type == 'variable') {
args.push(node('substitution', [ token.value ]));
if (isUnary(operation)) return node(operation, args);
}
else if (token.type == 'operator') {
if (isUnary(token.value)) {
args.push(process(token.value));
continue;
}
if (operation) {
var tmp = args.slice(0);
args = [];
args.push(node(operation, tmp));
}
operation = token.value;
}
}
return node(operation, args);
}
function next() {
//TODO: use pointer instead of shifting
//(parse would not need to clone tokens array)
return (token = tokens.shift());
}
function node(action, args) {
return {
action: translate(action),
args: args
};
}
function translate(operator) {
var map = {
'!': 'negation',
'|': 'disjunction',
'&': 'conjunction',
'->': 'implication',
'<->': 'equivalence'
};
return map[operator] || operator;
}
function isUnary(op) {
return op === '!';
}
function syntaxError() {
throw new Error('Syntax error!');
}
}