scratch – Blame information for rev
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
66 | office | 1 | var helpers = require('./helpers'); |
2 | // --- Lexer |
||
3 | |||
4 | /** |
||
5 | * YAML grammar tokens. |
||
6 | */ |
||
7 | |||
8 | var tokens = [ |
||
9 | ['comment', /^#[^\n]*/], |
||
10 | ['indent', /^\n( *)/], |
||
11 | ['space', /^ +/], |
||
12 | ['true', /^\b(enabled|true|yes|on)\b/], |
||
13 | ['false', /^\b(disabled|false|no|off)\b/], |
||
14 | ['null', /^\b(null|Null|NULL|~)\b/], |
||
15 | ['string', /^"(.*?)"/], |
||
16 | ['string', /^'(.*?)'/], |
||
17 | ['timestamp', /^((\d{4})-(\d\d?)-(\d\d?)(?:(?:[ \t]+)(\d\d?):(\d\d)(?::(\d\d))?)?)/], |
||
18 | ['float', /^(\d+\.\d+)/], |
||
19 | ['int', /^(\d+)/], |
||
20 | ['doc', /^---/], |
||
21 | [',', /^,/], |
||
22 | ['{', /^\{(?![^\n\}]*\}[^\n]*[^\s\n\}])/], |
||
23 | ['}', /^\}/], |
||
24 | ['[', /^\[(?![^\n\]]*\][^\n]*[^\s\n\]])/], |
||
25 | [']', /^\]/], |
||
26 | ['-', /^\-/], |
||
27 | [':', /^[:]/], |
||
28 | ['string', /^(?![^:\n\s]*:[^\/]{2})(([^:,\]\}\n\s]|(?!\n)\s(?!\s*?\n)|:\/\/|,(?=[^\n]*\s*[^\]\}\s\n]\s*\n)|[\]\}](?=[^\n]*\s*[^\]\}\s\n]\s*\n))*)(?=[,:\]\}\s\n]|$)/], |
||
29 | ['id', /^([\w|\/|\$][\w -]*)/ ] |
||
30 | ] |
||
31 | |||
32 | |||
33 | /** |
||
34 | * Tokenize the given _str_. |
||
35 | * |
||
36 | * @param {string} str |
||
37 | * @return {array} |
||
38 | * @api private |
||
39 | */ |
||
40 | |||
41 | exports.tokenize = function (str) { |
||
42 | var token, captures, ignore, input, |
||
43 | index = 0, |
||
44 | indents = 0, lastIndents = 0, |
||
45 | stack = [], indentAmount = -1 |
||
46 | |||
47 | // Windows new line support (CR+LF, \r\n) |
||
48 | str = str.replace(/\r\n/g, "\n"); |
||
49 | |||
50 | while (str.length) { |
||
51 | for (var i = 0, len = tokens.length; i < len; ++i) |
||
52 | if (captures = tokens[i][1].exec(str)) { |
||
53 | // token format: [tokenType, capturedToken, startIndex, endIndex] |
||
54 | token = [tokens[i][0], captures, index, index + captures[0].length - 1]; |
||
55 | str = str.replace(tokens[i][1], ''); |
||
56 | index += captures[0].length; |
||
57 | switch (token[0]) { |
||
58 | case 'comment': |
||
59 | ignore = true; |
||
60 | break; |
||
61 | case 'indent': |
||
62 | lastIndents = indents; |
||
63 | // determine the indentation amount from the first indent |
||
64 | if (indentAmount == -1) { |
||
65 | indentAmount = token[1][1].length; |
||
66 | } |
||
67 | |||
68 | indents = token[1][1].length / indentAmount; |
||
69 | |||
70 | if (indents === lastIndents || isNaN(indents)) { |
||
71 | ignore = true; |
||
72 | } |
||
73 | else if (indents > lastIndents + 1){ |
||
74 | throw new SyntaxError('invalid indentation, got ' + indents + ' instead of ' + (lastIndents + 1)); |
||
75 | } |
||
76 | else if (indents < lastIndents) {> |
||
77 | < lastIndents) { input = token[1].input;> |
||
78 | < lastIndents) { token = ['dedent'];> |
||
79 | < lastIndents) { token.input = input;> |
||
80 | < lastIndents) { while (--lastIndents > indents){> |
||
81 | < lastIndents) { stack.push(token)> |
||
82 | < lastIndents) { }> |
||
83 | < lastIndents) { }> |
||
84 | < lastIndents) { }> |
||
85 | < lastIndents) { break> |
||
86 | < lastIndents) { }> |
||
87 | < lastIndents) { if (!ignore)> |
||
88 | < lastIndents) { if (token)> |
||
89 | < lastIndents) { stack.push(token),> |
||
90 | < lastIndents) { token = null> |
||
91 | < lastIndents) { else> |
||
92 | < lastIndents) { throw new SyntaxError(helpers.context(str))> |
||
93 | < lastIndents) { ignore = false> |
||
94 | < lastIndents) { }> |
||
95 | < lastIndents) { return stack> |
||
96 | < lastIndents) {}> |