-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathparser.js
More file actions
executable file
·104 lines (93 loc) · 3.12 KB
/
Copy pathparser.js
File metadata and controls
executable file
·104 lines (93 loc) · 3.12 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
92
93
94
95
96
97
98
99
100
101
102
103
var parser = (function (grammar) {
function indent(n) {
return new Array(n + 1).join(' ')
}
function makeParseTreeNode(text, terminalOrNonTerminal) {
return {
text : text,
matched : terminalOrNonTerminal,
children: [],
toString : function(i){
i = i || 0;
var p = [];
p.push(indent(i) + terminalOrNonTerminal.toString())
this.children.forEach(function(child){
p.push(child.toString(i+1));
});
return p.join('\n');
}
};
}
function identity(x) {
return x;
}
function terminalConsume(txt) {
var nextChar = txt[0];
if (this.matches(nextChar)) {
return makeParseTreeNode(nextChar, this);
}
}
function epsilonConsume(txt) {
return makeParseTreeNode('', this);
}
function nonTerminalConsume(txt) {
var that = this;
var parseResults = this.mappings.map(function (mapping) {
var childNodes = [], txtRemaining = txt;
var parsedOk = mapping.every(function (item) {
var childParseResult = item.consume(txtRemaining);
if (!childParseResult) {
return false;
}
childParseResult.parent = that;
childNodes.push(childParseResult);
txtRemaining = txtRemaining.substring(childParseResult.text.length);
return true;
});
if (parsedOk) {
var matchedText = txt.substring(0, txt.length - txtRemaining.length);
var node = makeParseTreeNode(matchedText, that);
node.children = childNodes;
return node;
} else {
return;
}
});
var r = parseResults.filter(identity);
var biggestMatch = r.sort(function (r1, r2) {
return r2.text.length - r1.text.length;
})[0];
return biggestMatch;
}
function addConsumeMethod(node) {
if (!node.consume) {
if (node.isTerminal) {
if (node.isEpsilon) {
node.consume = epsilonConsume;
} else {
node.consume = terminalConsume;
}
} else {
node.consume = nonTerminalConsume;
}
}
}
grammar.productionRules.forEach(function (nonTerminal) {
addConsumeMethod(nonTerminal);
nonTerminal.mappings.forEach(function (mappingItems) {
mappingItems.forEach(addConsumeMethod);
});
});
return {
compile : function(regexText){
var ssn = grammar.startSymbolName;
var rootNode = grammar.productionRules.get(ssn).consume(regexText);
//console.log(rootNode.toString())
if (rootNode.text != regexText){
throw 'Unable to parse regex, consumed "' + rootNode.text + '"'
}
return regex(rootNode);
}
};
}(grammar));
handlers.apply(grammar);