forked from kybernetikos/Javathcript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJavathcriptParser.js
More file actions
92 lines (76 loc) · 2.52 KB
/
Copy pathJavathcriptParser.js
File metadata and controls
92 lines (76 loc) · 2.52 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
83
84
85
86
87
88
89
90
91
var JavathcriptParser = (function() {
/*
* expression = atomOrListOrObject | quotedAtomOrList
* atomOrList = atom | list | object
* object = '{' nameValue* '}
* nameValue = atom ':' expression
* quotedAtomOrList = ''' atomOrList
* list = '(' expression* ')'
* atom = Word | Num | QuotedString
*/
var expression = grammarRule(Alternation, function(exp) {
exp.either(atomOrListOrObject()).or(quotedAtomOrList());
});
var atomOrListOrObject = grammarRule(Alternation, function(atomOrListOrObject) {
atomOrListOrObject.either(atom()).or(list()).or(object());
});
var objectStart = new Symbol("{").discard();
objectStart.setAssembler(new Assembler(function(a) {
a.push(new UnevaluatedObj());
}));
var object = grammarRule(Track, function(object) {
object.first(objectStart).then(nameValue().repeating()).then(new Symbol("}").discard());
});
var nameValue = grammarRule(Track, function(nameValue) {
nameValue.first(atom()).then(new Symbol(":").discard()).then(expression());
}, new Assembler(function(a) {
var exp = a.pop();
var name = a.pop();
var obj = a.pop();
obj[name] = exp;
a.push(obj);
}));
var quotedAtomOrList = grammarRule(Sequence, function(quotedAtomOrList) {
quotedAtomOrList.first(new Symbol("'").discard()).then(atomOrListOrObject());
}, new Assembler(function(a) {
var val = a.pop();
a.push([new Atom("quote"), val]);
}));
var openBrace = new Symbol('(');
var list = grammarRule(Track, function(list) {
list.first(openBrace).then(expression().repeating()).then(new Symbol(')').discard());
}, new Assembler(function(a) {
var elements = Assembler.elementsAbove(a, "(");
a.push(elements.reverse());
}));
var string = new QuotedString();
string.setAssembler(Assembler.unary(function (token) {
return token.sval.substring(1, token.sval.length -1);
}));
var num = new Num();
num.setAssembler(Assembler.unary(function (token) {return token.nval;}));
var word = new Word();
word.setAssembler(Assembler.unary(function (token) {
token.sval.atom = true;
return new Atom(token.sval);
}));
var atom = grammarRule(Alternation, function(atom) {
atom.either(word).or(num).or(string);
});
return {
parse: function(s) {
var a = expression().completeMatch(new TokenAssembly(new JavathcriptTokenizer(s)));
if (a == null) {
throw new Error("Failed to parse "+s);
}
return a.pop();
},
parsePartial: function(tokA) {
var a = expression().bestMatch(tokA);
if (a == null) {
throw new Error("Failed to parse "+tokA);
}
return a;
}
};
})();