# -*- coding: utf-8 -*- # Copyright JS Foundation and other contributors, https://js.foundation/ # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from __future__ import absolute_import, unicode_literals
import re
from .objects import Object from .compat import xrange, unicode, uchr, uord from .character import Character, HEX_CONV, OCTAL_CONV from .messages import Messages from .token import Token
# Ran off the end of the file - the whole thing is a comment if self.trackComment:
loc.end = Position(
line=self.lineNumber,
column=self.index - self.lineStart
)
entry = Comment(
multiLine=True,
slice=[start + 2, self.index],
range=[start, self.index],
loc=loc
)
comments.append(entry)
# Backslash (U+005C) starts an escaped character.
id = self.getComplexIdentifier() if self.source[start] == '\\'else self.getIdentifier()
# There is no keyword or literal with only one character. # Thus, it must be an identifier. if len(id) == 1:
type = Token.Identifier elif self.isKeyword(id):
type = Token.Keyword elif id == 'null':
type = Token.NullLiteral elif id == 'true'or id == 'false':
type = Token.BooleanLiteral else:
type = Token.Identifier
if type isnot Token.Identifier and start + len(id) != self.index:
restore = self.index
self.index = start
self.tolerateUnexpectedToken(Messages.InvalidEscapedReservedWord)
self.index = restore
# Check for most common single-character punctuators.
str = self.source[self.index] if str in ( '(', '{',
): if str == '{':
self.curlyStack.append('{')
def isImplicitOctalLiteral(self): # Implicit octal, unless there is a non-octal digit. # (Annex B.1.1 on Numeric Literals) for i in xrange(self.index + 1, self.length):
ch = self.source[i] if ch in'89': returnFalse ifnot Character.isOctalDigit(ch): returnTrue returnTrue
def scanNumericLiteral(self):
start = self.index
ch = self.source[start] assert Character.isDecimalDigit(ch) or ch == '.', 'Numeric literal must start with a decimal digit or a decimal point'
num = '' if ch != '.':
num = self.source[self.index]
self.index += 1
ch = self.source[self.index]
# Hex number starts with '0x'. # Octal number starts with '0'. # Octal number in ES6 starts with '0o'. # Binary number in ES6 starts with '0b'. if num == '0': if ch in ('x', 'X'):
self.index += 1 return self.scanHexLiteral(start)
if ch in ('b', 'B'):
self.index += 1 return self.scanBinaryLiteral(start)
if ch in ('o', 'O'): return self.scanOctalLiteral(ch, start)
if ch and Character.isOctalDigit(ch): if self.isImplicitOctalLiteral(): return self.scanOctalLiteral(ch, start)
while Character.isDecimalDigit(self.source[self.index]):
num += self.source[self.index]
self.index += 1
ch = self.source[self.index]
if ch == '.':
num += self.source[self.index]
self.index += 1 while Character.isDecimalDigit(self.source[self.index]):
num += self.source[self.index]
self.index += 1
ch = self.source[self.index]
if ch in ('e', 'E'):
num += self.source[self.index]
self.index += 1
ch = self.source[self.index] if ch in ('+', '-'):
num += self.source[self.index]
self.index += 1
if Character.isDecimalDigit(self.source[self.index]): while Character.isDecimalDigit(self.source[self.index]):
num += self.source[self.index]
self.index += 1
else:
self.throwUnexpectedToken()
if Character.isIdentifierStart(self.source[self.index]):
self.throwUnexpectedToken()
value = float(num) return RawToken(
type=Token.NumericLiteral,
value=int(value) if value.is_integer() else value,
lineNumber=self.lineNumber,
lineStart=self.lineStart,
start=start,
end=self.index
)
else: if ch == '0': if Character.isDecimalDigit(self.source[self.index]): # Illegal: \01 \02 and so on
self.throwUnexpectedToken(Messages.TemplateOctalLiteral)
def testRegExp(self, pattern, flags): # The BMP character to use as a replacement for astral symbols when # translating an ES6 "u"-flagged pattern to an ES5-compatible # approximation. # Note: replacing with '\uFFFF' enables false positives in unlikely # scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid # pattern that would not be detected by this substitution.
astralSubstitute = '\uFFFF'
# Replace every Unicode escape sequence with the equivalent # BMP character or a constant ASCII code point in the case of # astral symbols. (See the above note on `astralSubstitute` # for more information.) def astralSub(m):
codePoint = int(m.group(1) or m.group(2), 16) if codePoint > 0x10FFFF:
self.tolerateUnexpectedToken(Messages.InvalidRegExp) elif codePoint <= 0xFFFF: return uchr(codePoint) return astralSubstitute
pattern = re.sub(r'\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})', astralSub, pattern)
# Replace each paired surrogate with a single ASCII symbol to # avoid throwing on regular expressions that are only valid in # combination with the "u" flag.
pattern = re.sub(r'[\uD800-\uDBFF][\uDC00-\uDFFF]', astralSubstitute, pattern)
# Return a regular expression object for this pattern-flag pair, or # `null` in case the current environment doesn't support the flags it # uses.
pyflags = 0 | re.M if'm'in flags else 0 | re.I if'i'in flags else 0 try: return re.compile(pattern, pyflags) except Exception:
self.tolerateUnexpectedToken(Messages.InvalidRegExp)
def scanRegExpBody(self):
ch = self.source[self.index] assert ch == '/', 'Regular expression literal must start with a slash'
if Character.isIdentifierStart(ch): return self.scanIdentifier()
# Very common: ( and ) and ; if ch in ('(', ')', ';'): return self.scanPunctuator()
# String literal starts with single quote (U+0027) or double quote (U+0022). if ch in ('\'', '"'): return self.scanStringLiteral()
# Dot (.) U+002E can also start a floating-point number, hence the need # to check the next character. if ch == '.': if Character.isDecimalDigit(self.source[self.index + 1]): return self.scanNumericLiteral()
return self.scanPunctuator()
if Character.isDecimalDigit(ch): return self.scanNumericLiteral()
# Template literals start with ` (U+0060) for template head # or } (U+007D) for template middle or template tail. if ch == '`'or (ch == '}'and self.curlyStack and self.curlyStack[-1] == '${'): return self.scanTemplate()
# Possible identifier start in a surrogate pair.
cp = ord(ch) if cp >= 0xD800 and cp < 0xDFFF:
cp = self.codePointAt(self.index)
ch = Character.fromCodePoint(cp) if Character.isIdentifierStart(ch): return self.scanIdentifier()
return self.scanPunctuator()
Messung V0.5
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.