Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/python/esprima/esprima/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 117 kB image not shown  

Quelle  parser.py

  Sprache: Python
 

# -*- 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

from .objects import Object
from .compat import basestring, unicode
from .utils import format
from .error_handler import ErrorHandler
from .messages import Messages
from .scanner import RawToken, Scanner, SourceLocation, Position, RegExp
from .token import Token, TokenName
from .syntax import Syntax
from . import nodes as Node


class Value(object):
    def __init__(self, value):
        self.value = value


class Params(object):
    def __init__(self, simple=None, message=None, stricted=None, firstRestricted=None, inFor=None, paramSet=None, params=None, get=None):
        self.simple = simple
        self.message = message
        self.stricted = stricted
        self.firstRestricted = firstRestricted
        self.inFor = inFor
        self.paramSet = paramSet
        self.params = params
        self.get = get


class Config(Object):
    def __init__(self, range=False, loc=False, source=None, tokens=False, comment=False, tolerant=False, **options):
        self.range = range
        self.loc = loc
        self.source = source
        self.tokens = tokens
        self.comment = comment
        self.tolerant = tolerant
        for k, v in options.items():
            setattr(self, k, v)


class Context(object):
    def __init__(self, isModule=False, allowAwait=False, allowIn=True, allowStrictDirective=True, allowYield=True, firstCoverInitializedNameError=None, isAssignmentTarget=False, isBindingElement=False, inFunctionBody=False, inIteration=False, inSwitch=FalselabelSet=None, strict=False):
        self.isModule = isModule
        self.allowAwait = allowAwait
        self.allowIn = allowIn
        self.allowStrictDirective = allowStrictDirective
        self.allowYield = allowYield
        self.firstCoverInitializedNameError = firstCoverInitializedNameError
        self.isAssignmentTarget = isAssignmentTarget
        self.isBindingElement = isBindingElement
        self.inFunctionBody = inFunctionBody
        self.inIteration = inIteration
        self.inSwitch = inSwitch
        self.labelSet = {} if labelSet is None else labelSet
        self.strict = strict


class Marker(object):
    def __init__(self, index=None, line=None, column=None):
        self.index = index
        self.line = line
        self.column = column


class TokenEntry(Object):
    def __init__(self, type=None, value=None, regex=None, range=None, loc=None):
        self.type = type
        self.value = value
        self.regex = regex
        self.range = range
        self.loc = loc


