|
@@ -898,7 +898,7 @@ const unicodeLetterTable = [
|
|
|
195101,
|
|
195101,
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
-const identifierStartTable = [];
|
|
|
|
|
|
|
+const identifierStartTable: any[] = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < 128; i++) {
|
|
for (let i = 0; i < 128; i++) {
|
|
|
identifierStartTable[i] =
|
|
identifierStartTable[i] =
|
|
@@ -922,24 +922,28 @@ for (let i = 0; i < 128; i++) {
|
|
|
|
|
|
|
|
const identifierPartTable = identifierStartTable;
|
|
const identifierPartTable = identifierStartTable;
|
|
|
|
|
|
|
|
-export function Lexer(this: any, expression) {
|
|
|
|
|
- this.input = expression;
|
|
|
|
|
- this.char = 1;
|
|
|
|
|
- this.from = 1;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+export class Lexer {
|
|
|
|
|
+ input: any;
|
|
|
|
|
+ char: number;
|
|
|
|
|
+ from: number;
|
|
|
|
|
+
|
|
|
|
|
+ constructor(expression: any) {
|
|
|
|
|
+ this.input = expression;
|
|
|
|
|
+ this.char = 1;
|
|
|
|
|
+ this.from = 1;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-Lexer.prototype = {
|
|
|
|
|
- peek: function(i) {
|
|
|
|
|
|
|
+ peek(i?: number) {
|
|
|
return this.input.charAt(i || 0);
|
|
return this.input.charAt(i || 0);
|
|
|
- },
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- skip: function(i) {
|
|
|
|
|
|
|
+ skip(i?: number) {
|
|
|
i = i || 1;
|
|
i = i || 1;
|
|
|
this.char += i;
|
|
this.char += i;
|
|
|
this.input = this.input.slice(i);
|
|
this.input = this.input.slice(i);
|
|
|
- },
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- tokenize: function() {
|
|
|
|
|
|
|
+ tokenize() {
|
|
|
const list = [];
|
|
const list = [];
|
|
|
let token = this.next();
|
|
let token = this.next();
|
|
|
while (token) {
|
|
while (token) {
|
|
@@ -947,9 +951,9 @@ Lexer.prototype = {
|
|
|
token = this.next();
|
|
token = this.next();
|
|
|
}
|
|
}
|
|
|
return list;
|
|
return list;
|
|
|
- },
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- next: function() {
|
|
|
|
|
|
|
+ next() {
|
|
|
this.from = this.char;
|
|
this.from = this.char;
|
|
|
|
|
|
|
|
// Move to the next non-space character.
|
|
// Move to the next non-space character.
|
|
@@ -979,9 +983,9 @@ Lexer.prototype = {
|
|
|
|
|
|
|
|
// No token could be matched, give up.
|
|
// No token could be matched, give up.
|
|
|
return null;
|
|
return null;
|
|
|
- },
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- scanTemplateSequence: function() {
|
|
|
|
|
|
|
+ scanTemplateSequence() {
|
|
|
if (this.peek() === '[' && this.peek(1) === '[') {
|
|
if (this.peek() === '[' && this.peek(1) === '[') {
|
|
|
return {
|
|
return {
|
|
|
type: 'templateStart',
|
|
type: 'templateStart',
|
|
@@ -999,7 +1003,7 @@ Lexer.prototype = {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
return null;
|
|
|
- },
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
* Extract a JavaScript identifier out of the next sequence of
|
|
* Extract a JavaScript identifier out of the next sequence of
|
|
@@ -1007,7 +1011,7 @@ Lexer.prototype = {
|
|
|
* to Identifier this method can also produce BooleanLiteral
|
|
* to Identifier this method can also produce BooleanLiteral
|
|
|
* (true/false) and NullLiteral (null).
|
|
* (true/false) and NullLiteral (null).
|
|
|
*/
|
|
*/
|
|
|
- scanIdentifier: function() {
|
|
|
|
|
|
|
+ scanIdentifier() {
|
|
|
let id = '';
|
|
let id = '';
|
|
|
let index = 0;
|
|
let index = 0;
|
|
|
let type, char;
|
|
let type, char;
|
|
@@ -1020,7 +1024,7 @@ Lexer.prototype = {
|
|
|
// Both approach and unicodeLetterTable were borrowed from
|
|
// Both approach and unicodeLetterTable were borrowed from
|
|
|
// Google's Traceur.
|
|
// Google's Traceur.
|
|
|
|
|
|
|
|
- function isUnicodeLetter(code) {
|
|
|
|
|
|
|
+ function isUnicodeLetter(code: number) {
|
|
|
for (let i = 0; i < unicodeLetterTable.length; ) {
|
|
for (let i = 0; i < unicodeLetterTable.length; ) {
|
|
|
if (code < unicodeLetterTable[i++]) {
|
|
if (code < unicodeLetterTable[i++]) {
|
|
|
return false;
|
|
return false;
|
|
@@ -1034,7 +1038,7 @@ Lexer.prototype = {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function isHexDigit(str) {
|
|
|
|
|
|
|
+ function isHexDigit(str: string) {
|
|
|
return /^[0-9a-fA-F]$/.test(str);
|
|
return /^[0-9a-fA-F]$/.test(str);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1157,7 +1161,7 @@ Lexer.prototype = {
|
|
|
value: id,
|
|
value: id,
|
|
|
pos: this.char,
|
|
pos: this.char,
|
|
|
};
|
|
};
|
|
|
- },
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
* Extract a numeric literal out of the next sequence of
|
|
* Extract a numeric literal out of the next sequence of
|
|
@@ -1168,26 +1172,26 @@ Lexer.prototype = {
|
|
|
* This method's implementation was heavily influenced by the
|
|
* This method's implementation was heavily influenced by the
|
|
|
* scanNumericLiteral function in the Esprima parser's source code.
|
|
* scanNumericLiteral function in the Esprima parser's source code.
|
|
|
*/
|
|
*/
|
|
|
- scanNumericLiteral: function(): any {
|
|
|
|
|
|
|
+ scanNumericLiteral(): any {
|
|
|
let index = 0;
|
|
let index = 0;
|
|
|
let value = '';
|
|
let value = '';
|
|
|
const length = this.input.length;
|
|
const length = this.input.length;
|
|
|
let char = this.peek(index);
|
|
let char = this.peek(index);
|
|
|
let bad;
|
|
let bad;
|
|
|
|
|
|
|
|
- function isDecimalDigit(str) {
|
|
|
|
|
|
|
+ function isDecimalDigit(str: string) {
|
|
|
return /^[0-9]$/.test(str);
|
|
return /^[0-9]$/.test(str);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function isOctalDigit(str) {
|
|
|
|
|
|
|
+ function isOctalDigit(str: string) {
|
|
|
return /^[0-7]$/.test(str);
|
|
return /^[0-7]$/.test(str);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function isHexDigit(str) {
|
|
|
|
|
|
|
+ function isHexDigit(str: string) {
|
|
|
return /^[0-9a-fA-F]$/.test(str);
|
|
return /^[0-9a-fA-F]$/.test(str);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function isIdentifierStart(ch) {
|
|
|
|
|
|
|
+ function isIdentifierStart(ch: string) {
|
|
|
return ch === '$' || ch === '_' || ch === '\\' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
|
|
return ch === '$' || ch === '_' || ch === '\\' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1369,9 +1373,9 @@ Lexer.prototype = {
|
|
|
pos: this.char,
|
|
pos: this.char,
|
|
|
isMalformed: !isFinite(+value),
|
|
isMalformed: !isFinite(+value),
|
|
|
};
|
|
};
|
|
|
- },
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- isPunctuator: ch1 => {
|
|
|
|
|
|
|
+ isPunctuator(ch1: string) {
|
|
|
switch (ch1) {
|
|
switch (ch1) {
|
|
|
case '.':
|
|
case '.':
|
|
|
case '(':
|
|
case '(':
|
|
@@ -1383,9 +1387,9 @@ Lexer.prototype = {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
return false;
|
|
|
- },
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- scanPunctuator: function() {
|
|
|
|
|
|
|
+ scanPunctuator() {
|
|
|
const ch1 = this.peek();
|
|
const ch1 = this.peek();
|
|
|
|
|
|
|
|
if (this.isPunctuator(ch1)) {
|
|
if (this.isPunctuator(ch1)) {
|
|
@@ -1397,7 +1401,7 @@ Lexer.prototype = {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
return null;
|
|
|
- },
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
* Extract a string out of the next sequence of characters and/or
|
|
* Extract a string out of the next sequence of characters and/or
|
|
@@ -1410,7 +1414,7 @@ Lexer.prototype = {
|
|
|
* var str = "hello\
|
|
* var str = "hello\
|
|
|
* world";
|
|
* world";
|
|
|
*/
|
|
*/
|
|
|
- scanStringLiteral: function() {
|
|
|
|
|
|
|
+ scanStringLiteral() {
|
|
|
/*jshint loopfunc:true */
|
|
/*jshint loopfunc:true */
|
|
|
const quote = this.peek();
|
|
const quote = this.peek();
|
|
|
|
|
|
|
@@ -1451,5 +1455,5 @@ Lexer.prototype = {
|
|
|
quote: quote,
|
|
quote: quote,
|
|
|
pos: this.char,
|
|
pos: this.char,
|
|
|
};
|
|
};
|
|
|
- },
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+}
|