-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlexer.js
58 lines (53 loc) · 2.07 KB
/
lexer.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
// lexer.js - A simple lexer in javascript
//
// Author: Simon Pratt
// License: ISC
// Website: http://blog.pr4tt.com/lc2.js/
var lexer = (function(lexer, undefined) {
lexer.debug = false;
lexer.log = function(o) { if(lexer.debug) console.log(o); };
lexer.dir = function(o) { if(lexer.debug) console.dir(o); };
lexer.lex = function(str,spec) {
var tokens = [];
var state = spec.start_state;
lexer.log('len: ' + str.length);
str.split('\n').forEach(function(line_str,line_num) {
lexer.log(line_num + ': "' + line_str + '"');
line_str += '\n'; // replace removed newline
var start = 0;
while(start < line_str.length) {
lexer.log('start: ' + start);
var matched = false;
var patterns = spec.states[state];
for(var i = 0; i < patterns.length; ++i) {
var pattern = patterns[i];
var matches = pattern.regex.exec(line_str.substring(start));
lexer.dir(matches);
if(matches) {
var match = matches[1] || matches[0];
if('type' in pattern) {
tokens.push({
type: pattern.type,
val: match,
line: line_num+1
});
}
if('next_state' in pattern) {
state = pattern.next_state;
}
matched = true;
start += matches[0].length;
break;
}
}
if(!matched)
throw new Error('No pattern matched on line ' + (line_num+1) +
', character ' + start);
lexer.log('end: ' + start);
lexer.log('state: ' + state);
}
});
return tokens;
};
return lexer;
})(lexer || {});