class Parser(object):
    def __init__(self, code, options={}, delegate=None):
        self.config = Config(**options)

        self.delegate = delegate

        self.errorHandler = ErrorHandler()
        self.errorHandler.tolerant = self.config.tolerant
        self.scanner = Scanner(code, self.errorHandler)
        self.scanner.trackComment = self.config.comment

        self.operatorPrecedence = {
            '||': 1,
            '&&': 2,
            '|': 3,
            '^': 4,
            '&': 5,
            '==': 6,
            '!=': 6,
            '===': 6,
            '!==': 6,
            '<': 7,
            '>': 7,
            '<=': 7,
            '>=': 7,
            'instanceof': 7,
            'in': 7,
            '<<': 8,
            '>>': 8,
            '>>>': 8,
            '+': 9,
            '-': 9,
            '*': 11,
            '/': 11,
            '%': 11,
        }

        self.lookahead = RawToken(
            type=Token.EOF,
            value='',
            lineNumber=self.scanner.lineNumber,
            lineStart=0,
            start=0,
            end=0
        )
        self.hasLineTerminator = False

        self.context = Context(
            isModule=False,
            allowAwait=False,
            allowIn=True,
            allowStrictDirective=True,
            allowYield=True,
            firstCoverInitializedNameError=None,
            isAssignmentTarget=False,
            isBindingElement=False,
            inFunctionBody=False,
            inIteration=False,
            inSwitch=False,
            labelSet={},
            strict=False
        )
        self.tokens = []

        self.startMarker = Marker(
            index=0,
            line=self.scanner.lineNumber,
            column=0
        )
        self.lastMarker = Marker(
            index=0,
            line=self.scanner.lineNumber,
            column=0
        )
        self.nextToken()
        self.lastMarker = Marker(
            index=self.scanner.index,
            line=self.scanner.lineNumber,
            column=self.scanner.index - self.scanner.lineStart
        )

    def throwError(self, messageFormat, *args):
        msg = format(messageFormat, *args)
        index = self.lastMarker.index
        line = self.lastMarker.line
        column = self.lastMarker.column + 1
        raise self.errorHandler.createError(index, line, column, msg)

    def tolerateError(self, messageFormat, *args):
        msg = format(messageFormat, *args)
        index = self.lastMarker.index
        line = self.scanner.lineNumber
        column = self.lastMarker.column + 1
        self.errorHandler.tolerateError(index, line, column, msg)

    # Throw an exception because of the token.

    def unexpectedTokenError(self, token=None, message=None):
        msg = message or Messages.UnexpectedToken
        if token:
            if not message:
                typ = token.type
                if typ is Token.EOF:
                    msg = Messages.UnexpectedEOS
                elif typ is Token.Identifier:
                    msg = Messages.UnexpectedIdentifier
                elif typ is Token.NumericLiteral:
                    msg = Messages.UnexpectedNumber
                elif typ is Token.StringLiteral:
                    msg = Messages.UnexpectedString
                elif typ is Token.Template:
                    msg = Messages.UnexpectedTemplate
                elif typ is Token.Keyword:
                    if self.scanner.isFutureReservedWord(token.value):
                        msg = Messages.UnexpectedReserved
                    elif self.context.strict and self.scanner.isStrictModeReservedWord(token.value):
                        msg = Messages.StrictReservedWord
                else:
                    msg = Messages.UnexpectedToken
            value = token.value
        else:
            value = 'ILLEGAL'

        msg = msg.replace('%0', unicode(value), 1)

        if token and isinstance(token.lineNumber, int):
            index = token.start
            line = token.lineNumber
            lastMarkerLineStart = self.lastMarker.index - self.lastMarker.column
            column = token.start - lastMarkerLineStart + 1
            return self.errorHandler.createError(index, line, column, msg)
        else:
            index = self.lastMarker.index
            line = self.lastMarker.line
            column = self.lastMarker.column + 1
            return self.errorHandler.createError(index, line, column, msg)

    def throwUnexpectedToken(self, token=None, message=None):
        raise self.unexpectedTokenError(token, message)

    def tolerateUnexpectedToken(self, token=None, message=None):
        self.errorHandler.tolerate(self.unexpectedTokenError(token, message))

    def collectComments(self):
        if not self.config.comment:
            self.scanner.scanComments()
        else:
            comments = self.scanner.scanComments()
            if comments:
                for e in comments:
                    if e.multiLine:
                        node = Node.BlockComment(self.scanner.source[e.slice[0]:e.slice[1]])
                    else:
                        node = Node.LineComment(self.scanner.source[e.slice[0]:e.slice[1]])
                    if self.config.range:
                        node.range = e.range
                    if self.config.loc:
                        node.loc = e.loc
                    if self.delegate:
                        metadata = SourceLocation(
                            start=Position(
                                line=e.loc.start.line,
                                column=e.loc.start.column,
                                offset=e.range[0],
                            ),
                            end=Position(
                                line=e.loc.end.line,
                                column=e.loc.end.column,
                                offset=e.range[1],
                            )
                        )
                        new_node = self.delegate(node, metadata)
                        if new_node is not None:
                            node = new_node

    # From internal representation to an external structure

    def getTokenRaw(self, token):
        return self.scanner.source[token.start:token.end]

    def convertToken(self, token):
        t = TokenEntry(
            type=TokenName[token.type],
            value=self.getTokenRaw(token),
        )
        if self.config.range:
            t.range = [token.start, token.end]
        if self.config.loc:
            t.loc = SourceLocation(
                start=Position(
                    line=self.startMarker.line,
                    column=self.startMarker.column,
                ),
                end=Position(
                    line=self.scanner.lineNumber,
                    column=self.scanner.index - self.scanner.lineStart,
                ),
            )
        if token.type is Token.RegularExpression:
            t.regex = RegExp(
                pattern=token.pattern,
                flags=token.flags,
            )

        return t

    def nextToken(self):
        token = self.lookahead

        self.lastMarker.index = self.scanner.index
        self.lastMarker.line = self.scanner.lineNumber
        self.lastMarker.column = self.scanner.index - self.scanner.lineStart

        self.collectComments()

        if self.scanner.index != self.startMarker.index:
            self.startMarker.index = self.scanner.index
            self.startMarker.line = self.scanner.lineNumber
            self.startMarker.column = self.scanner.index - self.scanner.lineStart

        next = self.scanner.lex()
        self.hasLineTerminator = token.lineNumber != next.lineNumber

        if next and self.context.strict and next.type is Token.Identifier:
            if self.scanner.isStrictModeReservedWord(next.value):
                next.type = Token.Keyword
        self.lookahead = next

        if self.config.tokens and next.type is not Token.EOF:
            self.tokens.append(self.convertToken(next))

        return token

    def nextRegexToken(self):
        self.collectComments()

        token = self.scanner.scanRegExp()
        if self.config.tokens:
            # Pop the previous token, '/' or '/='
            # self is added from the lookahead token.
            self.tokens.pop()

            self.tokens.append(self.convertToken(token))

        # Prime the next lookahead.
        self.lookahead = token
        self.nextToken()

        return token

    def createNode(self):
        return Marker(
            index=self.startMarker.index,
            line=self.startMarker.line,
            column=self.startMarker.column,
        )

    def startNode(self, token, lastLineStart=0):
        column = token.start - token.lineStart
        line = token.lineNumber
        if column < 0:
            column += lastLineStart
            line -= 1

        return Marker(
            index=token.start,
            line=line,
            column=column,
        )

    def finalize(self, marker, node):
        if self.config.range:
            node.range = [marker.index, self.lastMarker.index]

        if self.config.loc:
            node.loc = SourceLocation(
                start=Position(
                    line=marker.line,
                    column=marker.column,
                ),
                end=Position(
                    line=self.lastMarker.line,
                    column=self.lastMarker.column,
                ),
            )
            if self.config.source:
                node.loc.source = self.config.source

        if self.delegate:
            metadata = SourceLocation(
                start=Position(
                    line=marker.line,
                    column=marker.column,
                    offset=marker.index,
                ),
                end=Position(
                    line=self.lastMarker.line,
                    column=self.lastMarker.column,
                    offset=self.lastMarker.index,
                )
            )
            new_node = self.delegate(node, metadata)
            if new_node is not None:
                node = new_node

        return node

    # Expect the next token to match the specified punctuator.
    # If not, an exception will be thrown.

    def expect(self, value):
        token = self.nextToken()
        if token.type is not Token.Punctuator or token.value != value:
            self.throwUnexpectedToken(token)

    # Quietly expect a comma when in tolerant mode, otherwise delegates to expect().

    def expectCommaSeparator(self):
        if self.config.tolerant:
            token = self.lookahead
            if token.type is Token.Punctuator and token.value == ',':
                self.nextToken()
            elif token.type is Token.Punctuator and token.value == ';':
                self.nextToken()
                self.tolerateUnexpectedToken(token)
            else:
                self.tolerateUnexpectedToken(token, Messages.UnexpectedToken)
        else:
            self.expect(',')

    # Expect the next token to match the specified keyword.
    # If not, an exception will be thrown.

    def expectKeyword(self, keyword):
        token = self.nextToken()
        if token.type is not Token.Keyword or token.value != keyword:
            self.throwUnexpectedToken(token)

    # Return true if the next token matches the specified punctuator.

    def match(self, *value):
        return self.lookahead.type is Token.Punctuator and self.lookahead.value in value

    # Return true if the next token matches the specified keyword

    def matchKeyword(self, *keyword):
        return self.lookahead.type is Token.Keyword and self.lookahead.value in keyword

    # Return true if the next token matches the specified contextual keyword
    # (where an identifier is sometimes a keyword depending on the context)

    def matchContextualKeyword(self, *keyword):
        return self.lookahead.type is Token.Identifier and self.lookahead.value in keyword

    # Return true if the next token is an assignment operator

    def matchAssign(self):
        if self.lookahead.type is not Token.Punctuator:
            return False

        op = self.lookahead.value
        return op in ('=''*=''**=''/=''%=''+=''-=''<<=''>>=''>>>=''&=''^=''|=')

    # Cover grammar support.
    #
    # When an assignment expression position starts with an left parenthesis, the determination of the type
    # of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead)
    # or the first comma. This situation also defers the determination of all the expressions nested in the pair.
    #
    # There are three productions that can be parsed in a parentheses pair that needs to be determined
    # after the outermost pair is closed. They are:
    #
    #   1. AssignmentExpression
    #   2. BindingElements
    #   3. AssignmentTargets
    #
    # In order to avoid exponential backtracking, we use two flags to denote if the production can be
    # binding element or assignment target.
    #
    # The three productions have the relationship:
    #
    #   BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression
    #
    # with a single exception that CoverInitializedName when used directly in an Expression, generates
    # an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the
    # first usage of CoverInitializedName and report it when we reached the end of the parentheses pair.
    #
    # isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not
    # effect the current flags. This means the production the parser parses is only used as an expression. Therefore
    # the CoverInitializedName check is conducted.
    #
    # inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates
    # the flags outside of the parser. This means the production the parser parses is used as a part of a potential
    # pattern. The CoverInitializedName check is deferred.

    def isolateCoverGrammar(self, parseFunction):
        previousIsBindingElement = self.context.isBindingElement
        previousIsAssignmentTarget = self.context.isAssignmentTarget
        previousFirstCoverInitializedNameError = self.context.firstCoverInitializedNameError

        self.context.isBindingElement = True
        self.context.isAssignmentTarget = True
        self.context.firstCoverInitializedNameError = None

        result = parseFunction()
        if self.context.firstCoverInitializedNameError is not None:
            self.throwUnexpectedToken(self.context.firstCoverInitializedNameError)

        self.context.isBindingElement = previousIsBindingElement
        self.context.isAssignmentTarget = previousIsAssignmentTarget
        self.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError

        return result

    def inheritCoverGrammar(self, parseFunction):
        previousIsBindingElement = self.context.isBindingElement
        previousIsAssignmentTarget = self.context.isAssignmentTarget
        previousFirstCoverInitializedNameError = self.context.firstCoverInitializedNameError

        self.context.isBindingElement = True
        self.context.isAssignmentTarget = True
        self.context.firstCoverInitializedNameError = None

        result = parseFunction()

        self.context.isBindingElement = self.context.isBindingElement and previousIsBindingElement
        self.context.isAssignmentTarget = self.context.isAssignmentTarget and previousIsAssignmentTarget
        self.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError or self.context.firstCoverInitializedNameError

        return result

    def consumeSemicolon(self):
        if self.match(';'):
            self.nextToken()
        elif not self.hasLineTerminator:
            if self.lookahead.type is not Token.EOF and not self.match('}'):
                self.throwUnexpectedToken(self.lookahead)
            self.lastMarker.index = self.startMarker.index
            self.lastMarker.line = self.startMarker.line
            self.lastMarker.column = self.startMarker.column

    https://tc39.github.io/ecma262/#sec-primary-expression

    def parsePrimaryExpression(self):
        node = self.createNode()

        typ = self.lookahead.type
        if typ is Token.Identifier:
            if (self.context.isModule or self.context.allowAwait) and self.lookahead.value == 'await':
                self.tolerateUnexpectedToken(self.lookahead)
            expr = self.parseFunctionExpression() if self.matchAsyncFunction() else self.finalize(node, Node.Identifier(self.nextToken().value))

        elif typ in (
            Token.NumericLiteral,
            Token.StringLiteral,
        ):
            if self.context.strict and self.lookahead.octal:
                self.tolerateUnexpectedToken(self.lookahead, Messages.StrictOctalLiteral)
            self.context.isAssignmentTarget = False
            self.context.isBindingElement = False
            token = self.nextToken()
            raw = self.getTokenRaw(token)
            expr = self.finalize(node, Node.Literal(token.value, raw))

        elif typ is Token.BooleanLiteral:
            self.context.isAssignmentTarget = False
            self.context.isBindingElement = False
            token = self.nextToken()
            raw = self.getTokenRaw(token)
            expr = self.finalize(node, Node.Literal(token.value == 'true', raw))

        elif typ is Token.NullLiteral:
            self.context.isAssignmentTarget = False
            self.context.isBindingElement = False
            token = self.nextToken()
            raw = self.getTokenRaw(token)
            expr = self.finalize(node, Node.Literal(None, raw))

        elif typ is Token.Template:
            expr = self.parseTemplateLiteral()

        elif typ is Token.Punctuator:
            value = self.lookahead.value
            if value == '(':
                self.context.isBindingElement = False
                expr = self.inheritCoverGrammar(self.parseGroupExpression)
            elif value == '[':
                expr = self.inheritCoverGrammar(self.parseArrayInitializer)
            elif value == '{':
                expr = self.inheritCoverGrammar(self.parseObjectInitializer)
            elif value in ('/''/='):
                self.context.isAssignmentTarget = False
                self.context.isBindingElement = False
                self.scanner.index = self.startMarker.index
                token = self.nextRegexToken()
                raw = self.getTokenRaw(token)
                expr = self.finalize(node, Node.RegexLiteral(token.regex, raw, token.pattern, token.flags))
            else:
                expr = self.throwUnexpectedToken(self.nextToken())

        elif typ is Token.Keyword:
            if not self.context.strict and self.context.allowYield and self.matchKeyword('yield'):
                expr = self.parseIdentifierName()
            elif not self.context.strict and self.matchKeyword('let'):
                expr = self.finalize(node, Node.Identifier(self.nextToken().value))
            else:
                self.context.isAssignmentTarget = False
                self.context.isBindingElement = False
                if self.matchKeyword('function'):
                    expr = self.parseFunctionExpression()
                elif self.matchKeyword('this'):
                    self.nextToken()
                    expr = self.finalize(node, Node.ThisExpression())
                elif self.matchKeyword('class'):
                    expr = self.parseClassExpression()
                elif self.matchImportCall():
                    expr = self.parseImportCall()
                else:
                    expr = self.throwUnexpectedToken(self.nextToken())

        else:
            expr = self.throwUnexpectedToken(self.nextToken())

        return expr

    https://tc39.github.io/ecma262/#sec-array-initializer

    def parseSpreadElement(self):
        node = self.createNode()
        self.expect('...')
        arg = self.inheritCoverGrammar(self.parseAssignmentExpression)
        return self.finalize(node, Node.SpreadElement(arg))

    def parseArrayInitializer(self):
        node = self.createNode()
        elements = []

        self.expect('[')
        while not self.match(']'):
            if self.match(','):
                self.nextToken()
                elements.append(None)
            elif self.match('...'):
                element = self.parseSpreadElement()
                if not self.match(']'):
                    self.context.isAssignmentTarget = False
                    self.context.isBindingElement = False
                    self.expect(',')
                elements.append(element)
            else:
                elements.append(self.inheritCoverGrammar(self.parseAssignmentExpression))
                if not self.match(']'):
                    self.expect(',')
        self.expect(']')

        return self.finalize(node, Node.ArrayExpression(elements))

    https://tc39.github.io/ecma262/#sec-object-initializer

    def parsePropertyMethod(self, params):
        self.context.isAssignmentTarget = False
        self.context.isBindingElement = False

        previousStrict = self.context.strict
        previousAllowStrictDirective = self.context.allowStrictDirective
        self.context.allowStrictDirective = params.simple
        body = self.isolateCoverGrammar(self.parseFunctionSourceElements)
        if self.context.strict and params.firstRestricted:
            self.tolerateUnexpectedToken(params.firstRestricted, params.message)
        if self.context.strict and params.stricted:
            self.tolerateUnexpectedToken(params.stricted, params.message)
        self.context.strict = previousStrict
        self.context.allowStrictDirective = previousAllowStrictDirective

        return body

    def parsePropertyMethodFunction(self):
        isGenerator = False
        node = self.createNode()

        previousAllowYield = self.context.allowYield
        self.context.allowYield = True
        params = self.parseFormalParameters()
        method = self.parsePropertyMethod(params)
        self.context.allowYield = previousAllowYield

        return self.finalize(node, Node.FunctionExpression(None, params.params, method, isGenerator))

    def parsePropertyMethodAsyncFunction(self):
        node = self.createNode()

        previousAllowYield = self.context.allowYield
        previousAwait = self.context.allowAwait
        self.context.allowYield = False
        self.context.allowAwait = True
        params = self.parseFormalParameters()
        method = self.parsePropertyMethod(params)
        self.context.allowYield = previousAllowYield
        self.context.allowAwait = previousAwait

        return self.finalize(node, Node.AsyncFunctionExpression(None, params.params, method))

    def parseObjectPropertyKey(self):
        node = self.createNode()
        token = self.nextToken()

        typ = token.type
        if typ in (
            Token.StringLiteral,
            Token.NumericLiteral,
        ):
            if self.context.strict and token.octal:
                self.tolerateUnexpectedToken(token, Messages.StrictOctalLiteral)
            raw = self.getTokenRaw(token)
            key = self.finalize(node, Node.Literal(token.value, raw))

        elif typ in (
            Token.Identifier,
            Token.BooleanLiteral,
            Token.NullLiteral,
            Token.Keyword,
        ):
            key = self.finalize(node, Node.Identifier(token.value))

        elif typ is Token.Punctuator:
            if token.value == '[':
                key = self.isolateCoverGrammar(self.parseAssignmentExpression)
                self.expect(']')
            else:
                key = self.throwUnexpectedToken(token)

        else:
            key = self.throwUnexpectedToken(token)

        return key

    def isPropertyKey(self, key, value):
        return (
            (key.type is Syntax.Identifier and key.name == value) or
            (key.type is Syntax.Literal and key.value == value)
        )

    def parseObjectProperty(self, hasProto):
        node = self.createNode()
        token = self.lookahead

        key = None
        value = None

        computed = False
        method = False
        shorthand = False
        isAsync = False

        if token.type is Token.Identifier:
            id = token.value
            self.nextToken()
            computed = self.match('[')
            isAsync = not self.hasLineTerminator and (id == 'async'and not (self.match(':''(''*'','))
            key = self.parseObjectPropertyKey() if isAsync else self.finalize(node, Node.Identifier(id))
        elif self.match('*'):
            self.nextToken()
        else:
            computed = self.match('[')
            key = self.parseObjectPropertyKey()

        lookaheadPropertyKey = self.qualifiedPropertyName(self.lookahead)
        if token.type is Token.Identifier and not isAsync and token.value == 'get' and lookaheadPropertyKey:
            kind = 'get'
            computed = self.match('[')
            key = self.parseObjectPropertyKey()
            self.context.allowYield = False
            value = self.parseGetterMethod()

        elif token.type is Token.Identifier and not isAsync and token.value == 'set' and lookaheadPropertyKey:
            kind = 'set'
            computed = self.match('[')
            key = self.parseObjectPropertyKey()
            value = self.parseSetterMethod()

        elif token.type is Token.Punctuator and token.value == '*' and lookaheadPropertyKey:
            kind = 'init'
            computed = self.match('[')
            key = self.parseObjectPropertyKey()
            value = self.parseGeneratorMethod()
            method = True

        else:
            if not key:
                self.throwUnexpectedToken(self.lookahead)

            kind = 'init'
            if self.match(':'and not isAsync:
                if not computed and self.isPropertyKey(key, '__proto__'):
                    if hasProto.value:
                        self.tolerateError(Messages.DuplicateProtoProperty)
                    hasProto.value = True
                self.nextToken()
                value = self.inheritCoverGrammar(self.parseAssignmentExpression)

            elif self.match('('):
                value = self.parsePropertyMethodAsyncFunction() if isAsync else self.parsePropertyMethodFunction()
                method = True

            elif token.type is Token.Identifier:
                id = self.finalize(node, Node.Identifier(token.value))
                if self.match('='):
                    self.context.firstCoverInitializedNameError = self.lookahead
                    self.nextToken()
                    shorthand = True
                    init = self.isolateCoverGrammar(self.parseAssignmentExpression)
                    value = self.finalize(node, Node.AssignmentPattern(id, init))
                else:
                    shorthand = True
                    value = id
            else:
                self.throwUnexpectedToken(self.nextToken())

        return self.finalize(node, Node.Property(kind, key, computed, value, method, shorthand))

    def parseObjectInitializer(self):
        node = self.createNode()

        self.expect('{')
        properties = []
        hasProto = Value(False)
        while not self.match('}'):
            properties.append(self.parseSpreadElement() if self.match('...'else self.parseObjectProperty(hasProto))
            if not self.match('}'):
                self.expectCommaSeparator()
        self.expect('}')

        return self.finalize(node, Node.ObjectExpression(properties))

    https://tc39.github.io/ecma262/#sec-template-literals

    def parseTemplateHead(self):
        assert self.lookahead.head, 'Template literal must start with a template head'

        node = self.createNode()
        token = self.nextToken()
        raw = token.value
        cooked = token.cooked

        return self.finalize(node, Node.TemplateElement(raw, cooked, token.tail))

    def parseTemplateElement(self):
        if self.lookahead.type is not Token.Template:
            self.throwUnexpectedToken()

        node = self.createNode()
        token = self.nextToken()
        raw = token.value
        cooked = token.cooked

        return self.finalize(node, Node.TemplateElement(raw, cooked, token.tail))

    def parseTemplateLiteral(self):
        node = self.createNode()

        expressions = []
        quasis = []

        quasi = self.parseTemplateHead()
        quasis.append(quasi)
        while not quasi.tail:
            expressions.append(self.parseExpression())
            quasi = self.parseTemplateElement()
            quasis.append(quasi)

        return self.finalize(node, Node.TemplateLiteral(quasis, expressions))

    https://tc39.github.io/ecma262/#sec-grouping-operator

    def reinterpretExpressionAsPattern(self, expr):
        typ = expr.type
        if typ in (
            Syntax.Identifier,
            Syntax.MemberExpression,
            Syntax.RestElement,
            Syntax.AssignmentPattern,
        ):
            pass
        elif typ is Syntax.SpreadElement:
            expr.type = Syntax.RestElement
            self.reinterpretExpressionAsPattern(expr.argument)
        elif typ is Syntax.ArrayExpression:
            expr.type = Syntax.ArrayPattern
            for elem in expr.elements:
                if elem is not None:
                    self.reinterpretExpressionAsPattern(elem)
        elif typ is Syntax.ObjectExpression:
            expr.type = Syntax.ObjectPattern
            for prop in expr.properties:
                self.reinterpretExpressionAsPattern(prop if prop.type is Syntax.SpreadElement else prop.value)
        elif typ is Syntax.AssignmentExpression:
            expr.type = Syntax.AssignmentPattern
            del expr.operator
            self.reinterpretExpressionAsPattern(expr.left)
        else:
            # Allow other node type for tolerant parsing.
            pass

    def parseGroupExpression(self):
        self.expect('(')
        if self.match(')'):
            self.nextToken()
            if not self.match('=>'):
                self.expect('=>')
            expr = Node.ArrowParameterPlaceHolder([])
        else:
            startToken = self.lookahead
            params = []
            if self.match('...'):
                expr = self.parseRestElement(params)
                self.expect(')')
                if not self.match('=>'):
                    self.expect('=>')
                expr = Node.ArrowParameterPlaceHolder([expr])
            else:
                arrow = False
                self.context.isBindingElement = True
                expr = self.inheritCoverGrammar(self.parseAssignmentExpression)

                if self.match(','):
                    expressions = []

                    self.context.isAssignmentTarget = False
                    expressions.append(expr)
                    while self.lookahead.type is not Token.EOF:
                        if not self.match(','):
                            break
                        self.nextToken()
                        if self.match(')'):
                            self.nextToken()
                            for expression in expressions:
                                self.reinterpretExpressionAsPattern(expression)
                            arrow = True
                            expr = Node.ArrowParameterPlaceHolder(expressions)
                        elif self.match('...'):
                            if not self.context.isBindingElement:
                                self.throwUnexpectedToken(self.lookahead)
                            expressions.append(self.parseRestElement(params))
                            self.expect(')')
                            if not self.match('=>'):
                                self.expect('=>')
                            self.context.isBindingElement = False
                            for expression in expressions:
                                self.reinterpretExpressionAsPattern(expression)
                            arrow = True
                            expr = Node.ArrowParameterPlaceHolder(expressions)
                        else:
                            expressions.append(self.inheritCoverGrammar(self.parseAssignmentExpression))
                        if arrow:
                            break
                    if not arrow:
                        expr = self.finalize(self.startNode(startToken), Node.SequenceExpression(expressions))

                if not arrow:
                    self.expect(')')
                    if self.match('=>'):
                        if expr.type is Syntax.Identifier and expr.name == 'yield':
                            arrow = True
                            expr = Node.ArrowParameterPlaceHolder([expr])
                        if not arrow:
                            if not self.context.isBindingElement:
                                self.throwUnexpectedToken(self.lookahead)

                            if expr.type is Syntax.SequenceExpression:
                                for expression in expr.expressions:
                                    self.reinterpretExpressionAsPattern(expression)
                            else:
                                self.reinterpretExpressionAsPattern(expr)

                            if expr.type is Syntax.SequenceExpression:
                                parameters = expr.expressions
                            else:
                                parameters = [expr]
                            expr = Node.ArrowParameterPlaceHolder(parameters)
                    self.context.isBindingElement = False

        return expr

    https://tc39.github.io/ecma262/#sec-left-hand-side-expressions

    def parseArguments(self):
        self.expect('(')
        args = []
        if not self.match(')'):
            while True:
                if self.match('...'):
                    expr = self.parseSpreadElement()
                else:
                    expr = self.isolateCoverGrammar(self.parseAssignmentExpression)
                args.append(expr)
                if self.match(')'):
                    break
                self.expectCommaSeparator()
                if self.match(')'):
                    break
        self.expect(')')

        return args

    def isIdentifierName(self, token):
        return (
            token.type is Token.Identifier or
            token.type is Token.Keyword or
            token.type is Token.BooleanLiteral or
            token.type is Token.NullLiteral
        )

    def parseIdentifierName(self):
        node = self.createNode()
        token = self.nextToken()
        if not self.isIdentifierName(token):
            self.throwUnexpectedToken(token)
        return self.finalize(node, Node.Identifier(token.value))

    def parseNewExpression(self):
        node = self.createNode()

        id = self.parseIdentifierName()
        assert id.name == 'new''New expression must start with `new`'

        if self.match('.'):
            self.nextToken()
            if self.lookahead.type is Token.Identifier and self.context.inFunctionBody and self.lookahead.value == 'target':
                property = self.parseIdentifierName()
                expr = Node.MetaProperty(id, property)
            else:
                self.throwUnexpectedToken(self.lookahead)
        elif self.matchKeyword('import'):
            self.throwUnexpectedToken(self.lookahead)
        else:
            callee = self.isolateCoverGrammar(self.parseLeftHandSideExpression)
            args = self.parseArguments() if self.match('('else []
            expr = Node.NewExpression(callee, args)
            self.context.isAssignmentTarget = False
            self.context.isBindingElement = False

        return self.finalize(node, expr)

    def parseAsyncArgument(self):
        arg = self.parseAssignmentExpression()
        self.context.firstCoverInitializedNameError = None
        return arg

    def parseAsyncArguments(self):
        self.expect('(')
        args = []
        if not self.match(')'):
            while True:
                if self.match('...'):
                    expr = self.parseSpreadElement()
                else:
                    expr = self.isolateCoverGrammar(self.parseAsyncArgument)
                args.append(expr)
                if self.match(')'):
                    break
                self.expectCommaSeparator()
                if self.match(')'):
                    break
        self.expect(')')

        return args

    def matchImportCall(self):
        match = self.matchKeyword('import')
        if match:
            state = self.scanner.saveState()
            self.scanner.scanComments()
            next = self.scanner.lex()
            self.scanner.restoreState(state)
            match = (next.type is Token.Punctuator) and (next.value == '(')

        return match

    def parseImportCall(self):
        node = self.createNode()
        self.expectKeyword('import')
        return self.finalize(node, Node.Import())

    def parseLeftHandSideExpressionAllowCall(self):
        startToken = self.lookahead
        maybeAsync = self.matchContextualKeyword('async')

        previousAllowIn = self.context.allowIn
        self.context.allowIn = True

        if self.matchKeyword('super'and self.context.inFunctionBody:
            expr = self.createNode()
            self.nextToken()
            expr = self.finalize(expr, Node.Super())
            if not self.match('('and not self.match('.'and not self.match('['):
                self.throwUnexpectedToken(self.lookahead)
        else:
            expr = self.inheritCoverGrammar(self.parseNewExpression if self.matchKeyword('new'else self.parsePrimaryExpression)

        while True:
            if self.match('.'):
                self.context.isBindingElement = False
                self.context.isAssignmentTarget = True
                self.expect('.')
                property = self.parseIdentifierName()
                expr = self.finalize(self.startNode(startToken), Node.StaticMemberExpression(expr, property))

            elif self.match('('):
                asyncArrow = maybeAsync and (startToken.lineNumber == self.lookahead.lineNumber)
                self.context.isBindingElement = False
                self.context.isAssignmentTarget = False
                if asyncArrow:
                    args = self.parseAsyncArguments()
                else:
                    args = self.parseArguments()
                if expr.type is Syntax.Import and len(args) != 1:
                    self.tolerateError(Messages.BadImportCallArity)
                expr = self.finalize(self.startNode(startToken), Node.CallExpression(expr, args))
                if asyncArrow and self.match('=>'):
                    for arg in args:
                        self.reinterpretExpressionAsPattern(arg)
                    expr = Node.AsyncArrowParameterPlaceHolder(args)
            elif self.match('['):
                self.context.isBindingElement = False
                self.context.isAssignmentTarget = True
                self.expect('[')
                property = self.isolateCoverGrammar(self.parseExpression)
                self.expect(']')
                expr = self.finalize(self.startNode(startToken), Node.ComputedMemberExpression(expr, property))

            elif self.lookahead.type is Token.Template and self.lookahead.head:
                quasi = self.parseTemplateLiteral()
                expr = self.finalize(self.startNode(startToken), Node.TaggedTemplateExpression(expr, quasi))

            else:
                break

        self.context.allowIn = previousAllowIn

        return expr

    def parseSuper(self):
        node = self.createNode()

        self.expectKeyword('super')
        if not self.match('['and not self.match('.'):
            self.throwUnexpectedToken(self.lookahead)

        return self.finalize(node, Node.Super())

    def parseLeftHandSideExpression(self):
        assert self.context.allowIn, 'callee of new expression always allow in keyword.'

        node = self.startNode(self.lookahead)
        if self.matchKeyword('super'and self.context.inFunctionBody:
            expr = self.parseSuper()
        else:
            expr = self.inheritCoverGrammar(self.parseNewExpression if self.matchKeyword('new'else self.parsePrimaryExpression)

        while True:
            if self.match('['):
                self.context.isBindingElement = False
                self.context.isAssignmentTarget = True
                self.expect('[')
                property = self.isolateCoverGrammar(self.parseExpression)
                self.expect(']')
                expr = self.finalize(node, Node.ComputedMemberExpression(expr, property))

            elif self.match('.'):
                self.context.isBindingElement = False
                self.context.isAssignmentTarget = True
                self.expect('.')
                property = self.parseIdentifierName()
                expr = self.finalize(node, Node.StaticMemberExpression(expr, property))

            elif self.lookahead.type is Token.Template and self.lookahead.head:
                quasi = self.parseTemplateLiteral()
                expr = self.finalize(node, Node.TaggedTemplateExpression(expr, quasi))

            else:
                break

        return expr

    https://tc39.github.io/ecma262/#sec-update-expressions

    def parseUpdateExpression(self):
        startToken = self.lookahead

        if self.match('++''--'):
            node = self.startNode(startToken)
            token = self.nextToken()
            expr = self.inheritCoverGrammar(self.parseUnaryExpression)
            if self.context.strict and expr.type is Syntax.Identifier and self.scanner.isRestrictedWord(expr.name):
                self.tolerateError(Messages.StrictLHSPrefix)
            if not self.context.isAssignmentTarget:
                self.tolerateError(Messages.InvalidLHSInAssignment)
            prefix = True
            expr = self.finalize(node, Node.UpdateExpression(token.value, expr, prefix))
            self.context.isAssignmentTarget = False
            self.context.isBindingElement = False
        else:
            expr = self.inheritCoverGrammar(self.parseLeftHandSideExpressionAllowCall)
            if not self.hasLineTerminator and self.lookahead.type is Token.Punctuator:
                if self.match('++''--'):
                    if self.context.strict and expr.type is Syntax.Identifier and self.scanner.isRestrictedWord(expr.name):
                        self.tolerateError(Messages.StrictLHSPostfix)
                    if not self.context.isAssignmentTarget:
                        self.tolerateError(Messages.InvalidLHSInAssignment)
                    self.context.isAssignmentTarget = False
                    self.context.isBindingElement = False
                    operator = self.nextToken().value
                    prefix = False
                    expr = self.finalize(self.startNode(startToken), Node.UpdateExpression(operator, expr, prefix))

        return expr

    https://tc39.github.io/ecma262/#sec-unary-operators

    def parseAwaitExpression(self):
        node = self.createNode()
        self.nextToken()
        argument = self.parseUnaryExpression()
        return self.finalize(node, Node.AwaitExpression(argument))

    def parseUnaryExpression(self):
        if (
            self.match('+''-''~''!'or
            self.matchKeyword('delete''void''typeof')
        ):
            node = self.startNode(self.lookahead)
            token = self.nextToken()
            expr = self.inheritCoverGrammar(self.parseUnaryExpression)
            expr = self.finalize(node, Node.UnaryExpression(token.value, expr))
            if self.context.strict and expr.operator == 'delete' and expr.argument.type is Syntax.Identifier:
                self.tolerateError(Messages.StrictDelete)
            self.context.isAssignmentTarget = False
            self.context.isBindingElement = False
        elif self.context.allowAwait and self.matchContextualKeyword('await'):
            expr = self.parseAwaitExpression()
        else:
            expr = self.parseUpdateExpression()

        return expr

    def parseExponentiationExpression(self):
        startToken = self.lookahead

        expr = self.inheritCoverGrammar(self.parseUnaryExpression)
        if expr.type is not Syntax.UnaryExpression and self.match('**'):
            self.nextToken()
            self.context.isAssignmentTarget = False
            self.context.isBindingElement = False
            left = expr
            right = self.isolateCoverGrammar(self.parseExponentiationExpression)
            expr = self.finalize(self.startNode(startToken), Node.BinaryExpression('**', left, right))

        return expr

    https://tc39.github.io/ecma262/#sec-exp-operator
    https://tc39.github.io/ecma262/#sec-multiplicative-operators
    https://tc39.github.io/ecma262/#sec-additive-operators
    https://tc39.github.io/ecma262/#sec-bitwise-shift-operators
    https://tc39.github.io/ecma262/#sec-relational-operators
    https://tc39.github.io/ecma262/#sec-equality-operators
    https://tc39.github.io/ecma262/#sec-binary-bitwise-operators
    https://tc39.github.io/ecma262/#sec-binary-logical-operators

    def binaryPrecedence(self, token):
        op = token.value
        if token.type is Token.Punctuator:
            precedence = self.operatorPrecedence.get(op, 0)
        elif token.type is Token.Keyword:
            precedence = 7 if (op == 'instanceof' or (self.context.allowIn and op == 'in')) else 0
        else:
            precedence = 0
        return precedence

    def parseBinaryExpression(self):
        startToken = self.lookahead

        expr = self.inheritCoverGrammar(self.parseExponentiationExpression)

        token = self.lookahead
        prec = self.binaryPrecedence(token)
        if prec > 0:
            self.nextToken()

            self.context.isAssignmentTarget = False
            self.context.isBindingElement = False

            markers = [startToken, self.lookahead]
            left = expr
            right = self.isolateCoverGrammar(self.parseExponentiationExpression)

            stack = [left, token.value, right]
            precedences = [prec]
            while True:
                prec = self.binaryPrecedence(self.lookahead)
                if prec <= 0:
                    break

                # Reduce: make a binary expression from the three topmost entries.
                while len(stack) > 2 and prec <= precedences[-1]:
                    right = stack.pop()
                    operator = stack.pop()
                    precedences.pop()
                    left = stack.pop()
                    markers.pop()
                    node = self.startNode(markers[-1])
                    stack.append(self.finalize(node, Node.BinaryExpression(operator, left, right)))

                # Shift.
                stack.append(self.nextToken().value)
                precedences.append(prec)
                markers.append(self.lookahead)
                stack.append(self.isolateCoverGrammar(self.parseExponentiationExpression))

            # Final reduce to clean-up the stack.
            i = len(stack) - 1
            expr = stack[i]

            lastMarker = markers.pop()
            while i > 1:
                marker = markers.pop()
                lastLineStart = lastMarker.lineStart if lastMarker else 0
                node = self.startNode(marker, lastLineStart)
                operator = stack[i - 1]
                expr = self.finalize(node, Node.BinaryExpression(operator, stack[i - 2], expr))
                i -= 2
                lastMarker = marker

        return expr

    https://tc39.github.io/ecma262/#sec-conditional-operator

    def parseConditionalExpression(self):
        startToken = self.lookahead

        expr = self.inheritCoverGrammar(self.parseBinaryExpression)
        if self.match('?'):
            self.nextToken()

            previousAllowIn = self.context.allowIn
            self.context.allowIn = True
            consequent = self.isolateCoverGrammar(self.parseAssignmentExpression)
            self.context.allowIn = previousAllowIn

            self.expect(':')
            alternate = self.isolateCoverGrammar(self.parseAssignmentExpression)

            expr = self.finalize(self.startNode(startToken), Node.ConditionalExpression(expr, consequent, alternate))
            self.context.isAssignmentTarget = False
            self.context.isBindingElement = False

        return expr

    https://tc39.github.io/ecma262/#sec-assignment-operators

    def checkPatternParam(self, options, param):
        typ = param.type
        if typ is Syntax.Identifier:
            self.validateParam(options, param, param.name)
        elif typ is Syntax.RestElement:
            self.checkPatternParam(options, param.argument)
        elif typ is Syntax.AssignmentPattern:
            self.checkPatternParam(options, param.left)
        elif typ is Syntax.ArrayPattern:
            for element in param.elements:
                if element is not None:
                    self.checkPatternParam(options, element)
        elif typ is Syntax.ObjectPattern:
            for prop in param.properties:
                self.checkPatternParam(options, prop if prop.type is Syntax.RestElement else prop.value)

        options.simple = options.simple and isinstance(param, Node.Identifier)

    def reinterpretAsCoverFormalsList(self, expr):
        params = [expr]

        asyncArrow = False
        typ = expr.type
        if typ is Syntax.Identifier:
            pass
        elif typ is Syntax.ArrowParameterPlaceHolder:
            params = expr.params
            asyncArrow = expr.isAsync
        else:
            return None

        options = Params(
            simple=True,
            paramSet={},
        )

        for param in params:
            if param.type is Syntax.AssignmentPattern:
                if param.right.type is Syntax.YieldExpression:
                    if param.right.argument:
                        self.throwUnexpectedToken(self.lookahead)
                    param.right.type = Syntax.Identifier
                    param.right.name = 'yield'
                    del param.right.argument
                    del param.right.delegate
            elif asyncArrow and param.type is Syntax.Identifier and param.name == 'await':
                self.throwUnexpectedToken(self.lookahead)
            self.checkPatternParam(options, param)

        if self.context.strict or not self.context.allowYield:
            for param in params:
                if param.type is Syntax.YieldExpression:
                    self.throwUnexpectedToken(self.lookahead)

        if options.message is Messages.StrictParamDupe:
            token = options.stricted if self.context.strict else options.firstRestricted
            self.throwUnexpectedToken(token, options.message)

        return Params(
            simple=options.simple,
            params=params,
            stricted=options.stricted,
            firstRestricted=options.firstRestricted,
            message=options.message
        )

    def parseAssignmentExpression(self):
        if not self.context.allowYield and self.matchKeyword('yield'):
            expr = self.parseYieldExpression()
        else:
            startToken = self.lookahead
            token = startToken
            expr = self.parseConditionalExpression()

            if token.type is Token.Identifier and (token.lineNumber == self.lookahead.lineNumber) and token.value == 'async':
                if self.lookahead.type is Token.Identifier or self.matchKeyword('yield'):
                    arg = self.parsePrimaryExpression()
                    self.reinterpretExpressionAsPattern(arg)
                    expr = Node.AsyncArrowParameterPlaceHolder([arg])

            if expr.type is Syntax.ArrowParameterPlaceHolder or self.match('=>'):

                https://tc39.github.io/ecma262/#sec-arrow-function-definitions
                self.context.isAssignmentTarget = False
                self.context.isBindingElement = False
                isAsync = expr.isAsync
                list = self.reinterpretAsCoverFormalsList(expr)

                if list:
                    if self.hasLineTerminator:
                        self.tolerateUnexpectedToken(self.lookahead)
                    self.context.firstCoverInitializedNameError = None

                    previousStrict = self.context.strict
                    previousAllowStrictDirective = self.context.allowStrictDirective
                    self.context.allowStrictDirective = list.simple

                    previousAllowYield = self.context.allowYield
                    previousAwait = self.context.allowAwait
                    self.context.allowYield = True
                    self.context.allowAwait = isAsync

                    node = self.startNode(startToken)
                    self.expect('=>')
                    if self.match('{'):
                        previousAllowIn = self.context.allowIn
                        self.context.allowIn = True
                        body = self.parseFunctionSourceElements()
                        self.context.allowIn = previousAllowIn
                    else:
                        body = self.isolateCoverGrammar(self.parseAssignmentExpression)
                    expression = body.type is not Syntax.BlockStatement

                    if self.context.strict and list.firstRestricted:
                        self.throwUnexpectedToken(list.firstRestricted, list.message)
                    if self.context.strict and list.stricted:
                        self.tolerateUnexpectedToken(list.stricted, list.message)
                    if isAsync:
                        expr = self.finalize(node, Node.AsyncArrowFunctionExpression(list.params, body, expression))
                    else:
                        expr = self.finalize(node, Node.ArrowFunctionExpression(list.params, body, expression))

                    self.context.strict = previousStrict
                    self.context.allowStrictDirective = previousAllowStrictDirective
                    self.context.allowYield = previousAllowYield
                    self.context.allowAwait = previousAwait
            else:
                if self.matchAssign():
                    if not self.context.isAssignmentTarget:
                        self.tolerateError(Messages.InvalidLHSInAssignment)

                    if self.context.strict and expr.type is Syntax.Identifier:
                        id = expr
                        if self.scanner.isRestrictedWord(id.name):
                            self.tolerateUnexpectedToken(token, Messages.StrictLHSAssignment)
                        if self.scanner.isStrictModeReservedWord(id.name):
                            self.tolerateUnexpectedToken(token, Messages.StrictReservedWord)

                    if not self.match('='):
                        self.context.isAssignmentTarget = False
                        self.context.isBindingElement = False
                    else:
                        self.reinterpretExpressionAsPattern(expr)

                    token = self.nextToken()
                    operator = token.value
                    right = self.isolateCoverGrammar(self.parseAssignmentExpression)
                    expr = self.finalize(self.startNode(startToken), Node.AssignmentExpression(operator, expr, right))
                    self.context.firstCoverInitializedNameError = None

        return expr

    https://tc39.github.io/ecma262/#sec-comma-operator

    def parseExpression(self):
        startToken = self.lookahead
        expr = self.isolateCoverGrammar(self.parseAssignmentExpression)

        if self.match(','):
            expressions = []
            expressions.append(expr)
            while self.lookahead.type is not Token.EOF:
                if not self.match(','):
                    break
                self.nextToken()
                expressions.append(self.isolateCoverGrammar(self.parseAssignmentExpression))

            expr = self.finalize(self.startNode(startToken), Node.SequenceExpression(expressions))

        return expr

    https://tc39.github.io/ecma262/#sec-block

    def parseStatementListItem(self):
        self.context.isAssignmentTarget = True
        self.context.isBindingElement = True
        if self.lookahead.type is Token.Keyword:
            value = self.lookahead.value
            if value == 'export':
                if not self.context.isModule:
                    self.tolerateUnexpectedToken(self.lookahead, Messages.IllegalExportDeclaration)
                statement = self.parseExportDeclaration()
            elif value == 'import':
                if self.matchImportCall():
                    statement = self.parseExpressionStatement()
                else:
                    if not self.context.isModule:
                        self.tolerateUnexpectedToken(self.lookahead, Messages.IllegalImportDeclaration)
                    statement = self.parseImportDeclaration()
            elif value == 'const':
                statement = self.parseLexicalDeclaration(Params(inFor=False))
            elif value == 'function':
                statement = self.parseFunctionDeclaration()
            elif value == 'class':
                statement = self.parseClassDeclaration()
            elif value == 'let':
                statement = self.parseLexicalDeclaration(Params(inFor=False)) if self.isLexicalDeclaration() else self.parseStatement()
            else:
                statement = self.parseStatement()
        else:
            statement = self.parseStatement()

        return statement

    def parseBlock(self):
        node = self.createNode()

        self.expect('{')
        block = []
        while True:
            if self.match('}'):
                break
            block.append(self.parseStatementListItem())
        self.expect('}')

        return self.finalize(node, Node.BlockStatement(block))

    https://tc39.github.io/ecma262/#sec-let-and-const-declarations

    def parseLexicalBinding(self, kind, options):
        node = self.createNode()
        params = []
        id = self.parsePattern(params, kind)

        if self.context.strict and id.type is Syntax.Identifier:
            if self.scanner.isRestrictedWord(id.name):
                self.tolerateError(Messages.StrictVarName)

        init = None
        if kind == 'const':
            if not self.matchKeyword('in'and not self.matchContextualKeyword('of'):
                if self.match('='):
                    self.nextToken()
                    init = self.isolateCoverGrammar(self.parseAssignmentExpression)
                else:
                    self.throwError(Messages.DeclarationMissingInitializer, 'const')
        elif (not options.inFor and id.type is not Syntax.Identifier) or self.match('='):
            self.expect('=')
            init = self.isolateCoverGrammar(self.parseAssignmentExpression)

        return self.finalize(node, Node.VariableDeclarator(id, init))

    def parseBindingList(self, kind, options):
        lst = [self.parseLexicalBinding(kind, options)]

        while self.match(','):
            self.nextToken()
            lst.append(self.parseLexicalBinding(kind, options))

        return lst

    def isLexicalDeclaration(self):
        state = self.scanner.saveState()
        self.scanner.scanComments()
        next = self.scanner.lex()
        self.scanner.restoreState(state)

        return (
            (next.type is Token.Identifier) or
            (next.type is Token.Punctuator and next.value == '['or
            (next.type is Token.Punctuator and next.value == '{'or
            (next.type is Token.Keyword and next.value == 'let'or
            (next.type is Token.Keyword and next.value == 'yield')
        )

    def parseLexicalDeclaration(self, options):
        node = self.createNode()
        kind = self.nextToken().value
        assert kind == 'let' or kind == 'const''Lexical declaration must be either or const'

        declarations = self.parseBindingList(kind, options)
        self.consumeSemicolon()

        return self.finalize(node, Node.VariableDeclaration(declarations, kind))

    https://tc39.github.io/ecma262/#sec-destructuring-binding-patterns

    def parseBindingRestElement(self, params, kind=None):
        node = self.createNode()

        self.expect('...')
        arg = self.parsePattern(params, kind)

        return self.finalize(node, Node.RestElement(arg))

    def parseArrayPattern(self, params, kind=None):
        node = self.createNode()

        self.expect('[')
        elements = []
        while not self.match(']'):
            if self.match(','):
                self.nextToken()
                elements.append(None)
            else:
                if self.match('...'):
                    elements.append(self.parseBindingRestElement(params, kind))
                    break
                else:
                    elements.append(self.parsePatternWithDefault(params, kind))
                if not self.match(']'):
                    self.expect(',')
        self.expect(']')

        return self.finalize(node, Node.ArrayPattern(elements))

    def parsePropertyPattern(self, params, kind=None):
        node = self.createNode()

        computed = False
        shorthand = False
        method = False

        key = None

        if self.lookahead.type is Token.Identifier:
            keyToken = self.lookahead
            key = self.parseVariableIdentifier()
            init = self.finalize(node, Node.Identifier(keyToken.value))
            if self.match('='):
                params.append(keyToken)
                shorthand = True
                self.nextToken()
                expr = self.parseAssignmentExpression()
                value = self.finalize(self.startNode(keyToken), Node.AssignmentPattern(init, expr))
            elif not self.match(':'):
                params.append(keyToken)
                shorthand = True
                value = init
            else:
                self.expect(':')
                value = self.parsePatternWithDefault(params, kind)
        else:
            computed = self.match('[')
            key = self.parseObjectPropertyKey()
            self.expect(':')
            value = self.parsePatternWithDefault(params, kind)

        return self.finalize(node, Node.Property('init', key, computed, value, method, shorthand))

    def parseRestProperty(self, params, kind):
        node = self.createNode()
        self.expect('...')
        arg = self.parsePattern(params)
        if self.match('='):
            self.throwError(Messages.DefaultRestProperty)
        if not self.match('}'):
            self.throwError(Messages.PropertyAfterRestProperty)
        return self.finalize(node, Node.RestElement(arg))

    def parseObjectPattern(self, params, kind=None):
        node = self.createNode()
        properties = []

        self.expect('{')
        while not self.match('}'):
            properties.append(self.parseRestProperty(params, kind) if self.match('...'else self.parsePropertyPattern(params, kind))
            if not self.match('}'):
                self.expect(',')
        self.expect('}')

        return self.finalize(node, Node.ObjectPattern(properties))

    def parsePattern(self, params, kind=None):
        if self.match('['):
            pattern = self.parseArrayPattern(params, kind)
        elif self.match('{'):
            pattern = self.parseObjectPattern(params, kind)
        else:
            if self.matchKeyword('let'and (kind in ('const''let')):
                self.tolerateUnexpectedToken(self.lookahead, Messages.LetInLexicalBinding)
            params.append(self.lookahead)
            pattern = self.parseVariableIdentifier(kind)

        return pattern

    def parsePatternWithDefault(self, params, kind=None):
        startToken = self.lookahead

        pattern = self.parsePattern(params, kind)
        if self.match('='):
            self.nextToken()
            previousAllowYield = self.context.allowYield
            self.context.allowYield = True
            right = self.isolateCoverGrammar(self.parseAssignmentExpression)
            self.context.allowYield = previousAllowYield
            pattern = self.finalize(self.startNode(startToken), Node.AssignmentPattern(pattern, right))

        return pattern

    https://tc39.github.io/ecma262/#sec-variable-statement

    def parseVariableIdentifier(self, kind=None):
        node = self.createNode()

        token = self.nextToken()
        if token.type is Token.Keyword and token.value == 'yield':
            if self.context.strict:
                self.tolerateUnexpectedToken(token, Messages.StrictReservedWord)
            elif not self.context.allowYield:
                self.throwUnexpectedToken(token)
        elif token.type is not Token.Identifier:
            if self.context.strict and token.type is Token.Keyword and self.scanner.isStrictModeReservedWord(token.value):
                self.tolerateUnexpectedToken(token, Messages.StrictReservedWord)
            else:
                if self.context.strict or token.value != 'let' or kind != 'var':
                    self.throwUnexpectedToken(token)
        elif (self.context.isModule or self.context.allowAwait) and token.type is Token.Identifier and token.value == 'await':
            self.tolerateUnexpectedToken(token)

        return self.finalize(node, Node.Identifier(token.value))

    def parseVariableDeclaration(self, options):
        node = self.createNode()

        params = []
        id = self.parsePattern(params, 'var')

        if self.context.strict and id.type is Syntax.Identifier:
            if self.scanner.isRestrictedWord(id.name):
                self.tolerateError(Messages.StrictVarName)

        init = None
        if self.match('='):
            self.nextToken()
            init = self.isolateCoverGrammar(self.parseAssignmentExpression)
        elif id.type is not Syntax.Identifier and not options.inFor:
            self.expect('=')

        return self.finalize(node, Node.VariableDeclarator(id, init))

    def parseVariableDeclarationList(self, options):
        opt = Params(inFor=options.inFor)

        lst = []
        lst.append(self.parseVariableDeclaration(opt))
        while self.match(','):
            self.nextToken()
            lst.append(self.parseVariableDeclaration(opt))

        return lst

    def parseVariableStatement(self):
        node = self.createNode()
        self.expectKeyword('var')
        declarations = self.parseVariableDeclarationList(Params(inFor=False))
        self.consumeSemicolon()

        return self.finalize(node, Node.VariableDeclaration(declarations, 'var'))

    https://tc39.github.io/ecma262/#sec-empty-statement

    def parseEmptyStatement(self):
        node = self.createNode()
        self.expect(';')
        return self.finalize(node, Node.EmptyStatement())

    https://tc39.github.io/ecma262/#sec-expression-statement

    def parseExpressionStatement(self):
        node = self.createNode()
        expr = self.parseExpression()
        self.consumeSemicolon()
        return self.finalize(node, Node.ExpressionStatement(expr))

    https://tc39.github.io/ecma262/#sec-if-statement

    def parseIfClause(self):
        if self.context.strict and self.matchKeyword('function'):
            self.tolerateError(Messages.StrictFunction)
        return self.parseStatement()

    def parseIfStatement(self):
        node = self.createNode()
        alternate = None

        self.expectKeyword('if')
        self.expect('(')
        test = self.parseExpression()

        if not self.match(')'and self.config.tolerant:
            self.tolerateUnexpectedToken(self.nextToken())
            consequent = self.finalize(self.createNode(), Node.EmptyStatement())
        else:
            self.expect(')')
            consequent = self.parseIfClause()
            if self.matchKeyword('else'):
                self.nextToken()
                alternate = self.parseIfClause()

        return self.finalize(node, Node.IfStatement(test, consequent, alternate))

    https://tc39.github.io/ecma262/#sec-do-while-statement

    def parseDoWhileStatement(self):
        node = self.createNode()
        self.expectKeyword('do')

        previousInIteration = self.context.inIteration
        self.context.inIteration = True
        body = self.parseStatement()
        self.context.inIteration = previousInIteration

        self.expectKeyword('while')
        self.expect('(')
        test = self.parseExpression()

        if not self.match(')'and self.config.tolerant:
            self.tolerateUnexpectedToken(self.nextToken())
        else:
            self.expect(')')
            if self.match(';'):
                self.nextToken()

        return self.finalize(node, Node.DoWhileStatement(body, test))

    https://tc39.github.io/ecma262/#sec-while-statement

    def parseWhileStatement(self):
        node = self.createNode()

        self.expectKeyword('while')
        self.expect('(')
        test = self.parseExpression()

        if not self.match(')'and self.config.tolerant:
            self.tolerateUnexpectedToken(self.nextToken())
            body = self.finalize(self.createNode(), Node.EmptyStatement())
        else:
            self.expect(')')

            previousInIteration = self.context.inIteration
            self.context.inIteration = True
            body = self.parseStatement()
            self.context.inIteration = previousInIteration

        return self.finalize(node, Node.WhileStatement(test, body))

    https://tc39.github.io/ecma262/#sec-for-statement
    https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements

    def parseForStatement(self):
        init = None
        test = None
        update = None
        forIn = True
        left = None
        right = None

        node = self.createNode()
        self.expectKeyword('for')
        self.expect('(')

        if self.match(';'):
            self.nextToken()
        else:
            if self.matchKeyword('var'):
                init = self.createNode()
                self.nextToken()

                previousAllowIn = self.context.allowIn
                self.context.allowIn = False
                declarations = self.parseVariableDeclarationList(Params(inFor=True))
                self.context.allowIn = previousAllowIn

                if len(declarations) == 1 and self.matchKeyword('in'):
                    decl = declarations[0]
                    if decl.init and (decl.id.type is Syntax.ArrayPattern or decl.id.type is Syntax.ObjectPattern or self.context.strict):
                        self.tolerateError(Messages.ForInOfLoopInitializer, 'for-in')
                    init = self.finalize(init, Node.VariableDeclaration(declarations, 'var'))
                    self.nextToken()
                    left = init
                    right = self.parseExpression()
                    init = None
                elif len(declarations) == 1 and declarations[0].init is None and self.matchContextualKeyword('of'):
                    init = self.finalize(init, Node.VariableDeclaration(declarations, 'var'))
                    self.nextToken()
                    left = init
                    right = self.parseAssignmentExpression()
                    init = None
                    forIn = False
                else:
                    init = self.finalize(init, Node.VariableDeclaration(declarations, 'var'))
                    self.expect(';')
            elif self.matchKeyword('const''let'):
                init = self.createNode()
                kind = self.nextToken().value

                if not self.context.strict and self.lookahead.value == 'in':
                    init = self.finalize(init, Node.Identifier(kind))
                    self.nextToken()
                    left = init
                    right = self.parseExpression()
                    init = None
                else:
                    previousAllowIn = self.context.allowIn
                    self.context.allowIn = False
                    declarations = self.parseBindingList(kind, Params(inFor=True))
                    self.context.allowIn = previousAllowIn

                    if len(declarations) == 1 and declarations[0].init is None and self.matchKeyword('in'):
                        init = self.finalize(init, Node.VariableDeclaration(declarations, kind))
                        self.nextToken()
                        left = init
                        right = self.parseExpression()
                        init = None
                    elif len(declarations) == 1 and declarations[0].init is None and self.matchContextualKeyword('of'):
                        init = self.finalize(init, Node.VariableDeclaration(declarations, kind))
                        self.nextToken()
                        left = init
                        right = self.parseAssignmentExpression()
                        init = None
                        forIn = False
                    else:
                        self.consumeSemicolon()
                        init = self.finalize(init, Node.VariableDeclaration(declarations, kind))
            else:
                initStartToken = self.lookahead
                previousAllowIn = self.context.allowIn
                self.context.allowIn = False
                init = self.inheritCoverGrammar(self.parseAssignmentExpression)
                self.context.allowIn = previousAllowIn

                if self.matchKeyword('in'):
                    if not self.context.isAssignmentTarget or init.type is Syntax.AssignmentExpression:
                        self.tolerateError(Messages.InvalidLHSInForIn)

                    self.nextToken()
                    self.reinterpretExpressionAsPattern(init)
                    left = init
                    right = self.parseExpression()
                    init = None
                elif self.matchContextualKeyword('of'):
                    if not self.context.isAssignmentTarget or init.type is Syntax.AssignmentExpression:
                        self.tolerateError(Messages.InvalidLHSInForLoop)

                    self.nextToken()
                    self.reinterpretExpressionAsPattern(init)
                    left = init
                    right = self.parseAssignmentExpression()
                    init = None
                    forIn = False
                else:
                    if self.match(','):
                        initSeq = [init]
                        while self.match(','):
                            self.nextToken()
                            initSeq.append(self.isolateCoverGrammar(self.parseAssignmentExpression))
                        init = self.finalize(self.startNode(initStartToken), Node.SequenceExpression(initSeq))
                    self.expect(';')

        if left is None:
            if not self.match(';'):
                test = self.parseExpression()
            self.expect(';')
            if not self.match(')'):
                update = self.parseExpression()

        if not self.match(')'and self.config.tolerant:
            self.tolerateUnexpectedToken(self.nextToken())
            body = self.finalize(self.createNode(), Node.EmptyStatement())
        else:
            self.expect(')')

            previousInIteration = self.context.inIteration
            self.context.inIteration = True
            body = self.isolateCoverGrammar(self.parseStatement)
            self.context.inIteration = previousInIteration

        if left is None:
            return self.finalize(node, Node.ForStatement(init, test, update, body))

        if forIn:
            return self.finalize(node, Node.ForInStatement(left, right, body))

        return self.finalize(node, Node.ForOfStatement(left, right, body))

    https://tc39.github.io/ecma262/#sec-continue-statement

    def parseContinueStatement(self):
        node = self.createNode()
        self.expectKeyword('continue')

        label = None
        if self.lookahead.type is Token.Identifier and not self.hasLineTerminator:
            id = self.parseVariableIdentifier()
            label = id

            key = '$' + id.name
            if key not in self.context.labelSet:
                self.throwError(Messages.UnknownLabel, id.name)

        self.consumeSemicolon()
        if label is None and not self.context.inIteration:
            self.throwError(Messages.IllegalContinue)

        return self.finalize(node, Node.ContinueStatement(label))

    https://tc39.github.io/ecma262/#sec-break-statement

    def parseBreakStatement(self):
        node = self.createNode()
        self.expectKeyword('break')

        label = None
        if self.lookahead.type is Token.Identifier and not self.hasLineTerminator:
            id = self.parseVariableIdentifier()

            key = '$' + id.name
            if key not in self.context.labelSet:
                self.throwError(Messages.UnknownLabel, id.name)
            label = id

        self.consumeSemicolon()
        if label is None and not self.context.inIteration and not self.context.inSwitch:
            self.throwError(Messages.IllegalBreak)

        return self.finalize(node, Node.BreakStatement(label))

    https://tc39.github.io/ecma262/#sec-return-statement

    def parseReturnStatement(self):
        if not self.context.inFunctionBody:
            self.tolerateError(Messages.IllegalReturn)

        node = self.createNode()
        self.expectKeyword('return')

        hasArgument = (
            (
                not self.match(';'and not self.match('}'and
                not self.hasLineTerminator and self.lookahead.type is not Token.EOF
            ) or
            self.lookahead.type is Token.StringLiteral or
            self.lookahead.type is Token.Template
        )
        argument = self.parseExpression() if hasArgument else None
        self.consumeSemicolon()

        return self.finalize(node, Node.ReturnStatement(argument))

    https://tc39.github.io/ecma262/#sec-with-statement

    def parseWithStatement(self):
        if self.context.strict:
            self.tolerateError(Messages.StrictModeWith)

        node = self.createNode()

        self.expectKeyword('with')
        self.expect('(')
        object = self.parseExpression()

        if not self.match(')'and self.config.tolerant:
            self.tolerateUnexpectedToken(self.nextToken())
            body = self.finalize(self.createNode(), Node.EmptyStatement())
        else:
            self.expect(')')
            body = self.parseStatement()

        return self.finalize(node, Node.WithStatement(object, body))

    https://tc39.github.io/ecma262/#sec-switch-statement

    def parseSwitchCase(self):
        node = self.createNode()

        if self.matchKeyword('default'):
            self.nextToken()
            test = None
        else:
            self.expectKeyword('case')
            test = self.parseExpression()
        self.expect(':')

        consequent = []
        while True:
            if self.match('}'or self.matchKeyword('default''case'):
                break
            consequent.append(self.parseStatementListItem())

        return self.finalize(node, Node.SwitchCase(test, consequent))

    def parseSwitchStatement(self):
        node = self.createNode()
        self.expectKeyword('switch')

        self.expect('(')
        discriminant = self.parseExpression()
        self.expect(')')

        previousInSwitch = self.context.inSwitch
        self.context.inSwitch = True

        cases = []
        defaultFound = False
        self.expect('{')
        while True:
            if self.match('}'):
                break
            clause = self.parseSwitchCase()
            if clause.test is None:
                if defaultFound:
                    self.throwError(Messages.MultipleDefaultsInSwitch)
                defaultFound = True
            cases.append(clause)
        self.expect('}')

        self.context.inSwitch = previousInSwitch

        return self.finalize(node, Node.SwitchStatement(discriminant, cases))

    https://tc39.github.io/ecma262/#sec-labelled-statements

    def parseLabelledStatement(self):
        node = self.createNode()
        expr = self.parseExpression()

        if expr.type is Syntax.Identifier and self.match(':'):
            self.nextToken()

            id = expr
            key = '$' + id.name
            if key in self.context.labelSet:
                self.throwError(Messages.Redeclaration, 'Label', id.name)

            self.context.labelSet[key] = True
            if self.matchKeyword('class'):
                self.tolerateUnexpectedToken(self.lookahead)
                body = self.parseClassDeclaration()
            elif self.matchKeyword('function'):
                token = self.lookahead
                declaration = self.parseFunctionDeclaration()
                if self.context.strict:
                    self.tolerateUnexpectedToken(token, Messages.StrictFunction)
                elif declaration.generator:
                    self.tolerateUnexpectedToken(token, Messages.GeneratorInLegacyContext)
                body = declaration
            else:
                body = self.parseStatement()
            del self.context.labelSet[key]

            statement = Node.LabeledStatement(id, body)
        else:
            self.consumeSemicolon()
            statement = Node.ExpressionStatement(expr)

        return self.finalize(node, statement)

    https://tc39.github.io/ecma262/#sec-throw-statement

    def parseThrowStatement(self):
        node = self.createNode()
        self.expectKeyword('throw')

        if self.hasLineTerminator:
            self.throwError(Messages.NewlineAfterThrow)

        argument = self.parseExpression()
        self.consumeSemicolon()

        return self.finalize(node, Node.ThrowStatement(argument))

    https://tc39.github.io/ecma262/#sec-try-statement

    def parseCatchClause(self):
        node = self.createNode()

        self.expectKeyword('catch')

        self.expect('(')
        if self.match(')'):
            self.throwUnexpectedToken(self.lookahead)

        params = []
        param = self.parsePattern(params)
        paramMap = {}
        for p in params:
            key = '$' + p.value
            if key in paramMap:
                self.tolerateError(Messages.DuplicateBinding, p.value)
            paramMap[key] = True

        if self.context.strict and param.type is Syntax.Identifier:
            if self.scanner.isRestrictedWord(param.name):
                self.tolerateError(Messages.StrictCatchVariable)

        self.expect(')')
        body = self.parseBlock()

        return self.finalize(node, Node.CatchClause(param, body))

    def parseFinallyClause(self):
        self.expectKeyword('finally')
        return self.parseBlock()

    def parseTryStatement(self):
        node = self.createNode()
        self.expectKeyword('try')

        block = self.parseBlock()
        handler = self.parseCatchClause() if self.matchKeyword('catch'else None
        finalizer = self.parseFinallyClause() if self.matchKeyword('finally'else None

        if not handler and not finalizer:
            self.throwError(Messages.NoCatchOrFinally)

        return self.finalize(node, Node.TryStatement(block, handler, finalizer))

    https://tc39.github.io/ecma262/#sec-debugger-statement

    def parseDebuggerStatement(self):
        node = self.createNode()
        self.expectKeyword('debugger')
        self.consumeSemicolon()
        return self.finalize(node, Node.DebuggerStatement())

    https://tc39.github.io/ecma262/#sec-ecmascript-language-statements-and-declarations

    def parseStatement(self):
        typ = self.lookahead.type
        if typ in (
            Token.BooleanLiteral,
            Token.NullLiteral,
            Token.NumericLiteral,
            Token.StringLiteral,
            Token.Template,
            Token.RegularExpression,
        ):
            statement = self.parseExpressionStatement()

        elif typ is Token.Punctuator:
            value = self.lookahead.value
            if value == '{':
                statement = self.parseBlock()
            elif value == '(':
                statement = self.parseExpressionStatement()
            elif value == ';':
                statement = self.parseEmptyStatement()
            else:
                statement = self.parseExpressionStatement()

        elif typ is Token.Identifier:
            statement = self.parseFunctionDeclaration() if self.matchAsyncFunction() else self.parseLabelledStatement()

        elif typ is Token.Keyword:
            value = self.lookahead.value
            if value == 'break':
                statement = self.parseBreakStatement()
            elif value == 'continue':
                statement = self.parseContinueStatement()
            elif value == 'debugger':
                statement = self.parseDebuggerStatement()
            elif value == 'do':
                statement = self.parseDoWhileStatement()
            elif value == 'for':
                statement = self.parseForStatement()
            elif value == 'function':
                statement = self.parseFunctionDeclaration()
            elif value == 'if':
                statement = self.parseIfStatement()
            elif value == 'return':
                statement = self.parseReturnStatement()
            elif value == 'switch':
                statement = self.parseSwitchStatement()
            elif value == 'throw':
                statement = self.parseThrowStatement()
            elif value == 'try':
                statement = self.parseTryStatement()
            elif value == 'var':
                statement = self.parseVariableStatement()
            elif value == 'while':
                statement = self.parseWhileStatement()
            elif value == 'with':
                statement = self.parseWithStatement()
            else:
                statement = self.parseExpressionStatement()

        else:
            statement = self.throwUnexpectedToken(self.lookahead)

        return statement

    https://tc39.github.io/ecma262/#sec-function-definitions

    def parseFunctionSourceElements(self):
        node = self.createNode()

        self.expect('{')
        body = self.parseDirectivePrologues()

        previousLabelSet = self.context.labelSet
        previousInIteration = self.context.inIteration
        previousInSwitch = self.context.inSwitch
        previousInFunctionBody = self.context.inFunctionBody

        self.context.labelSet = {}
        self.context.inIteration = False
        self.context.inSwitch = False
        self.context.inFunctionBody = True

        while self.lookahead.type is not Token.EOF:
            if self.match('}'):
                break
            body.append(self.parseStatementListItem())

        self.expect('}')

        self.context.labelSet = previousLabelSet
        self.context.inIteration = previousInIteration
        self.context.inSwitch = previousInSwitch
        self.context.inFunctionBody = previousInFunctionBody

        return self.finalize(node, Node.BlockStatement(body))

    def validateParam(self, options, param, name):
        key = '$' + name
        if self.context.strict:
            if self.scanner.isRestrictedWord(name):
                options.stricted = param
                options.message = Messages.StrictParamName
            if key in options.paramSet:
                options.stricted = param
                options.message = Messages.StrictParamDupe
        elif not options.firstRestricted:
            if self.scanner.isRestrictedWord(name):
                options.firstRestricted = param
                options.message = Messages.StrictParamName
            elif self.scanner.isStrictModeReservedWord(name):
                options.firstRestricted = param
                options.message = Messages.StrictReservedWord
            elif key in options.paramSet:
                options.stricted = param
                options.message = Messages.StrictParamDupe

        options.paramSet[key] = True

    def parseRestElement(self, params):
        node = self.createNode()

        self.expect('...')
        arg = self.parsePattern(params)
        if self.match('='):
            self.throwError(Messages.DefaultRestParameter)
        if not self.match(')'):
            self.throwError(Messages.ParameterAfterRestParameter)

        return self.finalize(node, Node.RestElement(arg))

    def parseFormalParameter(self, options):
        params = []
        param = self.parseRestElement(params) if self.match('...'else self.parsePatternWithDefault(params)
        for p in params:
            self.validateParam(options, p, p.value)
        options.simple = options.simple and isinstance(param, Node.Identifier)
        options.params.append(param)

    def parseFormalParameters(self, firstRestricted=None):
        options = Params(
            simple=True,
            params=[],
            firstRestricted=firstRestricted
        )

        self.expect('(')
        if not self.match(')'):
            options.paramSet = {}
            while self.lookahead.type is not Token.EOF:
                self.parseFormalParameter(options)
                if self.match(')'):
                    break
                self.expect(',')
                if self.match(')'):
                    break
        self.expect(')')

        return Params(
            simple=options.simple,
            params=options.params,
            stricted=options.stricted,
            firstRestricted=options.firstRestricted,
            message=options.message
        )

    def matchAsyncFunction(self):
        match = self.matchContextualKeyword('async')
        if match:
            state = self.scanner.saveState()
            self.scanner.scanComments()
            next = self.scanner.lex()
            self.scanner.restoreState(state)

            match = (state.lineNumber == next.lineNumber) and (next.type is Token.Keyword) and (next.value == 'function')

        return match

    def parseFunctionDeclaration(self, identifierIsOptional=False):
        node = self.createNode()

        isAsync = self.matchContextualKeyword('async')
        if isAsync:
            self.nextToken()

        self.expectKeyword('function')

        isGenerator = False if isAsync else self.match('*')
        if isGenerator:
            self.nextToken()

        id = None
        firstRestricted = None

        if not identifierIsOptional or not self.match('('):
            token = self.lookahead
            id = self.parseVariableIdentifier()
            if self.context.strict:
                if self.scanner.isRestrictedWord(token.value):
                    self.tolerateUnexpectedToken(token, Messages.StrictFunctionName)
            else:
                if self.scanner.isRestrictedWord(token.value):
                    firstRestricted = token
                    message = Messages.StrictFunctionName
                elif self.scanner.isStrictModeReservedWord(token.value):
                    firstRestricted = token
                    message = Messages.StrictReservedWord

        previousAllowAwait = self.context.allowAwait
        previousAllowYield = self.context.allowYield
        self.context.allowAwait = isAsync
        self.context.allowYield = not isGenerator

        formalParameters = self.parseFormalParameters(firstRestricted)
        params = formalParameters.params
        stricted = formalParameters.stricted
        firstRestricted = formalParameters.firstRestricted
        if formalParameters.message:
            message = formalParameters.message

        previousStrict = self.context.strict
        previousAllowStrictDirective = self.context.allowStrictDirective
        self.context.allowStrictDirective = formalParameters.simple
        body = self.parseFunctionSourceElements()
        if self.context.strict and firstRestricted:
            self.throwUnexpectedToken(firstRestricted, message)
        if self.context.strict and stricted:
            self.tolerateUnexpectedToken(stricted, message)

        self.context.strict = previousStrict
        self.context.allowStrictDirective = previousAllowStrictDirective
        self.context.allowAwait = previousAllowAwait
        self.context.allowYield = previousAllowYield

        if isAsync:
            return self.finalize(node, Node.AsyncFunctionDeclaration(id, params, body))

        return self.finalize(node, Node.FunctionDeclaration(id, params, body, isGenerator))

    def parseFunctionExpression(self):
        node = self.createNode()

        isAsync = self.matchContextualKeyword('async')
        if isAsync:
            self.nextToken()

        self.expectKeyword('function')

        isGenerator = False if isAsync else self.match('*')
        if isGenerator:
            self.nextToken()

        id = None
        firstRestricted = None

        previousAllowAwait = self.context.allowAwait
        previousAllowYield = self.context.allowYield
        self.context.allowAwait = isAsync
        self.context.allowYield = not isGenerator

        if not self.match('('):
            token = self.lookahead
            id = self.parseIdentifierName() if not self.context.strict and not isGenerator and self.matchKeyword('yield'else self.parseVariableIdentifier()
            if self.context.strict:
                if self.scanner.isRestrictedWord(token.value):
                    self.tolerateUnexpectedToken(token, Messages.StrictFunctionName)
            else:
                if self.scanner.isRestrictedWord(token.value):
                    firstRestricted = token
                    message = Messages.StrictFunctionName
                elif self.scanner.isStrictModeReservedWord(token.value):
                    firstRestricted = token
                    message = Messages.StrictReservedWord

        formalParameters = self.parseFormalParameters(firstRestricted)
        params = formalParameters.params
        stricted = formalParameters.stricted
        firstRestricted = formalParameters.firstRestricted
        if formalParameters.message:
            message = formalParameters.message

        previousStrict = self.context.strict
        previousAllowStrictDirective = self.context.allowStrictDirective
        self.context.allowStrictDirective = formalParameters.simple
        body = self.parseFunctionSourceElements()
        if self.context.strict and firstRestricted:
            self.throwUnexpectedToken(firstRestricted, message)
        if self.context.strict and stricted:
            self.tolerateUnexpectedToken(stricted, message)
        self.context.strict = previousStrict
        self.context.allowStrictDirective = previousAllowStrictDirective
        self.context.allowAwait = previousAllowAwait
        self.context.allowYield = previousAllowYield

        if isAsync:
            return self.finalize(node, Node.AsyncFunctionExpression(id, params, body))

        return self.finalize(node, Node.FunctionExpression(id, params, body, isGenerator))

    https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive

    def parseDirective(self):
        token = self.lookahead

        node = self.createNode()
        expr = self.parseExpression()
        directive = self.getTokenRaw(token)[1:-1] if expr.type is Syntax.Literal else None
        self.consumeSemicolon()

        return self.finalize(node, Node.Directive(expr, directive) if directive else Node.ExpressionStatement(expr))

    def parseDirectivePrologues(self):
        firstRestricted = None

        body = []
        while True:
            token = self.lookahead
            if token.type is not Token.StringLiteral:
                break

            statement = self.parseDirective()
            body.append(statement)
            directive = statement.directive
            if not isinstance(directive, basestring):
                break

            if directive == 'use strict':
                self.context.strict = True
                if firstRestricted:
                    self.tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral)
                if not self.context.allowStrictDirective:
                    self.tolerateUnexpectedToken(token, Messages.IllegalLanguageModeDirective)
            else:
                if not firstRestricted and token.octal:
                    firstRestricted = token

        return body

    https://tc39.github.io/ecma262/#sec-method-definitions

    def qualifiedPropertyName(self, token):
        typ = token.type
        if typ in (
            Token.Identifier,
            Token.StringLiteral,
            Token.BooleanLiteral,
            Token.NullLiteral,
            Token.NumericLiteral,
            Token.Keyword,
        ):
            return True
        elif typ is Token.Punctuator:
            return token.value == '['
        return False

    def parseGetterMethod(self):
        node = self.createNode()

        isGenerator = False
        previousAllowYield = self.context.allowYield
        self.context.allowYield = not isGenerator
        formalParameters = self.parseFormalParameters()
        if len(formalParameters.params) > 0:
            self.tolerateError(Messages.BadGetterArity)
        method = self.parsePropertyMethod(formalParameters)
        self.context.allowYield = previousAllowYield

        return self.finalize(node, Node.FunctionExpression(None, formalParameters.params, method, isGenerator))

    def parseSetterMethod(self):
        node = self.createNode()

        isGenerator = False
        previousAllowYield = self.context.allowYield
        self.context.allowYield = not isGenerator
        formalParameters = self.parseFormalParameters()
        if len(formalParameters.params) != 1:
            self.tolerateError(Messages.BadSetterArity)
        elif isinstance(formalParameters.params[0], Node.RestElement):
            self.tolerateError(Messages.BadSetterRestParameter)
        method = self.parsePropertyMethod(formalParameters)
        self.context.allowYield = previousAllowYield

        return self.finalize(node, Node.FunctionExpression(None, formalParameters.params, method, isGenerator))

    def parseGeneratorMethod(self):
        node = self.createNode()

        isGenerator = True
        previousAllowYield = self.context.allowYield

        self.context.allowYield = True
        params = self.parseFormalParameters()
        self.context.allowYield = False
        method = self.parsePropertyMethod(params)
        self.context.allowYield = previousAllowYield

        return self.finalize(node, Node.FunctionExpression(None, params.params, method, isGenerator))

    https://tc39.github.io/ecma262/#sec-generator-function-definitions

    def isStartOfExpression(self):
        start = True

        value = self.lookahead.value
        typ = self.lookahead.type
        if typ is Token.Punctuator:
            start = value in ('[''(''{''+''-''!''~''++''--''/''/=')  # regular expression literal )

        elif typ is Token.Keyword:
            start = value in ('class''delete''function''let''new''super''this''typeof''void''yield')

        return start

    def parseYieldExpression(self):
        node = self.createNode()
        self.expectKeyword('yield')

        argument = None
        delegate = False
        if not self.hasLineTerminator:
            previousAllowYield = self.context.allowYield
            self.context.allowYield = False
            delegate = self.match('*')
            if delegate:
                self.nextToken()
                argument = self.parseAssignmentExpression()
            elif self.isStartOfExpression():
                argument = self.parseAssignmentExpression()
            self.context.allowYield = previousAllowYield

        return self.finalize(node, Node.YieldExpression(argument, delegate))

    https://tc39.github.io/ecma262/#sec-class-definitions

    def parseClassElement(self, hasConstructor):
        token = self.lookahead
        node = self.createNode()

        kind = ''
        key = None
        value = None
        computed = False
        isStatic = False
        isAsync = False

        if self.match('*'):
            self.nextToken()

        else:
            computed = self.match('[')
            key = self.parseObjectPropertyKey()
            id = key
            if id.name == 'static' and (self.qualifiedPropertyName(self.lookahead) or self.match('*')):
                token = self.lookahead
                isStatic = True
                computed = self.match('[')
                if self.match('*'):
                    self.nextToken()
                else:
                    key = self.parseObjectPropertyKey()
            if token.type is Token.Identifier and not self.hasLineTerminator and token.value == 'async':
                punctuator = self.lookahead.value
                if punctuator != ':' and punctuator != '(' and punctuator != '*':
                    isAsync = True
                    token = self.lookahead
                    key = self.parseObjectPropertyKey()
                    if token.type is Token.Identifier and token.value == 'constructor':
                        self.tolerateUnexpectedToken(token, Messages.ConstructorIsAsync)

        lookaheadPropertyKey = self.qualifiedPropertyName(self.lookahead)
        if token.type is Token.Identifier:
            if token.value == 'get' and lookaheadPropertyKey:
                kind = 'get'
                computed = self.match('[')
                key = self.parseObjectPropertyKey()
                self.context.allowYield = False
                value = self.parseGetterMethod()
            elif token.value == 'set' and lookaheadPropertyKey:
                kind = 'set'
                computed = self.match('[')
                key = self.parseObjectPropertyKey()
                value = self.parseSetterMethod()
            elif self.config.classProperties and not self.match('('):
                kind = 'init'
                id = self.finalize(node, Node.Identifier(token.value))
                if self.match('='):
                    self.nextToken()
                    value = self.parseAssignmentExpression()

        elif token.type is Token.Punctuator and token.value == '*' and lookaheadPropertyKey:
            kind = 'method'
            computed = self.match('[')
            key = self.parseObjectPropertyKey()
            value = self.parseGeneratorMethod()

        if not kind and key and self.match('('):
            kind = 'method'
            value = self.parsePropertyMethodAsyncFunction() if isAsync else self.parsePropertyMethodFunction()

        if not kind:
            self.throwUnexpectedToken(self.lookahead)

        if not computed:
            if isStatic and self.isPropertyKey(key, 'prototype'):
                self.throwUnexpectedToken(token, Messages.StaticPrototype)
            if not isStatic and self.isPropertyKey(key, 'constructor'):
                if kind != 'method' or (value and value.generator):
                    self.throwUnexpectedToken(token, Messages.ConstructorSpecialMethod)
                if hasConstructor.value:
                    self.throwUnexpectedToken(token, Messages.DuplicateConstructor)
                else:
                    hasConstructor.value = True
                kind = 'constructor'

        if kind in ('constructor''method''get''set'):
            return self.finalize(node, Node.MethodDefinition(key, computed, value, kind, isStatic))

        else:
            return self.finalize(node, Node.FieldDefinition(key, computed, value, kind, isStatic))

    def parseClassElementList(self):
        body = []
        hasConstructor = Value(False)

        self.expect('{')
        while not self.match('}'):
            if self.match(';'):
                self.nextToken()
            else:
                body.append(self.parseClassElement(hasConstructor))
        self.expect('}')

        return body

    def parseClassBody(self):
        node = self.createNode()
        elementList = self.parseClassElementList()

        return self.finalize(node, Node.ClassBody(elementList))

    def parseClassDeclaration(self, identifierIsOptional=False):
        node = self.createNode()

        previousStrict = self.context.strict
        self.context.strict = True
        self.expectKeyword('class')

        id = None if identifierIsOptional and self.lookahead.type is not Token.Identifier else self.parseVariableIdentifier()
        superClass = None
        if self.matchKeyword('extends'):
            self.nextToken()
            superClass = self.isolateCoverGrammar(self.parseLeftHandSideExpressionAllowCall)
        classBody = self.parseClassBody()
        self.context.strict = previousStrict

        return self.finalize(node, Node.ClassDeclaration(id, superClass, classBody))

    def parseClassExpression(self):
        node = self.createNode()

        previousStrict = self.context.strict
        self.context.strict = True
        self.expectKeyword('class')
        id = self.parseVariableIdentifier() if self.lookahead.type is Token.Identifier else None
        superClass = None
        if self.matchKeyword('extends'):
            self.nextToken()
            superClass = self.isolateCoverGrammar(self.parseLeftHandSideExpressionAllowCall)
        classBody = self.parseClassBody()
        self.context.strict = previousStrict

        return self.finalize(node, Node.ClassExpression(id, superClass, classBody))

    https://tc39.github.io/ecma262/#sec-scripts
    https://tc39.github.io/ecma262/#sec-modules

    def parseModule(self):
        self.context.strict = True
        self.context.isModule = True
        self.scanner.isModule = True
        node = self.createNode()
        body = self.parseDirectivePrologues()
        while self.lookahead.type is not Token.EOF:
            body.append(self.parseStatementListItem())
        return self.finalize(node, Node.Module(body))

    def parseScript(self):
        node = self.createNode()
        body = self.parseDirectivePrologues()
        while self.lookahead.type is not Token.EOF:
            body.append(self.parseStatementListItem())
        return self.finalize(node, Node.Script(body))

    https://tc39.github.io/ecma262/#sec-imports

    def parseModuleSpecifier(self):
        node = self.createNode()

        if self.lookahead.type is not Token.StringLiteral:
            self.throwError(Messages.InvalidModuleSpecifier)

        token = self.nextToken()
        raw = self.getTokenRaw(token)
        return self.finalize(node, Node.Literal(token.value, raw))

    # import {<foo as bar>} ...
    def parseImportSpecifier(self):
        node = self.createNode()

        if self.lookahead.type is Token.Identifier:
            imported = self.parseVariableIdentifier()
            local = imported
            if self.matchContextualKeyword('as'):
                self.nextToken()
                local = self.parseVariableIdentifier()
        else:
            imported = self.parseIdentifierName()
            local = imported
            if self.matchContextualKeyword('as'):
                self.nextToken()
                local = self.parseVariableIdentifier()
            else:
                self.throwUnexpectedToken(self.nextToken())

        return self.finalize(node, Node.ImportSpecifier(local, imported))

    # {foo, bar as bas
    def parseNamedImports(self):
        self.expect('{')
        specifiers = []
        while not self.match('}'):
            specifiers.append(self.parseImportSpecifier())
            if not self.match('}'):
                self.expect(',')
        self.expect('}')

        return specifiers

    # import <foo> ...
    def parseImportDefaultSpecifier(self):
        node = self.createNode()
        local = self.parseIdentifierName()
        return self.finalize(node, Node.ImportDefaultSpecifier(local))

    # import <* as foo> ...
    def parseImportNamespaceSpecifier(self):
        node = self.createNode()

        self.expect('*')
        if not self.matchContextualKeyword('as'):
            self.throwError(Messages.NoAsAfterImportNamespace)
        self.nextToken()
        local = self.parseIdentifierName()

        return self.finalize(node, Node.ImportNamespaceSpecifier(local))

    def parseImportDeclaration(self):
        if self.context.inFunctionBody:
            self.throwError(Messages.IllegalImportDeclaration)

        node = self.createNode()
        self.expectKeyword('import')

        specifiers = []
        if self.lookahead.type is Token.StringLiteral:
            # import 'foo'
            src = self.parseModuleSpecifier()
        else:
            if self.match('{'):
                # import {bar
                specifiers.extend(self.parseNamedImports())
            elif self.match('*'):
                # import * as foo
                specifiers.append(self.parseImportNamespaceSpecifier())
            elif self.isIdentifierName(self.lookahead) and not self.matchKeyword('default'):
                # import foo
                specifiers.append(self.parseImportDefaultSpecifier())
                if self.match(','):
                    self.nextToken()
                    if self.match('*'):
                        # import foo, * as foo
                        specifiers.append(self.parseImportNamespaceSpecifier())
                    elif self.match('{'):
                        # import foo, {bar
                        specifiers.extend(self.parseNamedImports())
                    else:
                        self.throwUnexpectedToken(self.lookahead)
            else:
                self.throwUnexpectedToken(self.nextToken())

            if not self.matchContextualKeyword('from'):
                message = Messages.UnexpectedToken if self.lookahead.value else Messages.MissingFromClause
                self.throwError(message, self.lookahead.value)
            self.nextToken()
            src = self.parseModuleSpecifier()
        self.consumeSemicolon()

        return self.finalize(node, Node.ImportDeclaration(specifiers, src))

    https://tc39.github.io/ecma262/#sec-exports

    def parseExportSpecifier(self):
        node = self.createNode()

        local = self.parseIdentifierName()
        exported = local
        if self.matchContextualKeyword('as'):
            self.nextToken()
            exported = self.parseIdentifierName()

        return self.finalize(node, Node.ExportSpecifier(local, exported))

    def parseExportDefaultSpecifier(self):
        node = self.createNode()
        local = self.parseIdentifierName()
        return self.finalize(node, Node.ExportDefaultSpecifier(local))

    def parseExportDeclaration(self):
        if self.context.inFunctionBody:
            self.throwError(Messages.IllegalExportDeclaration)

        node = self.createNode()
        self.expectKeyword('export')

        if self.matchKeyword('default'):
            # export default ...
            self.nextToken()
            if self.matchKeyword('function'):
                # export default function foo (:
                # export default function (:
                declaration = self.parseFunctionDeclaration(True)
                exportDeclaration = self.finalize(node, Node.ExportDefaultDeclaration(declaration))
            elif self.matchKeyword('class'):
                # export default class foo {
                declaration = self.parseClassDeclaration(True)
                exportDeclaration = self.finalize(node, Node.ExportDefaultDeclaration(declaration))
            elif self.matchContextualKeyword('async'):
                # export default async function f (:
                # export default async function (:
                # export default async x => x
                declaration = self.parseFunctionDeclaration(Trueif self.matchAsyncFunction() else self.parseAssignmentExpression()
                exportDeclaration = self.finalize(node, Node.ExportDefaultDeclaration(declaration))
            else:
                if self.matchContextualKeyword('from'):
                    self.throwError(Messages.UnexpectedToken, self.lookahead.value)
                # export default {}
                # export default []
                # export default (1 + 2)
                if self.match('{'):
                    declaration = self.parseObjectInitializer()
                elif self.match('['):
                    declaration = self.parseArrayInitializer()
                else:
                    declaration = self.parseAssignmentExpression()
                self.consumeSemicolon()
                exportDeclaration = self.finalize(node, Node.ExportDefaultDeclaration(declaration))

        elif self.match('*'):
            # export * from 'foo'
            self.nextToken()
            if not self.matchContextualKeyword('from'):
                message = Messages.UnexpectedToken if self.lookahead.value else Messages.MissingFromClause
                self.throwError(message, self.lookahead.value)
            self.nextToken()
            src = self.parseModuleSpecifier()
            self.consumeSemicolon()
            exportDeclaration = self.finalize(node, Node.ExportAllDeclaration(src))

        elif self.lookahead.type is Token.Keyword:
            # export var f = 1
            value = self.lookahead.value
            if value in (
                'let',
                'const',
            ):
                declaration = self.parseLexicalDeclaration(Params(inFor=False))
            elif value in (
                'var',
                'class',
                'function',
            ):
                declaration = self.parseStatementListItem()
            else:
                self.throwUnexpectedToken(self.lookahead)
            exportDeclaration = self.finalize(node, Node.ExportNamedDeclaration(declaration, [], None))

        elif self.matchAsyncFunction():
            declaration = self.parseFunctionDeclaration()
            exportDeclaration = self.finalize(node, Node.ExportNamedDeclaration(declaration, [], None))

        else:
            specifiers = []
            source = None
            isExportFromIdentifier = False

            expectSpecifiers = True
            if self.lookahead.type is Token.Identifier:
                specifiers.append(self.parseExportDefaultSpecifier())
                if self.match(','):
                    self.nextToken()
                else:
                    expectSpecifiers = False

            if expectSpecifiers:
                self.expect('{')
                while not self.match('}'):
                    isExportFromIdentifier = isExportFromIdentifier or self.matchKeyword('default')
                    specifiers.append(self.parseExportSpecifier())
                    if not self.match('}'):
                        self.expect(',')
                self.expect('}')

            if self.matchContextualKeyword('from'):
                # export {default} from 'foo'
                # export {foo} from 'foo'
                self.nextToken()
                source = self.parseModuleSpecifier()
                self.consumeSemicolon()
            elif isExportFromIdentifier:
                # export {default}; # missing fromClause
                message = Messages.UnexpectedToken if self.lookahead.value else Messages.MissingFromClause
                self.throwError(message, self.lookahead.value)
            else:
                # export {foo}
                self.consumeSemicolon()
            exportDeclaration = self.finalize(node, Node.ExportNamedDeclaration(None, specifiers, source))

        return exportDeclaration

Messung V0.5 in Prozent
C=96 H=93 G=94

¤ Dauer der Verarbeitung: 0.48 Sekunden  (vorverarbeitet am  2026-04-26) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.