UNPKG

2.12 kBJavaScriptView Raw
1var debug = require('debug');
2var tokens = require('./tokens');
3
4// This pattern and basic lexer code were originally from the
5// Jade lexer, but have been modified:
6// https://github.com/visionmedia/jade/blob/master/lib/lexer.js
7
8function VLexer(){
9 this.lg = debug('vash:lexer');
10 this.input = '';
11 this.originalInput = '';
12 this.lineno = 1;
13 this.charno = 0;
14}
15
16module.exports = VLexer;
17
18VLexer.prototype = {
19
20 write: function(input) {
21 var normalized = input.replace(/\r\n|\r/g, '\n');
22
23 // Kill BOM if this is the first chunk.
24 if (this.originalInput.length == 0) {
25 normalized = normalized.replace(/^\uFEFF/, '');
26 }
27
28 this.input += normalized;
29 this.originalInput += normalized;
30 return true;
31 },
32
33 read: function() {
34 var out = []
35 , result;
36 while(this.input.length) {
37 result = this.advance();
38 if (result) {
39 out.push(result);
40 this.lg('Read %s at line %d, column %d with content %s',
41 result.type, result.line, result.chr, result.val.replace(/(\n)/, '\\n'));
42 }
43 }
44 return out;
45 },
46
47 scan: function(regexp, type){
48 var captures, token;
49 if (captures = regexp.exec(this.input)) {
50 this.input = this.input.substr((captures[1].length));
51
52 token = {
53 type: type
54 ,line: this.lineno
55 ,chr: this.charno
56 ,val: captures[1] || ''
57 ,toString: function(){
58 return '[' + this.type
59 + ' (' + this.line + ',' + this.chr + '): '
60 + this.val.replace(/(\n)/, '\\n') + ']';
61 }
62 };
63
64 this.charno += captures[0].length;
65 return token;
66 }
67 }
68
69 ,advance: function() {
70
71 var i, name, test, result;
72
73 for(i = 0; i < tokens.tests.length; i += 2){
74 test = tokens.tests[i+1];
75 test.displayName = tokens.tests[i];
76
77 if(typeof test === 'function'){
78 // assume complex callback
79 result = test.call(this);
80 }
81
82 if(typeof test.exec === 'function'){
83 // assume regex
84 result = this.scan(test, tokens.tests[i]);
85 }
86
87 if( result ){
88 return result;
89 }
90 }
91 }
92}