from fontTools.feaLib.error import FeatureLibError
from fontTools.feaLib.lexer import Lexer, IncludingLexer, NonIncludingLexer
from fontTools.misc.encodingTools import getEncoding
from fontTools.misc.py23 import bytechr, tobytes, tostr
import fontTools.feaLib.ast as ast
import logging
import os
import re


log = logging.getLogger(__name__)


class Parser(object):
    """Initializes a Parser object.

    Example:

        .. code:: python

            from fontTools.feaLib.parser import Parser
            parser = Parser(file, font.getReverseGlyphMap())
            parsetree = parser.parse()

    Note: the ``glyphNames`` iterable serves a double role to help distinguish
    glyph names from ranges in the presence of hyphens and to ensure that glyph
    names referenced in a feature file are actually part of a font's glyph set.
    If the iterable is left empty, no glyph name in glyph set checking takes
    place, and all glyph tokens containing hyphens are treated as literal glyph
    names, not as ranges. (Adding a space around the hyphen can, in any case,
    help to disambiguate ranges from glyph names containing hyphens.)

    By default, the parser will follow ``include()`` statements in the feature
    file. To turn this off, pass ``followIncludes=False``. Pass a directory string as
    ``includeDir`` to explicitly declare a directory to search included feature files
    in.
    """

    extensions = {}
    ast = ast
    SS_FEATURE_TAGS = {"ss%02d" % i for i in range(1, 20 + 1)}
    CV_FEATURE_TAGS = {"cv%02d" % i for i in range(1, 99 + 1)}

    def __init__(
        self, featurefile, glyphNames=(), followIncludes=True, includeDir=None, **kwargs
    ):

        if "glyphMap" in kwargs:
            from fontTools.misc.loggingTools import deprecateArgument

            deprecateArgument("glyphMap", "use 'glyphNames' (iterable) instead")
            if glyphNames:
                raise TypeError(
                    "'glyphNames' and (deprecated) 'glyphMap' are " "mutually exclusive"
                )
            glyphNames = kwargs.pop("glyphMap")
        if kwargs:
            raise TypeError(
                "unsupported keyword argument%s: %s"
                % ("" if len(kwargs) == 1 else "s", ", ".join(repr(k) for k in kwargs))
            )

        self.glyphNames_ = set(glyphNames)
        self.doc_ = self.ast.FeatureFile()
        self.anchors_ = SymbolTable()
        self.glyphclasses_ = SymbolTable()
        self.lookups_ = SymbolTable()
        self.valuerecords_ = SymbolTable()
        self.symbol_tables_ = {self.anchors_, self.valuerecords_}
        self.next_token_type_, self.next_token_ = (None, None)
        self.cur_comments_ = []
        self.next_token_location_ = None
        lexerClass = IncludingLexer if followIncludes else NonIncludingLexer
        self.lexer_ = lexerClass(featurefile, includeDir=includeDir)
        self.advance_lexer_(comments=True)

    def parse(self):
        """Parse the file, and return a :class:`fontTools.feaLib.ast.FeatureFile`
        object representing the root of the abstract syntax tree containing the
        parsed contents of the file."""
        statements = self.doc_.statements
        while self.next_token_type_ is not None or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.is_cur_keyword_("include"):
                statements.append(self.parse_include_())
            elif self.cur_token_type_ is Lexer.GLYPHCLASS:
                statements.append(self.parse_glyphclass_definition_())
            elif self.is_cur_keyword_(("anon", "anonymous")):
                statements.append(self.parse_anonymous_())
            elif self.is_cur_keyword_("anchorDef"):
                statements.append(self.parse_anchordef_())
            elif self.is_cur_keyword_("languagesystem"):
                statements.append(self.parse_languagesystem_())
            elif self.is_cur_keyword_("lookup"):
                statements.append(self.parse_lookup_(vertical=False))
            elif self.is_cur_keyword_("markClass"):
                statements.append(self.parse_markClass_())
            elif self.is_cur_keyword_("feature"):
                statements.append(self.parse_feature_block_())
            elif self.is_cur_keyword_("table"):
                statements.append(self.parse_table_())
            elif self.is_cur_keyword_("valueRecordDef"):
                statements.append(self.parse_valuerecord_definition_(vertical=False))
            elif (
                self.cur_token_type_ is Lexer.NAME
                and self.cur_token_ in self.extensions
            ):
                statements.append(self.extensions[self.cur_token_](self))
            elif self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError(
                    "Expected feature, languagesystem, lookup, markClass, "
                    'table, or glyph class definition, got {} "{}"'.format(
                        self.cur_token_type_, self.cur_token_
                    ),
                    self.cur_token_location_,
                )
        return self.doc_

    def parse_anchor_(self):
        # Parses an anchor in any of the four formats given in the feature
        # file specification (2.e.vii).
        self.expect_symbol_("<")
        self.expect_keyword_("anchor")
        location = self.cur_token_location_

        if self.next_token_ == "NULL":  # Format D
            self.expect_keyword_("NULL")
            self.expect_symbol_(">")
            return None

        if self.next_token_type_ == Lexer.NAME:  # Format E
            name = self.expect_name_()
            anchordef = self.anchors_.resolve(name)
            if anchordef is None:
                raise FeatureLibError(
                    'Unknown anchor "%s"' % name, self.cur_token_location_
                )
            self.expect_symbol_(">")
            return self.ast.Anchor(
                anchordef.x,
                anchordef.y,
                name=name,
                contourpoint=anchordef.contourpoint,
                xDeviceTable=None,
                yDeviceTable=None,
                location=location,
            )

        x, y = self.expect_number_(), self.expect_number_()

        contourpoint = None
        if self.next_token_ == "contourpoint":  # Format B
            self.expect_keyword_("contourpoint")
            contourpoint = self.expect_number_()

        if self.next_token_ == "<":  # Format C
            xDeviceTable = self.parse_device_()
            yDeviceTable = self.parse_device_()
        else:
            xDeviceTable, yDeviceTable = None, None

        self.expect_symbol_(">")
        return self.ast.Anchor(
            x,
            y,
            name=None,
            contourpoint=contourpoint,
            xDeviceTable=xDeviceTable,
            yDeviceTable=yDeviceTable,
            location=location,
        )

    def parse_anchor_marks_(self):
        # Parses a sequence of ``[<anchor> mark @MARKCLASS]*.``
        anchorMarks = []  # [(self.ast.Anchor, markClassName)*]
        while self.next_token_ == "<":
            anchor = self.parse_anchor_()
            if anchor is None and self.next_token_ != "mark":
                continue  # <anchor NULL> without mark, eg. in GPOS type 5
            self.expect_keyword_("mark")
            markClass = self.expect_markClass_reference_()
            anchorMarks.append((anchor, markClass))
        return anchorMarks

    def parse_anchordef_(self):
        # Parses a named anchor definition (`section 2.e.viii <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#2.e.vii>`_).
        assert self.is_cur_keyword_("anchorDef")
        location = self.cur_token_location_
        x, y = self.expect_number_(), self.expect_number_()
        contourpoint = None
        if self.next_token_ == "contourpoint":
            self.expect_keyword_("contourpoint")
            contourpoint = self.expect_number_()
        name = self.expect_name_()
        self.expect_symbol_(";")
        anchordef = self.ast.AnchorDefinition(
            name, x, y, contourpoint=contourpoint, location=location
        )
        self.anchors_.define(name, anchordef)
        return anchordef

    def parse_anonymous_(self):
        # Parses an anonymous data block (`section 10 <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#10>`_).
        assert self.is_cur_keyword_(("anon", "anonymous"))
        tag = self.expect_tag_()
        _, content, location = self.lexer_.scan_anonymous_block(tag)
        self.advance_lexer_()
        self.expect_symbol_("}")
        end_tag = self.expect_tag_()
        assert tag == end_tag, "bad splitting in Lexer.scan_anonymous_block()"
        self.expect_symbol_(";")
        return self.ast.AnonymousBlock(tag, content, location=location)

    def parse_attach_(self):
        # Parses a GDEF Attach statement (`section 9.b <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#9.b>`_)
        assert self.is_cur_keyword_("Attach")
        location = self.cur_token_location_
        glyphs = self.parse_glyphclass_(accept_glyphname=True)
        contourPoints = {self.expect_number_()}
        while self.next_token_ != ";":
            contourPoints.add(self.expect_number_())
        self.expect_symbol_(";")
        return self.ast.AttachStatement(glyphs, contourPoints, location=location)

    def parse_enumerate_(self, vertical):
        # Parse an enumerated pair positioning rule (`section 6.b.ii <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#6.b.ii>`_).
        assert self.cur_token_ in {"enumerate", "enum"}
        self.advance_lexer_()
        return self.parse_position_(enumerated=True, vertical=vertical)

    def parse_GlyphClassDef_(self):
        # Parses 'GlyphClassDef @BASE, @LIGATURES, @MARKS, @COMPONENTS;'
        assert self.is_cur_keyword_("GlyphClassDef")
        location = self.cur_token_location_
        if self.next_token_ != ",":
            baseGlyphs = self.parse_glyphclass_(accept_glyphname=False)
        else:
            baseGlyphs = None
        self.expect_symbol_(",")
        if self.next_token_ != ",":
            ligatureGlyphs = self.parse_glyphclass_(accept_glyphname=False)
        else:
            ligatureGlyphs = None
        self.expect_symbol_(",")
        if self.next_token_ != ",":
            markGlyphs = self.parse_glyphclass_(accept_glyphname=False)
        else:
            markGlyphs = None
        self.expect_symbol_(",")
        if self.next_token_ != ";":
            componentGlyphs = self.parse_glyphclass_(accept_glyphname=False)
        else:
            componentGlyphs = None
        self.expect_symbol_(";")
        return self.ast.GlyphClassDefStatement(
            baseGlyphs, markGlyphs, ligatureGlyphs, componentGlyphs, location=location
        )

    def parse_glyphclass_definition_(self):
        # Parses glyph class definitions such as '@UPPERCASE = [A-Z];'
        location, name = self.cur_token_location_, self.cur_token_
        self.expect_symbol_("=")
        glyphs = self.parse_glyphclass_(accept_glyphname=False)
        self.expect_symbol_(";")
        glyphclass = self.ast.GlyphClassDefinition(name, glyphs, location=location)
        self.glyphclasses_.define(name, glyphclass)
        return glyphclass

    def split_glyph_range_(self, name, location):
        # Since v1.20, the OpenType Feature File specification allows
        # for dashes in glyph names. A sequence like "a-b-c-d" could
        # therefore mean a single glyph whose name happens to be
        # "a-b-c-d", or it could mean a range from glyph "a" to glyph
        # "b-c-d", or a range from glyph "a-b" to glyph "c-d", or a
        # range from glyph "a-b-c" to glyph "d".Technically, this
        # example could be resolved because the (pretty complex)
        # definition of glyph ranges renders most of these splits
        # invalid. But the specification does not say that a compiler
        # should try to apply such fancy heuristics. To encourage
        # unambiguous feature files, we therefore try all possible
        # splits and reject the feature file if there are multiple
        # splits possible. It is intentional that we don't just emit a
        # warning; warnings tend to get ignored. To fix the problem,
        # font designers can trivially add spaces around the intended
        # split point, and we emit a compiler error that suggests
        # how exactly the source should be rewritten to make things
        # unambiguous.
        parts = name.split("-")
        solutions = []
        for i in range(len(parts)):
            start, limit = "-".join(parts[0:i]), "-".join(parts[i:])
            if start in self.glyphNames_ and limit in self.glyphNames_:
                solutions.append((start, limit))
        if len(solutions) == 1:
            start, limit = solutions[0]
            return start, limit
        elif len(solutions) == 0:
            raise FeatureLibError(
                '"%s" is not a glyph in the font, and it can not be split '
                "into a range of known glyphs" % name,
                location,
            )
        else:
            ranges = " or ".join(['"%s - %s"' % (s, l) for s, l in solutions])
            raise FeatureLibError(
                'Ambiguous glyph range "%s"; '
                "please use %s to clarify what you mean" % (name, ranges),
                location,
            )

    def parse_glyphclass_(self, accept_glyphname, accept_null=False):
        # Parses a glyph class, either named or anonymous, or (if
        # ``bool(accept_glyphname)``) a glyph name. If ``bool(accept_null)`` then
        # also accept the special NULL glyph.
        if accept_glyphname and self.next_token_type_ in (Lexer.NAME, Lexer.CID):
            if accept_null and self.next_token_ == "NULL":
                # If you want a glyph called NULL, you should escape it.
                self.advance_lexer_()
                return self.ast.NullGlyph(location=self.cur_token_location_)
            glyph = self.expect_glyph_()
            self.check_glyph_name_in_glyph_set(glyph)
            return self.ast.GlyphName(glyph, location=self.cur_token_location_)
        if self.next_token_type_ is Lexer.GLYPHCLASS:
            self.advance_lexer_()
            gc = self.glyphclasses_.resolve(self.cur_token_)
            if gc is None:
                raise FeatureLibError(
                    "Unknown glyph class @%s" % self.cur_token_,
                    self.cur_token_location_,
                )
            if isinstance(gc, self.ast.MarkClass):
                return self.ast.MarkClassName(gc, location=self.cur_token_location_)
            else:
                return self.ast.GlyphClassName(gc, location=self.cur_token_location_)

        self.expect_symbol_("[")
        location = self.cur_token_location_
        glyphs = self.ast.GlyphClass(location=location)
        while self.next_token_ != "]":
            if self.next_token_type_ is Lexer.NAME:
                glyph = self.expect_glyph_()
                location = self.cur_token_location_
                if "-" in glyph and self.glyphNames_ and glyph not in self.glyphNames_:
                    start, limit = self.split_glyph_range_(glyph, location)
                    self.check_glyph_name_in_glyph_set(start, limit)
                    glyphs.add_range(
                        start, limit, self.make_glyph_range_(location, start, limit)
                    )
                elif self.next_token_ == "-":
                    start = glyph
                    self.expect_symbol_("-")
                    limit = self.expect_glyph_()
                    self.check_glyph_name_in_glyph_set(start, limit)
                    glyphs.add_range(
                        start, limit, self.make_glyph_range_(location, start, limit)
                    )
                else:
                    if "-" in glyph and not self.glyphNames_:
                        log.warning(
                            str(
                                FeatureLibError(
                                    f"Ambiguous glyph name that looks like a range: {glyph!r}",
                                    location,
                                )
                            )
                        )
                    self.check_glyph_name_in_glyph_set(glyph)
                    glyphs.append(glyph)
            elif self.next_token_type_ is Lexer.CID:
                glyph = self.expect_glyph_()
                if self.next_token_ == "-":
                    range_location = self.cur_token_location_
                    range_start = self.cur_token_
                    self.expect_symbol_("-")
                    range_end = self.expect_cid_()
                    self.check_glyph_name_in_glyph_set(
                        f"cid{range_start:05d}",
                        f"cid{range_end:05d}",
                    )
                    glyphs.add_cid_range(
                        range_start,
                        range_end,
                        self.make_cid_range_(range_location, range_start, range_end),
                    )
                else:
                    glyph_name = f"cid{self.cur_token_:05d}"
                    self.check_glyph_name_in_glyph_set(glyph_name)
                    glyphs.append(glyph_name)
            elif self.next_token_type_ is Lexer.GLYPHCLASS:
                self.advance_lexer_()
                gc = self.glyphclasses_.resolve(self.cur_token_)
                if gc is None:
                    raise FeatureLibError(
                        "Unknown glyph class @%s" % self.cur_token_,
                        self.cur_token_location_,
                    )
                if isinstance(gc, self.ast.MarkClass):
                    gc = self.ast.MarkClassName(gc, location=self.cur_token_location_)
                else:
                    gc = self.ast.GlyphClassName(gc, location=self.cur_token_location_)
                glyphs.add_class(gc)
            else:
                raise FeatureLibError(
                    "Expected glyph name, glyph range, "
                    f"or glyph class reference, found {self.next_token_!r}",
                    self.next_token_location_,
                )
        self.expect_symbol_("]")
        return glyphs

    def parse_glyph_pattern_(self, vertical):
        # Parses a glyph pattern, including lookups and context, e.g.::
        #
        #    a b
        #    a b c' d e
        #    a b c' lookup ChangeC d e
        prefix, glyphs, lookups, values, suffix = ([], [], [], [], [])
        hasMarks = False
        while self.next_token_ not in {"by", "from", ";", ","}:
            gc = self.parse_glyphclass_(accept_glyphname=True)
            marked = False
            if self.next_token_ == "'":
                self.expect_symbol_("'")
                hasMarks = marked = True
            if marked:
                if suffix:
                    # makeotf also reports this as an error, while FontForge
                    # silently inserts ' in all the intervening glyphs.
                    # https://github.com/fonttools/fonttools/pull/1096
                    raise FeatureLibError(
                        "Unsupported contextual target sequence: at most "
                        "one run of marked (') glyph/class names allowed",
                        self.cur_token_location_,
                    )
                glyphs.append(gc)
            elif glyphs:
                suffix.append(gc)
            else:
                prefix.append(gc)

            if self.is_next_value_():
                values.append(self.parse_valuerecord_(vertical))
            else:
                values.append(None)

            lookuplist = None
            while self.next_token_ == "lookup":
                if lookuplist is None:
                    lookuplist = []
                self.expect_keyword_("lookup")
                if not marked:
                    raise FeatureLibError(
                        "Lookups can only follow marked glyphs",
                        self.cur_token_location_,
                    )
                lookup_name = self.expect_name_()
                lookup = self.lookups_.resolve(lookup_name)
                if lookup is None:
                    raise FeatureLibError(
                        'Unknown lookup "%s"' % lookup_name, self.cur_token_location_
                    )
                lookuplist.append(lookup)
            if marked:
                lookups.append(lookuplist)

        if not glyphs and not suffix:  # eg., "sub f f i by"
            assert lookups == []
            return ([], prefix, [None] * len(prefix), values, [], hasMarks)
        else:
            if any(values[: len(prefix)]):
                raise FeatureLibError(
                    "Positioning cannot be applied in the bactrack glyph sequence, "
                    "before the marked glyph sequence.",
                    self.cur_token_location_
                )
            marked_values = values[len(prefix) : len(prefix) + len(glyphs)]
            if any(marked_values):
                if any(values[len(prefix) + len(glyphs) :]):
                    raise FeatureLibError(
                        "Positioning values are allowed only in the marked glyph "
                        "sequence, or after the final glyph node when only one glyph "
                        "node is marked.",
                        self.cur_token_location_
                    )
                values = marked_values
            elif values and values[-1]:
                if len(glyphs) > 1 or any(values[:-1]):
                    raise FeatureLibError(
                        "Positioning values are allowed only in the marked glyph "
                        "sequence, or after the final glyph node when only one glyph "
                        "node is marked.",
                        self.cur_token_location_
                    )
                values = values[-1:]
            elif any(values):
                raise FeatureLibError(
                    "Positioning values are allowed only in the marked glyph "
                    "sequence, or after the final glyph node when only one glyph "
                    "node is marked.",
                    self.cur_token_location_
                )
            return (prefix, glyphs, lookups, values, suffix, hasMarks)

    def parse_chain_context_(self):
        location = self.cur_token_location_
        prefix, glyphs, lookups, values, suffix, hasMarks = self.parse_glyph_pattern_(
            vertical=False
        )
        chainContext = [(prefix, glyphs, suffix)]
        hasLookups = any(lookups)
        while self.next_token_ == ",":
            self.expect_symbol_(",")
            (
                prefix,
                glyphs,
                lookups,
                values,
                suffix,
                hasMarks,
            ) = self.parse_glyph_pattern_(vertical=False)
            chainContext.append((prefix, glyphs, suffix))
            hasLookups = hasLookups or any(lookups)
        self.expect_symbol_(";")
        return chainContext, hasLookups

    def parse_ignore_(self):
        # Parses an ignore sub/pos rule.
        assert self.is_cur_keyword_("ignore")
        location = self.cur_token_location_
        self.advance_lexer_()
        if self.cur_token_ in ["substitute", "sub"]:
            chainContext, hasLookups = self.parse_chain_context_()
            if hasLookups:
                raise FeatureLibError(
                    'No lookups can be specified for "ignore sub"', location
                )
            return self.ast.IgnoreSubstStatement(chainContext, location=location)
        if self.cur_token_ in ["position", "pos"]:
            chainContext, hasLookups = self.parse_chain_context_()
            if hasLookups:
                raise FeatureLibError(
                    'No lookups can be specified for "ignore pos"', location
                )
            return self.ast.IgnorePosStatement(chainContext, location=location)
        raise FeatureLibError(
            'Expected "substitute" or "position"', self.cur_token_location_
        )

    def parse_include_(self):
        assert self.cur_token_ == "include"
        location = self.cur_token_location_
        filename = self.expect_filename_()
        # self.expect_symbol_(";")
        return ast.IncludeStatement(filename, location=location)

    def parse_language_(self):
        assert self.is_cur_keyword_("language")
        location = self.cur_token_location_
        language = self.expect_language_tag_()
        include_default, required = (True, False)
        if self.next_token_ in {"exclude_dflt", "include_dflt"}:
            include_default = self.expect_name_() == "include_dflt"
        if self.next_token_ == "required":
            self.expect_keyword_("required")
            required = True
        self.expect_symbol_(";")
        return self.ast.LanguageStatement(
            language, include_default, required, location=location
        )

    def parse_ligatureCaretByIndex_(self):
        assert self.is_cur_keyword_("LigatureCaretByIndex")
        location = self.cur_token_location_
        glyphs = self.parse_glyphclass_(accept_glyphname=True)
        carets = [self.expect_number_()]
        while self.next_token_ != ";":
            carets.append(self.expect_number_())
        self.expect_symbol_(";")
        return self.ast.LigatureCaretByIndexStatement(glyphs, carets, location=location)

    def parse_ligatureCaretByPos_(self):
        assert self.is_cur_keyword_("LigatureCaretByPos")
        location = self.cur_token_location_
        glyphs = self.parse_glyphclass_(accept_glyphname=True)
        carets = [self.expect_number_()]
        while self.next_token_ != ";":
            carets.append(self.expect_number_())
        self.expect_symbol_(";")
        return self.ast.LigatureCaretByPosStatement(glyphs, carets, location=location)

    def parse_lookup_(self, vertical):
        # Parses a ``lookup`` - either a lookup block, or a lookup reference
        # inside a feature.
        assert self.is_cur_keyword_("lookup")
        location, name = self.cur_token_location_, self.expect_name_()

        if self.next_token_ == ";":
            lookup = self.lookups_.resolve(name)
            if lookup is None:
                raise FeatureLibError(
                    'Unknown lookup "%s"' % name, self.cur_token_location_
                )
            self.expect_symbol_(";")
            return self.ast.LookupReferenceStatement(lookup, location=location)

        use_extension = False
        if self.next_token_ == "useExtension":
            self.expect_keyword_("useExtension")
            use_extension = True

        block = self.ast.LookupBlock(name, use_extension, location=location)
        self.parse_block_(block, vertical)
        self.lookups_.define(name, block)
        return block

    def parse_lookupflag_(self):
        # Parses a ``lookupflag`` statement, either specified by number or
        # in words.
        assert self.is_cur_keyword_("lookupflag")
        location = self.cur_token_location_

        # format B: "lookupflag 6;"
        if self.next_token_type_ == Lexer.NUMBER:
            value = self.expect_number_()
            self.expect_symbol_(";")
            return self.ast.LookupFlagStatement(value, location=location)

        # format A: "lookupflag RightToLeft MarkAttachmentType @M;"
        value_seen = False
        value, markAttachment, markFilteringSet = 0, None, None
        flags = {
            "RightToLeft": 1,
            "IgnoreBaseGlyphs": 2,
            "IgnoreLigatures": 4,
            "IgnoreMarks": 8,
        }
        seen = set()
        while self.next_token_ != ";":
            if self.next_token_ in seen:
                raise FeatureLibError(
                    "%s can be specified only once" % self.next_token_,
                    self.next_token_location_,
                )
            seen.add(self.next_token_)
            if self.next_token_ == "MarkAttachmentType":
                self.expect_keyword_("MarkAttachmentType")
                markAttachment = self.parse_glyphclass_(accept_glyphname=False)
            elif self.next_token_ == "UseMarkFilteringSet":
                self.expect_keyword_("UseMarkFilteringSet")
                markFilteringSet = self.parse_glyphclass_(accept_glyphname=False)
            elif self.next_token_ in flags:
                value_seen = True
                value = value | flags[self.expect_name_()]
            else:
                raise FeatureLibError(
                    '"%s" is not a recognized lookupflag' % self.next_token_,
                    self.next_token_location_,
                )
        self.expect_symbol_(";")

        if not any([value_seen, markAttachment, markFilteringSet]):
            raise FeatureLibError(
                "lookupflag must have a value", self.next_token_location_
            )

        return self.ast.LookupFlagStatement(
            value,
            markAttachment=markAttachment,
            markFilteringSet=markFilteringSet,
            location=location,
        )

    def parse_markClass_(self):
        assert self.is_cur_keyword_("markClass")
        location = self.cur_token_location_
        glyphs = self.parse_glyphclass_(accept_glyphname=True)
        anchor = self.parse_anchor_()
        name = self.expect_class_name_()
        self.expect_symbol_(";")
        markClass = self.doc_.markClasses.get(name)
        if markClass is None:
            markClass = self.ast.MarkClass(name)
            self.doc_.markClasses[name] = markClass
            self.glyphclasses_.define(name, markClass)
        mcdef = self.ast.MarkClassDefinition(
            markClass, anchor, glyphs, location=location
        )
        markClass.addDefinition(mcdef)
        return mcdef

    def parse_position_(self, enumerated, vertical):
        assert self.cur_token_ in {"position", "pos"}
        if self.next_token_ == "cursive":  # GPOS type 3
            return self.parse_position_cursive_(enumerated, vertical)
        elif self.next_token_ == "base":  # GPOS type 4
            return self.parse_position_base_(enumerated, vertical)
        elif self.next_token_ == "ligature":  # GPOS type 5
            return self.parse_position_ligature_(enumerated, vertical)
        elif self.next_token_ == "mark":  # GPOS type 6
            return self.parse_position_mark_(enumerated, vertical)

        location = self.cur_token_location_
        prefix, glyphs, lookups, values, suffix, hasMarks = self.parse_glyph_pattern_(
            vertical
        )
        self.expect_symbol_(";")

        if any(lookups):
            # GPOS type 8: Chaining contextual positioning; explicit lookups
            if any(values):
                raise FeatureLibError(
                    'If "lookup" is present, no values must be specified', location
                )
            return self.ast.ChainContextPosStatement(
                prefix, glyphs, suffix, lookups, location=location
            )

        # Pair positioning, format A: "pos V 10 A -10;"
        # Pair positioning, format B: "pos V A -20;"
        if not prefix and not suffix and len(glyphs) == 2 and not hasMarks:
            if values[0] is None:  # Format B: "pos V A -20;"
                values.reverse()
            return self.ast.PairPosStatement(
                glyphs[0],
                values[0],
                glyphs[1],
                values[1],
                enumerated=enumerated,
                location=location,
            )

        if enumerated:
            raise FeatureLibError(
                '"enumerate" is only allowed with pair positionings', location
            )
        return self.ast.SinglePosStatement(
            list(zip(glyphs, values)),
            prefix,
            suffix,
            forceChain=hasMarks,
            location=location,
        )

    def parse_position_cursive_(self, enumerated, vertical):
        location = self.cur_token_location_
        self.expect_keyword_("cursive")
        if enumerated:
            raise FeatureLibError(
                '"enumerate" is not allowed with ' "cursive attachment positioning",
                location,
            )
        glyphclass = self.parse_glyphclass_(accept_glyphname=True)
        entryAnchor = self.parse_anchor_()
        exitAnchor = self.parse_anchor_()
        self.expect_symbol_(";")
        return self.ast.CursivePosStatement(
            glyphclass, entryAnchor, exitAnchor, location=location
        )

    def parse_position_base_(self, enumerated, vertical):
        location = self.cur_token_location_
        self.expect_keyword_("base")
        if enumerated:
            raise FeatureLibError(
                '"enumerate" is not allowed with '
                "mark-to-base attachment positioning",
                location,
            )
        base = self.parse_glyphclass_(accept_glyphname=True)
        marks = self.parse_anchor_marks_()
        self.expect_symbol_(";")
        return self.ast.MarkBasePosStatement(base, marks, location=location)

    def parse_position_ligature_(self, enumerated, vertical):
        location = self.cur_token_location_
        self.expect_keyword_("ligature")
        if enumerated:
            raise FeatureLibError(
                '"enumerate" is not allowed with '
                "mark-to-ligature attachment positioning",
                location,
            )
        ligatures = self.parse_glyphclass_(accept_glyphname=True)
        marks = [self.parse_anchor_marks_()]
        while self.next_token_ == "ligComponent":
            self.expect_keyword_("ligComponent")
            marks.append(self.parse_anchor_marks_())
        self.expect_symbol_(";")
        return self.ast.MarkLigPosStatement(ligatures, marks, location=location)

    def parse_position_mark_(self, enumerated, vertical):
        location = self.cur_token_location_
        self.expect_keyword_("mark")
        if enumerated:
            raise FeatureLibError(
                '"enumerate" is not allowed with '
                "mark-to-mark attachment positioning",
                location,
            )
        baseMarks = self.parse_glyphclass_(accept_glyphname=True)
        marks = self.parse_anchor_marks_()
        self.expect_symbol_(";")
        return self.ast.MarkMarkPosStatement(baseMarks, marks, location=location)

    def parse_script_(self):
        assert self.is_cur_keyword_("script")
        location, script = self.cur_token_location_, self.expect_script_tag_()
        self.expect_symbol_(";")
        return self.ast.ScriptStatement(script, location=location)

    def parse_substitute_(self):
        assert self.cur_token_ in {"substitute", "sub", "reversesub", "rsub"}
        location = self.cur_token_location_
        reverse = self.cur_token_ in {"reversesub", "rsub"}
        (
            old_prefix,
            old,
            lookups,
            values,
            old_suffix,
            hasMarks,
        ) = self.parse_glyph_pattern_(vertical=False)
        if any(values):
            raise FeatureLibError(
                "Substitution statements cannot contain values", location
            )
        new = []
        if self.next_token_ == "by":
            keyword = self.expect_keyword_("by")
            while self.next_token_ != ";":
                gc = self.parse_glyphclass_(accept_glyphname=True, accept_null=True)
                new.append(gc)
        elif self.next_token_ == "from":
            keyword = self.expect_keyword_("from")
            new = [self.parse_glyphclass_(accept_glyphname=False)]
        else:
            keyword = None
        self.expect_symbol_(";")
        if len(new) == 0 and not any(lookups):
            raise FeatureLibError(
                'Expected "by", "from" or explicit lookup references',
                self.cur_token_location_,
            )

        # GSUB lookup type 3: Alternate substitution.
        # Format: "substitute a from [a.1 a.2 a.3];"
        if keyword == "from":
            if reverse:
                raise FeatureLibError(
                    'Reverse chaining substitutions do not support "from"', location
                )
            if len(old) != 1 or len(old[0].glyphSet()) != 1:
                raise FeatureLibError('Expected a single glyph before "from"', location)
            if len(new) != 1:
                raise FeatureLibError(
                    'Expected a single glyphclass after "from"', location
                )
            return self.ast.AlternateSubstStatement(
                old_prefix, old[0], old_suffix, new[0], location=location
            )

        num_lookups = len([l for l in lookups if l is not None])

        is_deletion = False
        if len(new) == 1 and len(new[0].glyphSet()) == 0:
            new = []  # Deletion
            is_deletion = True

        # GSUB lookup type 1: Single substitution.
        # Format A: "substitute a by a.sc;"
        # Format B: "substitute [one.fitted one.oldstyle] by one;"
        # Format C: "substitute [a-d] by [A.sc-D.sc];"
        if not reverse and len(old) == 1 and len(new) == 1 and num_lookups == 0:
            glyphs = list(old[0].glyphSet())
            replacements = list(new[0].glyphSet())
            if len(replacements) == 1:
                replacements = replacements * len(glyphs)
            if len(glyphs) != len(replacements):
                raise FeatureLibError(
                    'Expected a glyph class with %d elements after "by", '
                    "but found a glyph class with %d elements"
                    % (len(glyphs), len(replacements)),
                    location,
                )
            return self.ast.SingleSubstStatement(
                old, new, old_prefix, old_suffix, forceChain=hasMarks, location=location
            )

        # Glyph deletion, built as GSUB lookup type 2: Multiple substitution
        # with empty replacement.
        if is_deletion and len(old) == 1 and num_lookups == 0:
            return self.ast.MultipleSubstStatement(
                old_prefix,
                old[0],
                old_suffix,
                (),
                forceChain=hasMarks,
                location=location,
            )

        # GSUB lookup type 2: Multiple substitution.
        # Format: "substitute f_f_i by f f i;"
        if (
            not reverse
            and len(old) == 1
            and len(old[0].glyphSet()) == 1
            and len(new) > 1
            and max([len(n.glyphSet()) for n in new]) == 1
            and num_lookups == 0
        ):
            return self.ast.MultipleSubstStatement(
                old_prefix,
                tuple(old[0].glyphSet())[0],
                old_suffix,
                tuple([list(n.glyphSet())[0] for n in new]),
                forceChain=hasMarks,
                location=location,
            )

        # GSUB lookup type 4: Ligature substitution.
        # Format: "substitute f f i by f_f_i;"
        if (
            not reverse
            and len(old) > 1
            and len(new) == 1
            and len(new[0].glyphSet()) == 1
            and num_lookups == 0
        ):
            return self.ast.LigatureSubstStatement(
                old_prefix,
                old,
                old_suffix,
                list(new[0].glyphSet())[0],
                forceChain=hasMarks,
                location=location,
            )

        # GSUB lookup type 8: Reverse chaining substitution.
        if reverse:
            if len(old) != 1:
                raise FeatureLibError(
                    "In reverse chaining single substitutions, "
                    "only a single glyph or glyph class can be replaced",
                    location,
                )
            if len(new) != 1:
                raise FeatureLibError(
                    "In reverse chaining single substitutions, "
                    'the replacement (after "by") must be a single glyph '
                    "or glyph class",
                    location,
                )
            if num_lookups != 0:
                raise FeatureLibError(
                    "Reverse chaining substitutions cannot call named lookups", location
                )
            glyphs = sorted(list(old[0].glyphSet()))
            replacements = sorted(list(new[0].glyphSet()))
            if len(replacements) == 1:
                replacements = replacements * len(glyphs)
            if len(glyphs) != len(replacements):
                raise FeatureLibError(
                    'Expected a glyph class with %d elements after "by", '
                    "but found a glyph class with %d elements"
                    % (len(glyphs), len(replacements)),
                    location,
                )
            return self.ast.ReverseChainSingleSubstStatement(
                old_prefix, old_suffix, old, new, location=location
            )

        if len(old) > 1 and len(new) > 1:
            raise FeatureLibError(
                "Direct substitution of multiple glyphs by multiple glyphs "
                "is not supported",
                location,
            )

        # If there are remaining glyphs to parse, this is an invalid GSUB statement
        if len(new) != 0 or is_deletion:
            raise FeatureLibError("Invalid substitution statement", location)

        # GSUB lookup type 6: Chaining contextual substitution.
        rule = self.ast.ChainContextSubstStatement(
            old_prefix, old, old_suffix, lookups, location=location
        )
        return rule

    def parse_subtable_(self):
        assert self.is_cur_keyword_("subtable")
        location = self.cur_token_location_
        self.expect_symbol_(";")
        return self.ast.SubtableStatement(location=location)

    def parse_size_parameters_(self):
        # Parses a ``parameters`` statement used in ``size`` features. See
        # `section 8.b <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#8.b>`_.
        assert self.is_cur_keyword_("parameters")
        location = self.cur_token_location_
        DesignSize = self.expect_decipoint_()
        SubfamilyID = self.expect_number_()
        RangeStart = 0.
        RangeEnd = 0.
        if self.next_token_type_ in (Lexer.NUMBER, Lexer.FLOAT) or SubfamilyID != 0:
            RangeStart = self.expect_decipoint_()
            RangeEnd = self.expect_decipoint_()

        self.expect_symbol_(";")
        return self.ast.SizeParameters(
            DesignSize, SubfamilyID, RangeStart, RangeEnd, location=location
        )

    def parse_size_menuname_(self):
        assert self.is_cur_keyword_("sizemenuname")
        location = self.cur_token_location_
        platformID, platEncID, langID, string = self.parse_name_()
        return self.ast.FeatureNameStatement(
            "size", platformID, platEncID, langID, string, location=location
        )

    def parse_table_(self):
        assert self.is_cur_keyword_("table")
        location, name = self.cur_token_location_, self.expect_tag_()
        table = self.ast.TableBlock(name, location=location)
        self.expect_symbol_("{")
        handler = {
            "GDEF": self.parse_table_GDEF_,
            "head": self.parse_table_head_,
            "hhea": self.parse_table_hhea_,
            "vhea": self.parse_table_vhea_,
            "name": self.parse_table_name_,
            "BASE": self.parse_table_BASE_,
            "OS/2": self.parse_table_OS_2_,
            "STAT": self.parse_table_STAT_,
        }.get(name)
        if handler:
            handler(table)
        else:
            raise FeatureLibError(
                '"table %s" is not supported' % name.strip(), location
            )
        self.expect_symbol_("}")
        end_tag = self.expect_tag_()
        if end_tag != name:
            raise FeatureLibError(
                'Expected "%s"' % name.strip(), self.cur_token_location_
            )
        self.expect_symbol_(";")
        return table

    def parse_table_GDEF_(self, table):
        statements = table.statements
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.is_cur_keyword_("Attach"):
                statements.append(self.parse_attach_())
            elif self.is_cur_keyword_("GlyphClassDef"):
                statements.append(self.parse_GlyphClassDef_())
            elif self.is_cur_keyword_("LigatureCaretByIndex"):
                statements.append(self.parse_ligatureCaretByIndex_())
            elif self.is_cur_keyword_("LigatureCaretByPos"):
                statements.append(self.parse_ligatureCaretByPos_())
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError(
                    "Expected Attach, LigatureCaretByIndex, " "or LigatureCaretByPos",
                    self.cur_token_location_,
                )

    def parse_table_head_(self, table):
        statements = table.statements
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.is_cur_keyword_("FontRevision"):
                statements.append(self.parse_FontRevision_())
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError("Expected FontRevision", self.cur_token_location_)

    def parse_table_hhea_(self, table):
        statements = table.statements
        fields = ("CaretOffset", "Ascender", "Descender", "LineGap")
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.cur_token_type_ is Lexer.NAME and self.cur_token_ in fields:
                key = self.cur_token_.lower()
                value = self.expect_number_()
                statements.append(
                    self.ast.HheaField(key, value, location=self.cur_token_location_)
                )
                if self.next_token_ != ";":
                    raise FeatureLibError(
                        "Incomplete statement", self.next_token_location_
                    )
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError(
                    "Expected CaretOffset, Ascender, " "Descender or LineGap",
                    self.cur_token_location_,
                )

    def parse_table_vhea_(self, table):
        statements = table.statements
        fields = ("VertTypoAscender", "VertTypoDescender", "VertTypoLineGap")
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.cur_token_type_ is Lexer.NAME and self.cur_token_ in fields:
                key = self.cur_token_.lower()
                value = self.expect_number_()
                statements.append(
                    self.ast.VheaField(key, value, location=self.cur_token_location_)
                )
                if self.next_token_ != ";":
                    raise FeatureLibError(
                        "Incomplete statement", self.next_token_location_
                    )
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError(
                    "Expected VertTypoAscender, "
                    "VertTypoDescender or VertTypoLineGap",
                    self.cur_token_location_,
                )

    def parse_table_name_(self, table):
        statements = table.statements
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.is_cur_keyword_("nameid"):
                statement = self.parse_nameid_()
                if statement:
                    statements.append(statement)
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError("Expected nameid", self.cur_token_location_)

    def parse_name_(self):
        """Parses a name record. See `section 9.e <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#9.e>`_."""
        platEncID = None
        langID = None
        if self.next_token_type_ in Lexer.NUMBERS:
            platformID = self.expect_any_number_()
            location = self.cur_token_location_
            if platformID not in (1, 3):
                raise FeatureLibError("Expected platform id 1 or 3", location)
            if self.next_token_type_ in Lexer.NUMBERS:
                platEncID = self.expect_any_number_()
                langID = self.expect_any_number_()
        else:
            platformID = 3
            location = self.cur_token_location_

        if platformID == 1:  # Macintosh
            platEncID = platEncID or 0  # Roman
            langID = langID or 0  # English
        else:  # 3, Windows
            platEncID = platEncID or 1  # Unicode
            langID = langID or 0x0409  # English

        string = self.expect_string_()
        self.expect_symbol_(";")

        encoding = getEncoding(platformID, platEncID, langID)
        if encoding is None:
            raise FeatureLibError("Unsupported encoding", location)
        unescaped = self.unescape_string_(string, encoding)
        return platformID, platEncID, langID, unescaped

    def parse_stat_name_(self):
        platEncID = None
        langID = None
        if self.next_token_type_ in Lexer.NUMBERS:
            platformID = self.expect_any_number_()
            location = self.cur_token_location_
            if platformID not in (1, 3):
                raise FeatureLibError("Expected platform id 1 or 3", location)
            if self.next_token_type_ in Lexer.NUMBERS:
                platEncID = self.expect_any_number_()
                langID = self.expect_any_number_()
        else:
            platformID = 3
            location = self.cur_token_location_

        if platformID == 1:  # Macintosh
            platEncID = platEncID or 0  # Roman
            langID = langID or 0  # English
        else:  # 3, Windows
            platEncID = platEncID or 1  # Unicode
            langID = langID or 0x0409  # English

        string = self.expect_string_()
        encoding = getEncoding(platformID, platEncID, langID)
        if encoding is None:
            raise FeatureLibError("Unsupported encoding", location)
        unescaped = self.unescape_string_(string, encoding)
        return platformID, platEncID, langID, unescaped

    def parse_nameid_(self):
        assert self.cur_token_ == "nameid", self.cur_token_
        location, nameID = self.cur_token_location_, self.expect_any_number_()
        if nameID > 32767:
            raise FeatureLibError(
                "Name id value cannot be greater than 32767", self.cur_token_location_
            )
        if 1 <= nameID <= 6:
            log.warning(
                "Name id %d cannot be set from the feature file. "
                "Ignoring record" % nameID
            )
            self.parse_name_()  # skip to the next record
            return None

        platformID, platEncID, langID, string = self.parse_name_()
        return self.ast.NameRecord(
            nameID, platformID, platEncID, langID, string, location=location
        )

    def unescape_string_(self, string, encoding):
        if encoding == "utf_16_be":
            s = re.sub(r"\\[0-9a-fA-F]{4}", self.unescape_unichr_, string)
        else:
            unescape = lambda m: self.unescape_byte_(m, encoding)
            s = re.sub(r"\\[0-9a-fA-F]{2}", unescape, string)
        # We now have a Unicode string, but it might contain surrogate pairs.
        # We convert surrogates to actual Unicode by round-tripping through
        # Python's UTF-16 codec in a special mode.
        utf16 = tobytes(s, "utf_16_be", "surrogatepass")
        return tostr(utf16, "utf_16_be")

    @staticmethod
    def unescape_unichr_(match):
        n = match.group(0)[1:]
        return chr(int(n, 16))

    @staticmethod
    def unescape_byte_(match, encoding):
        n = match.group(0)[1:]
        return bytechr(int(n, 16)).decode(encoding)

    def parse_table_BASE_(self, table):
        statements = table.statements
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.is_cur_keyword_("HorizAxis.BaseTagList"):
                horiz_bases = self.parse_base_tag_list_()
            elif self.is_cur_keyword_("HorizAxis.BaseScriptList"):
                horiz_scripts = self.parse_base_script_list_(len(horiz_bases))
                statements.append(
                    self.ast.BaseAxis(
                        horiz_bases,
                        horiz_scripts,
                        False,
                        location=self.cur_token_location_,
                    )
                )
            elif self.is_cur_keyword_("VertAxis.BaseTagList"):
                vert_bases = self.parse_base_tag_list_()
            elif self.is_cur_keyword_("VertAxis.BaseScriptList"):
                vert_scripts = self.parse_base_script_list_(len(vert_bases))
                statements.append(
                    self.ast.BaseAxis(
                        vert_bases,
                        vert_scripts,
                        True,
                        location=self.cur_token_location_,
                    )
                )
            elif self.cur_token_ == ";":
                continue

    def parse_table_OS_2_(self, table):
        statements = table.statements
        numbers = (
            "FSType",
            "TypoAscender",
            "TypoDescender",
            "TypoLineGap",
            "winAscent",
            "winDescent",
            "XHeight",
            "CapHeight",
            "WeightClass",
            "WidthClass",
            "LowerOpSize",
            "UpperOpSize",
        )
        ranges = ("UnicodeRange", "CodePageRange")
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.cur_token_type_ is Lexer.NAME:
                key = self.cur_token_.lower()
                value = None
                if self.cur_token_ in numbers:
                    value = self.expect_number_()
                elif self.is_cur_keyword_("Panose"):
                    value = []
                    for i in range(10):
                        value.append(self.expect_number_())
                elif self.cur_token_ in ranges:
                    value = []
                    while self.next_token_ != ";":
                        value.append(self.expect_number_())
                elif self.is_cur_keyword_("Vendor"):
                    value = self.expect_string_()
                statements.append(
                    self.ast.OS2Field(key, value, location=self.cur_token_location_)
                )
            elif self.cur_token_ == ";":
                continue

    def parse_STAT_ElidedFallbackName(self):
        assert self.is_cur_keyword_("ElidedFallbackName")
        self.expect_symbol_("{")
        names = []
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_()
            if self.is_cur_keyword_("name"):
                platformID, platEncID, langID, string = self.parse_stat_name_()
                nameRecord = self.ast.STATNameStatement(
                    "stat",
                    platformID,
                    platEncID,
                    langID,
                    string,
                    location=self.cur_token_location_,
                )
                names.append(nameRecord)
            else:
                if self.cur_token_ != ";":
                    raise FeatureLibError(
                        f"Unexpected token {self.cur_token_} " f"in ElidedFallbackName",
                        self.cur_token_location_,
                    )
        self.expect_symbol_("}")
        if not names:
            raise FeatureLibError('Expected "name"', self.cur_token_location_)
        return names

    def parse_STAT_design_axis(self):
        assert self.is_cur_keyword_("DesignAxis")
        names = []
        axisTag = self.expect_tag_()
        if (
            axisTag not in ("ital", "opsz", "slnt", "wdth", "wght")
            and not axisTag.isupper()
        ):
            log.warning(f"Unregistered axis tag {axisTag} should be uppercase.")
        axisOrder = self.expect_number_()
        self.expect_symbol_("{")
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_()
            if self.cur_token_type_ is Lexer.COMMENT:
                continue
            elif self.is_cur_keyword_("name"):
                location = self.cur_token_location_
                platformID, platEncID, langID, string = self.parse_stat_name_()
                name = self.ast.STATNameStatement(
                    "stat", platformID, platEncID, langID, string, location=location
                )
                names.append(name)
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError(
                    f'Expected "name", got {self.cur_token_}', self.cur_token_location_
                )

        self.expect_symbol_("}")
        return self.ast.STATDesignAxisStatement(
            axisTag, axisOrder, names, self.cur_token_location_
        )

    def parse_STAT_axis_value_(self):
        assert self.is_cur_keyword_("AxisValue")
        self.expect_symbol_("{")
        locations = []
        names = []
        flags = 0
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                continue
            elif self.is_cur_keyword_("name"):
                location = self.cur_token_location_
                platformID, platEncID, langID, string = self.parse_stat_name_()
                name = self.ast.STATNameStatement(
                    "stat", platformID, platEncID, langID, string, location=location
                )
                names.append(name)
            elif self.is_cur_keyword_("location"):
                location = self.parse_STAT_location()
                locations.append(location)
            elif self.is_cur_keyword_("flag"):
                flags = self.expect_stat_flags()
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError(
                    f"Unexpected token {self.cur_token_} " f"in AxisValue",
                    self.cur_token_location_,
                )
        self.expect_symbol_("}")
        if not names:
            raise FeatureLibError('Expected "Axis Name"', self.cur_token_location_)
        if not locations:
            raise FeatureLibError('Expected "Axis location"', self.cur_token_location_)
        if len(locations) > 1:
            for location in locations:
                if len(location.values) > 1:
                    raise FeatureLibError(
                        "Only one value is allowed in a "
                        "Format 4 Axis Value Record, but "
                        f"{len(location.values)} were found.",
                        self.cur_token_location_,
                    )
            format4_tags = []
            for location in locations:
                tag = location.tag
                if tag in format4_tags:
                    raise FeatureLibError(
                        f"Axis tag {tag} already " "defined.", self.cur_token_location_
                    )
                format4_tags.append(tag)

        return self.ast.STATAxisValueStatement(
            names, locations, flags, self.cur_token_location_
        )

    def parse_STAT_location(self):
        values = []
        tag = self.expect_tag_()
        if len(tag.strip()) != 4:
            raise FeatureLibError(
                f"Axis tag {self.cur_token_} must be 4 " "characters",
                self.cur_token_location_,
            )

        while self.next_token_ != ";":
            if self.next_token_type_ is Lexer.FLOAT:
                value = self.expect_float_()
                values.append(value)
            elif self.next_token_type_ is Lexer.NUMBER:
                value = self.expect_number_()
                values.append(value)
            else:
                raise FeatureLibError(
                    f'Unexpected value "{self.next_token_}". '
                    "Expected integer or float.",
                    self.next_token_location_,
                )
        if len(values) == 3:
            nominal, min_val, max_val = values
            if nominal < min_val or nominal > max_val:
                raise FeatureLibError(
                    f"Default value {nominal} is outside "
                    f"of specified range "
                    f"{min_val}-{max_val}.",
                    self.next_token_location_,
                )
        return self.ast.AxisValueLocationStatement(tag, values)

    def parse_table_STAT_(self, table):
        statements = table.statements
        design_axes = []
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.cur_token_type_ is Lexer.NAME:
                if self.is_cur_keyword_("ElidedFallbackName"):
                    names = self.parse_STAT_ElidedFallbackName()
                    statements.append(self.ast.ElidedFallbackName(names))
                elif self.is_cur_keyword_("ElidedFallbackNameID"):
                    value = self.expect_number_()
                    statements.append(self.ast.ElidedFallbackNameID(value))
                    self.expect_symbol_(";")
                elif self.is_cur_keyword_("DesignAxis"):
                    designAxis = self.parse_STAT_design_axis()
                    design_axes.append(designAxis.tag)
                    statements.append(designAxis)
                    self.expect_symbol_(";")
                elif self.is_cur_keyword_("AxisValue"):
                    axisValueRecord = self.parse_STAT_axis_value_()
                    for location in axisValueRecord.locations:
                        if location.tag not in design_axes:
                            # Tag must be defined in a DesignAxis before it
                            # can be referenced
                            raise FeatureLibError(
                                "DesignAxis not defined for " f"{location.tag}.",
                                self.cur_token_location_,
                            )
                    statements.append(axisValueRecord)
                    self.expect_symbol_(";")
                else:
                    raise FeatureLibError(
                        f"Unexpected token {self.cur_token_}", self.cur_token_location_
                    )
            elif self.cur_token_ == ";":
                continue

    def parse_base_tag_list_(self):
        # Parses BASE table entries. (See `section 9.a <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#9.a>`_)
        assert self.cur_token_ in (
            "HorizAxis.BaseTagList",
            "VertAxis.BaseTagList",
        ), self.cur_token_
        bases = []
        while self.next_token_ != ";":
            bases.append(self.expect_script_tag_())
        self.expect_symbol_(";")
        return bases

    def parse_base_script_list_(self, count):
        assert self.cur_token_ in (
            "HorizAxis.BaseScriptList",
            "VertAxis.BaseScriptList",
        ), self.cur_token_
        scripts = [(self.parse_base_script_record_(count))]
        while self.next_token_ == ",":
            self.expect_symbol_(",")
            scripts.append(self.parse_base_script_record_(count))
        self.expect_symbol_(";")
        return scripts

    def parse_base_script_record_(self, count):
        script_tag = self.expect_script_tag_()
        base_tag = self.expect_script_tag_()
        coords = [self.expect_number_() for i in range(count)]
        return script_tag, base_tag, coords

    def parse_device_(self):
        result = None
        self.expect_symbol_("<")
        self.expect_keyword_("device")
        if self.next_token_ == "NULL":
            self.expect_keyword_("NULL")
        else:
            result = [(self.expect_number_(), self.expect_number_())]
            while self.next_token_ == ",":
                self.expect_symbol_(",")
                result.append((self.expect_number_(), self.expect_number_()))
            result = tuple(result)  # make it hashable
        self.expect_symbol_(">")
        return result

    def is_next_value_(self):
        return self.next_token_type_ is Lexer.NUMBER or self.next_token_ == "<"

    def parse_valuerecord_(self, vertical):
        if self.next_token_type_ is Lexer.NUMBER:
            number, location = self.expect_number_(), self.cur_token_location_
            if vertical:
                val = self.ast.ValueRecord(
                    yAdvance=number, vertical=vertical, location=location
                )
            else:
                val = self.ast.ValueRecord(
                    xAdvance=number, vertical=vertical, location=location
                )
            return val
        self.expect_symbol_("<")
        location = self.cur_token_location_
        if self.next_token_type_ is Lexer.NAME:
            name = self.expect_name_()
            if name == "NULL":
                self.expect_symbol_(">")
                return self.ast.ValueRecord()
            vrd = self.valuerecords_.resolve(name)
            if vrd is None:
                raise FeatureLibError(
                    'Unknown valueRecordDef "%s"' % name, self.cur_token_location_
                )
            value = vrd.value
            xPlacement, yPlacement = (value.xPlacement, value.yPlacement)
            xAdvance, yAdvance = (value.xAdvance, value.yAdvance)
        else:
            xPlacement, yPlacement, xAdvance, yAdvance = (
                self.expect_number_(),
                self.expect_number_(),
                self.expect_number_(),
                self.expect_number_(),
            )

        if self.next_token_ == "<":
            xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = (
                self.parse_device_(),
                self.parse_device_(),
                self.parse_device_(),
                self.parse_device_(),
            )
            allDeltas = sorted(
                [
                    delta
                    for size, delta in (xPlaDevice if xPlaDevice else ())
                    + (yPlaDevice if yPlaDevice else ())
                    + (xAdvDevice if xAdvDevice else ())
                    + (yAdvDevice if yAdvDevice else ())
                ]
            )
            if allDeltas[0] < -128 or allDeltas[-1] > 127:
                raise FeatureLibError(
                    "Device value out of valid range (-128..127)",
                    self.cur_token_location_,
                )
        else:
            xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = (None, None, None, None)

        self.expect_symbol_(">")
        return self.ast.ValueRecord(
            xPlacement,
            yPlacement,
            xAdvance,
            yAdvance,
            xPlaDevice,
            yPlaDevice,
            xAdvDevice,
            yAdvDevice,
            vertical=vertical,
            location=location,
        )

    def parse_valuerecord_definition_(self, vertical):
        # Parses a named value record definition. (See section `2.e.v <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#2.e.v>`_)
        assert self.is_cur_keyword_("valueRecordDef")
        location = self.cur_token_location_
        value = self.parse_valuerecord_(vertical)
        name = self.expect_name_()
        self.expect_symbol_(";")
        vrd = self.ast.ValueRecordDefinition(name, value, location=location)
        self.valuerecords_.define(name, vrd)
        return vrd

    def parse_languagesystem_(self):
        assert self.cur_token_ == "languagesystem"
        location = self.cur_token_location_
        script = self.expect_script_tag_()
        language = self.expect_language_tag_()
        self.expect_symbol_(";")
        return self.ast.LanguageSystemStatement(script, language, location=location)

    def parse_feature_block_(self):
        assert self.cur_token_ == "feature"
        location = self.cur_token_location_
        tag = self.expect_tag_()
        vertical = tag in {"vkrn", "vpal", "vhal", "valt"}

        stylisticset = None
        cv_feature = None
        size_feature = False
        if tag in self.SS_FEATURE_TAGS:
            stylisticset = tag
        elif tag in self.CV_FEATURE_TAGS:
            cv_feature = tag
        elif tag == "size":
            size_feature = True

        use_extension = False
        if self.next_token_ == "useExtension":
            self.expect_keyword_("useExtension")
            use_extension = True

        block = self.ast.FeatureBlock(
            tag, use_extension=use_extension, location=location
        )
        self.parse_block_(block, vertical, stylisticset, size_feature, cv_feature)
        return block

    def parse_feature_reference_(self):
        assert self.cur_token_ == "feature", self.cur_token_
        location = self.cur_token_location_
        featureName = self.expect_tag_()
        self.expect_symbol_(";")
        return self.ast.FeatureReferenceStatement(featureName, location=location)

    def parse_featureNames_(self, tag):
        """Parses a ``featureNames`` statement found in stylistic set features.
        See section `8.c <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#8.c>`_."""
        assert self.cur_token_ == "featureNames", self.cur_token_
        block = self.ast.NestedBlock(
            tag, self.cur_token_, location=self.cur_token_location_
        )
        self.expect_symbol_("{")
        for symtab in self.symbol_tables_:
            symtab.enter_scope()
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                block.statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.is_cur_keyword_("name"):
                location = self.cur_token_location_
                platformID, platEncID, langID, string = self.parse_name_()
                block.statements.append(
                    self.ast.FeatureNameStatement(
                        tag, platformID, platEncID, langID, string, location=location
                    )
                )
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError('Expected "name"', self.cur_token_location_)
        self.expect_symbol_("}")
        for symtab in self.symbol_tables_:
            symtab.exit_scope()
        self.expect_symbol_(";")
        return block

    def parse_cvParameters_(self, tag):
        # Parses a ``cvParameters`` block found in Character Variant features.
        # See section `8.d <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#8.d>`_.
        assert self.cur_token_ == "cvParameters", self.cur_token_
        block = self.ast.NestedBlock(
            tag, self.cur_token_, location=self.cur_token_location_
        )
        self.expect_symbol_("{")
        for symtab in self.symbol_tables_:
            symtab.enter_scope()

        statements = block.statements
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.is_cur_keyword_(
                {
                    "FeatUILabelNameID",
                    "FeatUITooltipTextNameID",
                    "SampleTextNameID",
                    "ParamUILabelNameID",
                }
            ):
                statements.append(self.parse_cvNameIDs_(tag, self.cur_token_))
            elif self.is_cur_keyword_("Character"):
                statements.append(self.parse_cvCharacter_(tag))
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError(
                    "Expected statement: got {} {}".format(
                        self.cur_token_type_, self.cur_token_
                    ),
                    self.cur_token_location_,
                )

        self.expect_symbol_("}")
        for symtab in self.symbol_tables_:
            symtab.exit_scope()
        self.expect_symbol_(";")
        return block

    def parse_cvNameIDs_(self, tag, block_name):
        assert self.cur_token_ == block_name, self.cur_token_
        block = self.ast.NestedBlock(tag, block_name, location=self.cur_token_location_)
        self.expect_symbol_("{")
        for symtab in self.symbol_tables_:
            symtab.enter_scope()
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                block.statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.is_cur_keyword_("name"):
                location = self.cur_token_location_
                platformID, platEncID, langID, string = self.parse_name_()
                block.statements.append(
                    self.ast.CVParametersNameStatement(
                        tag,
                        platformID,
                        platEncID,
                        langID,
                        string,
                        block_name,
                        location=location,
                    )
                )
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError('Expected "name"', self.cur_token_location_)
        self.expect_symbol_("}")
        for symtab in self.symbol_tables_:
            symtab.exit_scope()
        self.expect_symbol_(";")
        return block

    def parse_cvCharacter_(self, tag):
        assert self.cur_token_ == "Character", self.cur_token_
        location, character = self.cur_token_location_, self.expect_any_number_()
        self.expect_symbol_(";")
        if not (0xFFFFFF >= character >= 0):
            raise FeatureLibError(
                "Character value must be between "
                "{:#x} and {:#x}".format(0, 0xFFFFFF),
                location,
            )
        return self.ast.CharacterStatement(character, tag, location=location)

    def parse_FontRevision_(self):
        # Parses a ``FontRevision`` statement found in the head table. See
        # `section 9.c <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#9.c>`_.
        assert self.cur_token_ == "FontRevision", self.cur_token_
        location, version = self.cur_token_location_, self.expect_float_()
        self.expect_symbol_(";")
        if version <= 0:
            raise FeatureLibError("Font revision numbers must be positive", location)
        return self.ast.FontRevisionStatement(version, location=location)

    def parse_block_(
        self, block, vertical, stylisticset=None, size_feature=False, cv_feature=None
    ):
        self.expect_symbol_("{")
        for symtab in self.symbol_tables_:
            symtab.enter_scope()

        statements = block.statements
        while self.next_token_ != "}" or self.cur_comments_:
            self.advance_lexer_(comments=True)
            if self.cur_token_type_ is Lexer.COMMENT:
                statements.append(
                    self.ast.Comment(self.cur_token_, location=self.cur_token_location_)
                )
            elif self.cur_token_type_ is Lexer.GLYPHCLASS:
                statements.append(self.parse_glyphclass_definition_())
            elif self.is_cur_keyword_("anchorDef"):
                statements.append(self.parse_anchordef_())
            elif self.is_cur_keyword_({"enum", "enumerate"}):
                statements.append(self.parse_enumerate_(vertical=vertical))
            elif self.is_cur_keyword_("feature"):
                statements.append(self.parse_feature_reference_())
            elif self.is_cur_keyword_("ignore"):
                statements.append(self.parse_ignore_())
            elif self.is_cur_keyword_("language"):
                statements.append(self.parse_language_())
            elif self.is_cur_keyword_("lookup"):
                statements.append(self.parse_lookup_(vertical))
            elif self.is_cur_keyword_("lookupflag"):
                statements.append(self.parse_lookupflag_())
            elif self.is_cur_keyword_("markClass"):
                statements.append(self.parse_markClass_())
            elif self.is_cur_keyword_({"pos", "position"}):
                statements.append(
                    self.parse_position_(enumerated=False, vertical=vertical)
                )
            elif self.is_cur_keyword_("script"):
                statements.append(self.parse_script_())
            elif self.is_cur_keyword_({"sub", "substitute", "rsub", "reversesub"}):
                statements.append(self.parse_substitute_())
            elif self.is_cur_keyword_("subtable"):
                statements.append(self.parse_subtable_())
            elif self.is_cur_keyword_("valueRecordDef"):
                statements.append(self.parse_valuerecord_definition_(vertical))
            elif stylisticset and self.is_cur_keyword_("featureNames"):
                statements.append(self.parse_featureNames_(stylisticset))
            elif cv_feature and self.is_cur_keyword_("cvParameters"):
                statements.append(self.parse_cvParameters_(cv_feature))
            elif size_feature and self.is_cur_keyword_("parameters"):
                statements.append(self.parse_size_parameters_())
            elif size_feature and self.is_cur_keyword_("sizemenuname"):
                statements.append(self.parse_size_menuname_())
            elif (
                self.cur_token_type_ is Lexer.NAME
                and self.cur_token_ in self.extensions
            ):
                statements.append(self.extensions[self.cur_token_](self))
            elif self.cur_token_ == ";":
                continue
            else:
                raise FeatureLibError(
                    "Expected glyph class definition or statement: got {} {}".format(
                        self.cur_token_type_, self.cur_token_
                    ),
                    self.cur_token_location_,
                )

        self.expect_symbol_("}")
        for symtab in self.symbol_tables_:
            symtab.exit_scope()

        name = self.expect_name_()
        if name != block.name.strip():
            raise FeatureLibError(
                'Expected "%s"' % block.name.strip(), self.cur_token_location_
            )
        self.expect_symbol_(";")

        # A multiple substitution may have a single destination, in which case
        # it will look just like a single substitution. So if there are both
        # multiple and single substitutions, upgrade all the single ones to
        # multiple substitutions.

        # Check if we have a mix of non-contextual singles and multiples.
        has_single = False
        has_multiple = False
        for s in statements:
            if isinstance(s, self.ast.SingleSubstStatement):
                has_single = not any([s.prefix, s.suffix, s.forceChain])
            elif isinstance(s, self.ast.MultipleSubstStatement):
                has_multiple = not any([s.prefix, s.suffix, s.forceChain])

        # Upgrade all single substitutions to multiple substitutions.
        if has_single and has_multiple:
            statements = []
            for s in block.statements:
                if isinstance(s, self.ast.SingleSubstStatement):
                    glyphs = s.glyphs[0].glyphSet()
                    replacements = s.replacements[0].glyphSet()
                    if len(replacements) == 1:
                        replacements *= len(glyphs)
                    for i, glyph in enumerate(glyphs):
                        statements.append(
                            self.ast.MultipleSubstStatement(
                                s.prefix,
                                glyph,
                                s.suffix,
                                [replacements[i]],
                                s.forceChain,
                                location=s.location,
                            )
                        )
                else:
                    statements.append(s)
            block.statements = statements

    def is_cur_keyword_(self, k):
        if self.cur_token_type_ is Lexer.NAME:
            if isinstance(k, type("")):  # basestring is gone in Python3
                return self.cur_token_ == k
            else:
                return self.cur_token_ in k
        return False

    def expect_class_name_(self):
        self.advance_lexer_()
        if self.cur_token_type_ is not Lexer.GLYPHCLASS:
            raise FeatureLibError("Expected @NAME", self.cur_token_location_)
        return self.cur_token_

    def expect_cid_(self):
        self.advance_lexer_()
        if self.cur_token_type_ is Lexer.CID:
            return self.cur_token_
        raise FeatureLibError("Expected a CID", self.cur_token_location_)

    def expect_filename_(self):
        self.advance_lexer_()
        if self.cur_token_type_ is not Lexer.FILENAME:
            raise FeatureLibError("Expected file name", self.cur_token_location_)
        return self.cur_token_

    def expect_glyph_(self):
        self.advance_lexer_()
        if self.cur_token_type_ is Lexer.NAME:
            self.cur_token_ = self.cur_token_.lstrip("\\")
            if len(self.cur_token_) > 63:
                raise FeatureLibError(
                    "Glyph names must not be longer than 63 characters",
                    self.cur_token_location_,
                )
            return self.cur_token_
        elif self.cur_token_type_ is Lexer.CID:
            return "cid%05d" % self.cur_token_
        raise FeatureLibError("Expected a glyph name or CID", self.cur_token_location_)

    def check_glyph_name_in_glyph_set(self, *names):
        """Raises if glyph name (just `start`) or glyph names of a
        range (`start` and `end`) are not in the glyph set.

        If no glyph set is present, does nothing.
        """
        if self.glyphNames_:
            missing = [name for name in names if name not in self.glyphNames_]
            if missing:
                raise FeatureLibError(
                    "The following glyph names are referenced but are missing from the "
                    f"glyph set: {', '.join(missing)}",
                    self.cur_token_location_,
                )

    def expect_markClass_reference_(self):
        name = self.expect_class_name_()
        mc = self.glyphclasses_.resolve(name)
        if mc is None:
            raise FeatureLibError(
                "Unknown markClass @%s" % name, self.cur_token_location_
            )
        if not isinstance(mc, self.ast.MarkClass):
            raise FeatureLibError(
                "@%s is not a markClass" % name, self.cur_token_location_
            )
        return mc

    def expect_tag_(self):
        self.advance_lexer_()
        if self.cur_token_type_ is not Lexer.NAME:
            raise FeatureLibError("Expected a tag", self.cur_token_location_)
        if len(self.cur_token_) > 4:
            raise FeatureLibError(
                "Tags cannot be longer than 4 characters", self.cur_token_location_
            )
        return (self.cur_token_ + "    ")[:4]

    def expect_script_tag_(self):
        tag = self.expect_tag_()
        if tag == "dflt":
            raise FeatureLibError(
                '"dflt" is not a valid script tag; use "DFLT" instead',
                self.cur_token_location_,
            )
        return tag

    def expect_language_tag_(self):
        tag = self.expect_tag_()
        if tag == "DFLT":
            raise FeatureLibError(
                '"DFLT" is not a valid language tag; use "dflt" instead',
                self.cur_token_location_,
            )
        return tag

    def expect_symbol_(self, symbol):
        self.advance_lexer_()
        if self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == symbol:
            return symbol
        raise FeatureLibError("Expected '%s'" % symbol, self.cur_token_location_)

    def expect_keyword_(self, keyword):
        self.advance_lexer_()
        if self.cur_token_type_ is Lexer.NAME and self.cur_token_ == keyword:
            return self.cur_token_
        raise FeatureLibError('Expected "%s"' % keyword, self.cur_token_location_)

    def expect_name_(self):
        self.advance_lexer_()
        if self.cur_token_type_ is Lexer.NAME:
            return self.cur_token_
        raise FeatureLibError("Expected a name", self.cur_token_location_)

    def expect_number_(self):
        self.advance_lexer_()
        if self.cur_token_type_ is Lexer.NUMBER:
            return self.cur_token_
        raise FeatureLibError("Expected a number", self.cur_token_location_)

    def expect_any_number_(self):
        self.advance_lexer_()
        if self.cur_token_type_ in Lexer.NUMBERS:
            return self.cur_token_
        raise FeatureLibError(
            "Expected a decimal, hexadecimal or octal number", self.cur_token_location_
        )

    def expect_float_(self):
        self.advance_lexer_()
        if self.cur_token_type_ is Lexer.FLOAT:
            return self.cur_token_
        raise FeatureLibError(
            "Expected a floating-point number", self.cur_token_location_
        )

    def expect_decipoint_(self):
        if self.next_token_type_ == Lexer.FLOAT:
            return self.expect_float_()
        elif self.next_token_type_ is Lexer.NUMBER:
            return self.expect_number_() / 10
        else:
            raise FeatureLibError(
                "Expected an integer or floating-point number", self.cur_token_location_
            )

    def expect_stat_flags(self):
        value = 0
        flags = {
            "OlderSiblingFontAttribute": 1,
            "ElidableAxisValueName": 2,
        }
        while self.next_token_ != ";":
            if self.next_token_ in flags:
                name = self.expect_name_()
                value = value | flags[name]
            else:
                raise FeatureLibError(
                    f"Unexpected STAT flag {self.cur_token_}", self.cur_token_location_
                )
        return value

    def expect_stat_values_(self):
        if self.next_token_type_ == Lexer.FLOAT:
            return self.expect_float_()
        elif self.next_token_type_ is Lexer.NUMBER:
            return self.expect_number_()
        else:
            raise FeatureLibError(
                "Expected an integer or floating-point number", self.cur_token_location_
            )

    def expect_string_(self):
        self.advance_lexer_()
        if self.cur_token_type_ is Lexer.STRING:
            return self.cur_token_
        raise FeatureLibError("Expected a string", self.cur_token_location_)

    def advance_lexer_(self, comments=False):
        if comments and self.cur_comments_:
            self.cur_token_type_ = Lexer.COMMENT
            self.cur_token_, self.cur_token_location_ = self.cur_comments_.pop(0)
            return
        else:
            self.cur_token_type_, self.cur_token_, self.cur_token_location_ = (
                self.next_token_type_,
                self.next_token_,
                self.next_token_location_,
            )
        while True:
            try:
                (
                    self.next_token_type_,
                    self.next_token_,
                    self.next_token_location_,
                ) = next(self.lexer_)
            except StopIteration:
                self.next_token_type_, self.next_token_ = (None, None)
            if self.next_token_type_ != Lexer.COMMENT:
                break
            self.cur_comments_.append((self.next_token_, self.next_token_location_))

    @staticmethod
    def reverse_string_(s):
        """'abc' --> 'cba'"""
        return "".join(reversed(list(s)))

    def make_cid_range_(self, location, start, limit):
        """(location, 999, 1001) --> ["cid00999", "cid01000", "cid01001"]"""
        result = list()
        if start > limit:
            raise FeatureLibError(
                "Bad range: start should be less than limit", location
            )
        for cid in range(start, limit + 1):
            result.append("cid%05d" % cid)
        return result

    def make_glyph_range_(self, location, start, limit):
        """(location, "a.sc", "d.sc") --> ["a.sc", "b.sc", "c.sc", "d.sc"]"""
        result = list()
        if len(start) != len(limit):
            raise FeatureLibError(
                'Bad range: "%s" and "%s" should have the same length' % (start, limit),
                location,
            )

        rev = self.reverse_string_
        prefix = os.path.commonprefix([start, limit])
        suffix = rev(os.path.commonprefix([rev(start), rev(limit)]))
        if len(suffix) > 0:
            start_range = start[len(prefix) : -len(suffix)]
            limit_range = limit[len(prefix) : -len(suffix)]
        else:
            start_range = start[len(prefix) :]
            limit_range = limit[len(prefix) :]

        if start_range >= limit_range:
            raise FeatureLibError(
                "Start of range must be smaller than its end", location
            )

        uppercase = re.compile(r"^[A-Z]$")
        if uppercase.match(start_range) and uppercase.match(limit_range):
            for c in range(ord(start_range), ord(limit_range) + 1):
                result.append("%s%c%s" % (prefix, c, suffix))
            return result

        lowercase = re.compile(r"^[a-z]$")
        if lowercase.match(start_range) and lowercase.match(limit_range):
            for c in range(ord(start_range), ord(limit_range) + 1):
                result.append("%s%c%s" % (prefix, c, suffix))
            return result

        digits = re.compile(r"^[0-9]{1,3}$")
        if digits.match(start_range) and digits.match(limit_range):
            for i in range(int(start_range, 10), int(limit_range, 10) + 1):
                number = ("000" + str(i))[-len(start_range) :]
                result.append("%s%s%s" % (prefix, number, suffix))
            return result

        raise FeatureLibError('Bad range: "%s-%s"' % (start, limit), location)


class SymbolTable(object):
    def __init__(self):
        self.scopes_ = [{}]

    def enter_scope(self):
        self.scopes_.append({})

    def exit_scope(self):
        self.scopes_.pop()

    def define(self, name, item):
        self.scopes_[-1][name] = item

    def resolve(self, name):
        for scope in reversed(self.scopes_):
            item = scope.get(name)
            if item:
                return item
        return None
