
    jke                        d dl mZ d dlmZmZmZ d dlmZ d dlm	Z	 d dl
mZmZmZ d dlmc mZ d dlZd dlZd dlZ ej(                  e      Z G d de      Z G d	 d
e      Zy)    )FeatureLibError)LexerIncludingLexerNonIncludingLexer)VariableScalar)getEncoding)bytechrtobytestostrNc                      e Zd ZdZi ZeZ edd      D  ch c]  }d|z  	 c}} Z edd      D  ch c]  }d|z  	 c}} Z	 dgdZ	d	 Z
d
 Zd Zd Zd Zd Zd Zd Zd Zd ZdhdZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d  Z!d! Z"d" Z#d# Z$d$ Z%d% Z&d& Z'd' Z(d( Z)d) Z*d* Z+d+ Z,d, Z-d- Z.d. Z/d/ Z0d0 Z1d1 Z2d2 Z3e4d3        Z5e4d4        Z6d5 Z7d6 Z8d7 Z9d8 Z:d9 Z;d: Z<d; Z=d< Z>d= Z?d> Z@d? ZAd@ ZBdA ZCdB ZDdC ZEdhdDZFdE ZGdF ZHdG ZIdH ZJdI ZKdJ ZLdK ZM	 didLZNdM ZOdN ZPdO ZQdP ZRdQ ZSdR ZTdS ZUdT ZVdU ZWdV ZXdW ZYdX ZZdY Z[dhdZZ\d[ Z]d\ Z^d] Z_d^ Z`d_ Zad` Zbda Zcdb ZddhdcZee4dd        Zfde Zgdf Zhyc c}} w c c}} w )jParsera
  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.
          zss%02dd   zcv%02dNc           	         d|v r-ddl m}  |dd       |rt        d      |j                  d      }|r7t        dt	        |      dk(  rdnd	d
dj                  d |D                    t        |      | _        | j                  j                         | _
        t               | _        t               | _        t               | _        t               | _        | j                  | j                  h| _        d\  | _        | _        g | _        d | _        |rt*        nt,        } |||      | _        i | _        | j3                  d       y )NglyphMapr   )deprecateArgumentz#use 'glyphNames' (iterable) insteadz?'glyphNames' and (deprecated) 'glyphMap' are mutually exclusivezunsupported keyword argumentr    sz: z, c              3   2   K   | ]  }t        |        y wN)repr).0ks     9/usr/lib/python3/dist-packages/fontTools/feaLib/parser.py	<genexpr>z"Parser.__init__.<locals>.<genexpr><   s     =V!d1g=Vs   NN)
includeDirTcomments)fontTools.misc.loggingToolsr   	TypeErrorpoplenjoinsetglyphNames_astFeatureFiledoc_SymbolTableanchors_glyphclasses_lookups_valuerecords_symbol_tables_next_token_type_next_token_cur_comments_next_token_location_r   r   lexer_missingadvance_lexer_)selffeaturefile
glyphNamesfollowIncludesr   kwargsr   
lexerClasss           r   __init__zParser.__init__-   s&    Ej*OPX   J/JV)2s2DII=Vv=V4VX 
 z?HH((*	#(]#(]#}}d.@.@A2>/t/$(!'5^;L
 DT*    c           	         | j                   j                  }| j                  | j                  r| j	                  d       | j
                  t        j                  u rB|j                  | j                  j                  | j                  | j                               n1| j                  d      r!|j                  | j                                n| j
                  t        j                  u r!|j                  | j!                                n| j                  d      r!|j                  | j#                                n| j                  d      r!|j                  | j%                                n^| j                  d      r!|j                  | j'                                n,| j                  d	      r#|j                  | j)                  d
             n| j                  d      r!|j                  | j+                                n| j                  d      r!|j                  | j-                                n| j                  d      r!|j                  | j/                                nb| j                  d      r#|j                  | j-                  d             n.| j                  d      r |j                  | j1                                n| j                  d      r"|j                  | j3                  d
             n| j
                  t        j4                  u rG| j                  | j6                  v r/|j                   | j6                  | j                     |              ng| j
                  t        j8                  u r| j                  dk(  rt;        dj=                  | j
                  | j                        | j                        | j                  | j                  r| j>                  rQ| j>                  jA                         D cg c]  \  }}d|d|d }}}t;        ddjC                  |      z   d      | j                   S c c}}w )zParse 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.NTr   locationincludeanon	anonymous	anchorDeflanguagesystemlookupFvertical	markClassfeatureconditionset	variation)rO   tablevalueRecordDef;zbExpected feature, languagesystem, lookup, markClass, table, or glyph class definition, got {} "{}" z (first found at )zMThe following glyph names are referenced but are missing from the glyph set:

)"r*   
statementsr1   r3   r7   cur_token_type_r   COMMENTappendr(   Comment
cur_token_cur_token_location_is_cur_keyword_parse_include_
GLYPHCLASSparse_glyphclass_definition_parse_anonymous_parse_anchordef_parse_languagesystem_parse_lookup_parse_markClass_parse_feature_block_parse_conditionset_parse_table_parse_valuerecord_definition_NAME
extensionsSYMBOLr   formatr6   itemsr%   )r8   rV   namelocerrors        r   parsezParser.parseN   s{    YY))
##/43E3E.##u}}4!!HH$$T__t?W?W$X %%i0!!$"5"5"78%%)9)99!!$"C"C"EF%%&;<!!$"7"7"9:%%k2!!$"7"7"9:%%&67!!$"<"<">?%%h/!!$"4"4e"4"DE%%k2!!$"7"7"9:%%i0!!$";";"=>%%n5!!$":":"<=%%k2!!$";";d";"KL%%g.!!$"3"3"56%%&67!!$"D"De"D"TU$$

2OOt6!!"B$//$//"B4"HI%%5$//S:P%DDJF,,dooE ,, M ##/43E3E\ << "&!3!3!5D# .237E  ""&))E"24 
 yys   Qc           	         | j                  d       | j                  d       | j                  }| j                  dk(  r#| j                  d       | j                  d       y | j                  t
        j                  k(  r| j                         }| j                  j                  |      }|t        d|z  | j                        | j                  d       | j                  j                  |j                  |j                  ||j                  d d |      S | j!                  d      | j!                  d      }}d }| j                  d	k(  r!| j                  d	       | j!                         }| j                  dk(  r!| j#                         }| j#                         }nd
\  }}| j                  d       | j                  j                  ||d ||||      S )N<anchorNULL>zUnknown anchor "%s")ro   contourpointxDeviceTableyDeviceTablerB   Tvariablerx   r   )expect_symbol_expect_keyword_r\   r2   r1   r   rj   expect_name_r,   resolver   r(   Anchorxyrx   expect_number_parse_device_)	r8   rB   ro   	anchordefr   r   rx   ry   rz   s	            r   parse_anchor_zParser.parse_anchor_   s    	C X&++v%  ($  EJJ.$$&D--d3I %)D0$2J2J  $88??&33!!! #   ""D"143F3FPT3F3U1~-  0..0Ls"--/L--/L)3&L,C xx%%%  
 	
r?   c                     g }| j                   dk(  rf| j                         }|| j                   dk7  r1| j                  d       | j                         }|j	                  ||f       | j                   dk(  rf|S )Nrt   mark)r2   r   r~   expect_markClass_reference_rY   )r8   anchorMarksru   rL   s       r   parse_anchor_marks_zParser.parse_anchor_marks_   s    #%'')F~$"2"2f"<  (88:I	23 #% r?   c                    | j                  d      sJ | j                  }| j                         | j                         }}d }| j                  dk(  r!| j	                  d       | j                         }| j                         }| j                  d       | j                  j                  |||||      }| j                  j                  ||       |S )NrG   rx   rR   )rx   rB   )r]   r\   r   r2   r~   r   r}   r(   AnchorDefinitionr,   define)r8   rB   r   r   rx   ro   r   s          r   rb   zParser.parse_anchordef_   s    ##K000++""$d&9&9&;1~-  0..0L  "C HH--!Q\H . 
	 	T9-r?   c                 ^   | j                  d      sJ | j                         }| j                  j                  |      \  }}}| j	                          | j                  d       | j                         }||k(  sJ d       | j                  d       | j                  j                  |||      S )NrD   }z-bad splitting in Lexer.scan_anonymous_block()rR   rA   )r]   expect_tag_r5   scan_anonymous_blockr7   r}   r(   AnonymousBlock)r8   tag_contentrB   end_tags         r   ra   zParser.parse_anonymous_   s    ##$9::: #{{??D7HC ""$g~NNN~C xx&&sGh&GGr?   c                 `   | j                  d      sJ | j                  }| j                  d      }| j                         h}| j                  dk7  r/|j                  | j                                | j                  dk7  r/| j                  d       | j                  j                  |||      S )NAttachTaccept_glyphnamerR   rA   )	r]   r\   parse_glyphclass_r   r2   addr}   r(   AttachStatement)r8   rB   glyphscontourPointss       r   parse_attach_zParser.parse_attach_   s    ##H---++'''>,,./#%d1134 #%C xx'''QQr?   c                 h    | j                   dv sJ | j                          | j                  d|      S )N>   enum	enumerateT
enumeratedrK   )r[   r7   parse_position_)r8   rK   s     r   parse_enumerate_zParser.parse_enumerate_   s7    "7777##th#GGr?   c                 (   | j                  d      sJ | j                  }| j                  dk7  r| j                  d      }nd }| j	                  d       | j                  dk7  r| j                  d      }nd }| j	                  d       | j                  dk7  r| j                  d      }nd }| j	                  d       | j                  dk7  r| j                  d      }nd }| j	                  d       | j
                  j                  |||||      S )NGlyphClassDef,Fr   rR   rA   )r]   r\   r2   r   r}   r(   GlyphClassDefStatement)r8   rB   
baseGlyphsligatureGlyphs
markGlyphscomponentGlyphss         r   parse_GlyphClassDef_zParser.parse_GlyphClassDef_   s   ##O444++s"///GJJC s"!33U3KN!NC s"///GJJC s""44e4LO"OC xx..
NOh / 
 	
r?   c                    | j                   | j                  }}| j                  d       | j                  d      }| j                  d       | j                  j                  |||      }| j                  j                  ||       |S )N=Fr   rR   rA   )r\   r[   r}   r   r(   GlyphClassDefinitionr-   r   )r8   rB   ro   r   
glyphclasss        r   r`   z#Parser.parse_glyphclass_definition_  s{    114??$C '''?C XX224(2S
!!$
3r?   c                    |j                  d      }g }t        t        |            D ][  }dj                  |d|       dj                  ||d        }}|| j                  v s:|| j                  v sI|j                  ||f       ] t        |      dk(  r|d   \  }}||fS t        |      dk(  rt        d|z  |      dj                  |D 	cg c]  \  }}	d|d|	d c}	}      }
t        d|d	|
d
|      c c}	}w )N-r   r   zU"%s" is not a glyph in the font, and it can not be split into a range of known glyphsz or "z - zAmbiguous glyph range "z"; please use z to clarify what you mean)splitranger$   r%   r'   rY   r   )r8   ro   rB   parts	solutionsistartlimitr   lrangess              r   split_glyph_range_zParser.split_glyph_range_#  s   & 

3	s5z" 	1A88E!AJ/%)1D5E(((Ud6F6F-F  %0	1 y>Q$Q<LE5%<^q !/156  [[9!M41aA"6!MNF!<@&J  "Ns   C;
c           	      
   |r| j                   t        j                  t        j                  fv r|rE| j                  dk(  r6| j                          | j                  j                  | j                        S | j                         }| j                  |       | j                  j                  || j                        S | j                   t        j                  u r| j                          | j                  j                  | j                        }|#t!        d| j                  z  | j                        t#        || j                  j$                        r'| j                  j'                  || j                        S | j                  j)                  || j                        S | j+                  d       | j                  }| j                  j-                  |      }| j                  dk7  r| j                   t        j                  u rP| j                         }| j                  }d|v rg| j.                  r[|| j.                  vrM| j1                  ||      \  }}| j                  ||       |j3                  ||| j5                  |||             n| j                  dk(  r[|}| j+                  d       | j                         }| j                  ||       |j3                  ||| j5                  |||             nad|v r7| j.                  s+t6        j9                  t;        t!        d||                   | j                  |       |j=                  |       n| j                   t        j                  u r| j                         }| j                  dk(  ry| j                  }	| j                  }
| j+                  d       | j?                         }| j                  d|
d	d|d	       |jA                  |
|| jC                  |	|
|             nNd| j                  d	}| j                  |       |j=                  |       n| j                   t        j                  u r| j                          | j                  j                  | j                        }|#t!        d| j                  z  | j                        t#        || j                  j$                        r(| j                  j'                  || j                        }n'| j                  j)                  || j                        }|jE                  |       n#t!        d
| j                  | jF                        | j                  dk7  r| j+                  d       |S )Nrv   rA   zUnknown glyph class @%s[]r   z.Ambiguous glyph name that looks like a range: cid05dzBExpected glyph name, glyph range, or glyph class reference, found )$r1   r   rj   CIDr2   r7   r(   	NullGlyphr\   expect_glyph_check_glyph_name_in_glyph_set	GlyphNamer_   r-   r   r[   r   
isinstance	MarkClassMarkClassNameGlyphClassNamer}   
GlyphClassr'   r   	add_rangemake_glyph_range_logwarningstrrY   expect_cid_add_cid_rangemake_cid_range_	add_classr4   )r8   r   accept_nullglyphgcrB   r   r   r   range_locationrange_start	range_end
glyph_names                r   r   zParser.parse_glyphclass_M  s     5 5%**eii9P Pt//69##%xx))43K3K)LL&&(E..u588%%ed6N6N%OO  E$4$44!##++DOO<Bz%-?,,  "dhh001xx--b4;S;S-TTxx..rD<T<T.UUC ++$$h$7#%$$

2**,33%<D$4$4dFVFV9V#'#:#:5(#KLE566ueD$$ud&<&<Xue&T %%,!E'', ..0E66ueD$$ud&<&<Xue&T e|D,<,< /&TUZT]$^$,!" 66u=MM%(&&%))3**,##s*%)%=%=N"&//K'', $ 0 0 2I66k#./i_- ((#!,,^[)T $'ts&;!<J66zBMM*-&&%*:*::##%''//@:)1DOOC00  b$(("4"45//T=U=U/VB00d>V>V0WB  $%77;7G7G6JL-- A #%J 	C r?   c                    g g g g g f\  }}}}}d}| j                   dvr| j                  d      }d}	| j                   dk(  r| j                  d       dx}}	|	r*|rt        d| j                        |j                  |       n%|r|j                  |       n|j                  |       | j                         r!|j                  | j                  |             n|j                  d        d }
| j                   dk(  r|
g }
| j                  d       |	st        d| j                        | j                         }| j                  j                  |      }|t        d	|z  | j                        |
j                  |       | j                   dk(  r|	r|j                  |
       | j                   dvr|s|s|g k(  sJ g |d gt        |      z  |g |fS t        |d t        |             rt        d
| j                        |t        |      t        |      t        |      z    }t        |      r<t        |t        |      t        |      z   d        rt        d| j                        |}n`|r=|d   r8t        |      dkD  st        |d d       rt        d| j                        |dd  }n!t        |      rt        d| j                        ||||||fS )NF>   byfromr   rR   Tr   'z_Unsupported contextual target sequence: at most one run of marked (') glyph/class names allowedrI   z%Lookups can only follow marked glyphsUnknown lookup "%s"z_Positioning cannot be applied in the bactrack glyph sequence, before the marked glyph sequence.zPositioning values are allowed only in the marked glyph sequence, or after the final glyph node when only one glyph node is marked.r   )r2   r   r}   r   r\   rY   is_next_value_parse_valuerecord_r~   r   r.   r   r$   any)r8   rK   prefixr   lookupsvaluessuffixhasMarksr   marked
lookuplistlookup_namerI   marked_valuess                 r   parse_glyph_pattern_zParser.parse_glyph_pattern_  s
    46r2r22F/&>>'''>BF3&##C($((6 *J00 
 b!b!b!""$d55h?@d#J""h.%!#J$$X.)?00  #//1..{;>)-;T=U=U  !!&) ""h.  z*[ &>>^ fb= =V 4fb(KK6-CK()%8,, 
 #3v;Vs6{1JKM=!vc&kCK79:;)* 00	  'F2Jv;?c&"+&6)* 00	   V%& ,,	  FGVVXFFr?   c                    | j                   }| j                  d      \  }}}}}}t        |      rt        d| d|      |s8t        d| d|      }	t        j                  t        |	             |dd  |dd }}|||f}
|
S )	NFrJ   z(No lookups can be specified for "ignore r   zAmbiguous "ignore z)", there should be least one marked glyphr   r   )r\   r   r   r   r   r   r   )r8   subrB   r   r   r   r   r   r   rq   chainContexts              r   parse_ignore_glyph_pattern_z"Parser.parse_ignore_glyph_pattern_  s    ++<@<U<U =V =
9 w<!:3%qA8  #$SE)RSE KKE
##ABZ!FF/r?   c                    | j                   }| j                  |      g}| j                  dk(  rA| j                  d       |j	                  | j                  |             | j                  dk(  rA| j                  d       |S )Nr   rR   )r\   r   r2   r}   rY   )r8   r   rB   r   s       r   parse_ignore_context_zParser.parse_ignore_context_!  s{    ++88=>#%$ @ @ EF #% 	C r?   c                 |   | j                  d      sJ | j                  }| j                          | j                  dv r.| j	                  d      }| j
                  j                  ||      S | j                  dv r.| j	                  d      }| j
                  j                  ||      S t        d| j                        )Nignore)
substituter   r   rA   )positionposr   z#Expected "substitute" or "position")	r]   r\   r7   r[   r   r(   IgnoreSubstStatementIgnorePosStatementr   )r8   rB   r   s      r   parse_ignore_zParser.parse_ignore_*  s    ##H---++??3355e<L88000QQ??1155e<L88..|h.OO143K3K
 	
r?   c                     | j                   dk(  sJ | j                  }| j                         }t        j                  ||      S )NrC   rA   )r[   r\   expect_filename_r(   IncludeStatement)r8   rB   filenames      r   r^   zParser.parse_include_9  s@    )+++++((*##Hx@@r?   c                 P   | j                  d      sJ | j                  }| j                         }d\  }}| j                  dv r| j	                         dk(  }| j                  dk(  r| j                  d       d}| j                  d       | j                  j                  ||||      S )	Nlanguage)TF>   exclude_dfltinclude_dfltr  requiredTrR   rA   )	r]   r\   expect_language_tag_r2   r   r~   r}   r(   LanguageStatement)r8   rB   r	  include_defaultr  s        r   parse_language_zParser.parse_language_@  s    ##J///++,,.$1!??"//1^COz)  ,HC xx))ox( * 
 	
r?   c                 `   | j                  d      sJ | j                  }| j                  d      }| j                         g}| j                  dk7  r/|j                  | j                                | j                  dk7  r/| j                  d       | j                  j                  |||      S )NLigatureCaretByIndexTr   rR   rA   )	r]   r\   r   r   r2   rY   r}   r(   LigatureCaretByIndexStatementr8   rB   r   caretss       r   parse_ligatureCaretByIndex_z"Parser.parse_ligatureCaretByIndex_O  s    ##$:;;;++'''>%%'(#%MM$--/0 #%C xx55ffx5XXr?   c                 h   | j                  d      sJ | j                  }| j                  d      }| j                  d      g}| j                  dk7  r1|j                  | j                  d             | j                  dk7  r1| j                  d       | j                  j                  |||      S )NLigatureCaretByPosTr   r{   rR   rA   )	r]   r\   r   r   r2   rY   r}   r(   LigatureCaretByPosStatementr  s       r   parse_ligatureCaretByPos_z Parser.parse_ligatureCaretByPos_Y  s    ##$8999++'''>%%t%45#%MM$--t-<= #%C xx33FFX3VVr?   c                 *   | j                  d      sJ | j                  | j                         }}| j                  dk(  rd| j                  j                  |      }|t        d|z  | j                        | j                  d       | j                  j                  ||      S d}| j                  dk(  r| j                  d       d}| j                  j                  |||      }| j                  ||       | j                  j                  ||       |S )NrI   rR   r   rA   FuseExtensionT)r]   r\   r   r2   r.   r   r   r}   r(   LookupReferenceStatementr~   LookupBlockparse_block_r   )r8   rK   rB   ro   rI   use_extensionblocks          r   rd   zParser.parse_lookup_c  s    ##H---1143D3D3F$s"]]**40F~%)D0$2J2J  $8844Vh4OO~-  0 M$$T=8$L%*T5)r?   c                 
   | j                  d      sJ | j                  }| j                  t        j                  k(  r>| j                         }| j                  d       | j                  j                  ||      S d}d\  }}}dddd	d
}t               }| j                  dk7  r| j                  |v r#t        d| j                  z  | j                        |j                  | j                         | j                  dk(  r$| j                  d       | j                  d      }n}| j                  dk(  r$| j                  d       | j                  d      }nJ| j                  |v rd}||| j!                            z  }n#t        d| j                  z  | j                        | j                  dk7  r| j                  d       t#        |||g      st        d| j                        | j                  j                  ||||      S )N
lookupflagrR   rA   F)r   NNr            )RightToLeftIgnoreBaseGlyphsIgnoreLigaturesIgnoreMarksz%s can be specified only onceMarkAttachmentTyper   UseMarkFilteringSetTz#"%s" is not a recognized lookupflagzlookupflag must have a value)markAttachmentmarkFilteringSetrB   )r]   r\   r1   r   NUMBERr   r}   r(   LookupFlagStatementr&   r2   r   r4   r   r~   r   r   r   )r8   rB   value
value_seenr-  r.  flagsseens           r   parse_lookupflag_zParser.parse_lookupflag_|  s    ##L111++   ELL0'')E$88///II 
2?/~/ ! 	
 u#%4'%3d6F6FF--  HHT%%&#77$$%9:!%!7!7!7!O!!%::$$%:;#'#9#95#9#Q !!U*!
d&7&7&9 ::%9D<L<LL-- # #%* 	C J0@AB!.0I0I  xx++)-	 , 
 	
r?   c                 P   | j                  d      sJ | j                  }| j                  d      }|j                         st	        d|      | j                         }| j                         }| j                  d       | j                  j                  j                  |      }|P| j                  j                  |      }|| j                  j                  |<   | j                  j                  ||       | j                  j                  ||||      }|j!                  |       |S )NrL   Tr   z*Empty glyph class in mark class definitionrR   rA   )r]   r\   r   glyphSetr   r   expect_class_name_r}   r*   markClassesgetr(   r   r-   r   MarkClassDefinitionaddDefinition)r8   rB   r   ru   ro   rL   mcdefs          r   re   zParser.parse_markClass_  s   ##K000++'''> !<h  ##%&&(C II))--d3	**40I*3DII!!$'%%dI6,,vv - 
 	&r?   c                 F   | j                   dv sJ | j                  dk(  r| j                  ||      S | j                  dk(  r| j                  ||      S | j                  dk(  r| j	                  ||      S | j                  dk(  r| j                  ||      S | j                  }| j                  |      \  }}}}}}	| j                  d       t        |      r7t        |      rt        d|      | j                  j                  |||||      S |sT|sRt        |      d	k(  rD|	sB|d
   |j                          | j                  j                  |d
   |d
   |d   |d   ||      S |rt        d|      | j                  j!                  t#        t%        ||            |||	|      S )N>   r   r   cursivebaseligaturer   rR   z3If "lookup" is present, no values must be specifiedrA   r$  r   r   )r   rB   z2"enumerate" is only allowed with pair positionings
forceChainrB   )r[   r2   parse_position_cursive_parse_position_base_parse_position_ligature_parse_position_mark_r\   r   r}   r   r   r(   ChainContextPosStatementr$   reversePairPosStatementSinglePosStatementlistzip)
r8   r   rK   rB   r   r   r   r   r   r   s
             r   r   zParser.parse_position_  s   "5555y(//
HEE',,ZBB+00XFF',,ZBB++<@<U<U=
9 	C w<6{%I8  8844( 5   fV)9(ay  88,,q	q	q	q	%! -   !Dh  xx**VV$% + 
 	
r?   c                    | j                   }| j                  d       |rt        d|      | j                  d      }| j	                         }| j	                         }| j                  d       | j                  j                  ||||      S )Nr?  z>"enumerate" is not allowed with cursive attachment positioningTr   rR   rA   )r\   r~   r   r   r   r}   r(   CursivePosStatement)r8   r   rK   rB   r   entryAnchor
exitAnchors          r   rD  zParser.parse_position_cursive_   s    ++Y'!S  ++T+B
((*'')
C xx++Z( , 
 	
r?   c                     | j                   }| j                  d       |rt        d|      | j                  d      }| j	                         }| j                  d       | j                  j                  |||      S )Nr@  zC"enumerate" is not allowed with mark-to-base attachment positioningTr   rR   rA   )r\   r~   r   r   r   r}   r(   MarkBasePosStatement)r8   r   rK   rB   r@  markss         r   rE  zParser.parse_position_base_  s    ++V$!6 
 %%t%<((*C xx,,T58,LLr?   c                    | j                   }| j                  d       |rt        d|      | j                  d      }| j	                         g}| j
                  dk(  r@| j                  d       |j                  | j	                                | j
                  dk(  r@| j                  d       | j                  j                  |||      S )NrA  zG"enumerate" is not allowed with mark-to-ligature attachment positioningTr   ligComponentrR   rA   )
r\   r~   r   r   r   r2   rY   r}   r(   MarkLigPosStatement)r8   r   rK   rB   	ligaturesrT  s         r   rF  zParser.parse_position_ligature_  s    ++Z(!: 
 **D*A	))+,.0  0LL1134 .0 	C xx++Iux+PPr?   c                     | j                   }| j                  d       |rt        d|      | j                  d      }| j	                         }| j                  d       | j                  j                  |||      S )Nr   zC"enumerate" is not allowed with mark-to-mark attachment positioningTr   rR   rA   )r\   r~   r   r   r   r}   r(   MarkMarkPosStatement)r8   r   rK   rB   	baseMarksrT  s         r   rG  zParser.parse_position_mark_/  s    ++V$!6 
 **D*A	((*C xx,,Y,QQr?   c                     | j                  d      sJ | j                  | j                         }}| j                  d       | j                  j                  ||      S )NscriptrR   rA   )r]   r\   expect_script_tag_r}   r(   ScriptStatement)r8   rB   r]  s      r   parse_script_zParser.parse_script_=  sV    ##H---33T5L5L5N&C xx'''BBr?   c           
          | j                   dv sJ | j                  }| j                   dv }| j                  d      \  }}}}}}t        |      rt	        d|      g }	| j
                  dk(  rU| j                  d      }
| j
                  dk7  rk| j                  dd	      }|	j                  |       | j
                  dk7  r4n6| j
                  d
k(  r%| j                  d
      }
| j                  d      g}	nd }
| j                  d       t        |	      dk(  r!t        |      st	        d| j                        |
d
k(  r|rt	        d|      t        |      dk7  st        |d   j                               dk7  rt	        d|      t        |	      dk7  rt	        d|      | j                  j                  ||d   ||	d   |      S t        |D cg c]  }||	 c}      }d}t        |	      dk(  r!t        |	d   t        j                        rg }	d}|st        |      dk(  rt        |	      dk(  r|dk(  rt!        |d   j                               }t!        |	d   j                               }t        |      dk(  r|t        |      z  }t        |      t        |      k7  r#t	        dt        |      t        |      fz  |      | j                  j#                  ||	||||      S |r7t        |      dk(  r)|dk(  r$| j                  j%                  ||d   |d||      S |st        |      dk(  rt        |	      dkD  r|dk(  rt        |d   j                               }|	D ]  }t!        |j                               st	        d|      t        |j                               dk7  sEt        |j                               |k7  sbt	        d| dt        |j                                d|       | j                  j%                  ||d   ||	||      S |s~t        |      dkD  rpt        |	      dk(  rbt        |	d   j                               dk(  rC|dk(  r>| j                  j'                  |||t!        |	d   j                               d   ||      S |rt        |      dk7  rt	        d|      t        |	      dk7  rt	        d|      |dk7  rt	        d|      t)        t!        |d   j                                     }t)        t!        |	d   j                                     }t        |      dk(  r|t        |      z  }t        |      t        |      k7  r#t	        dt        |      t        |      fz  |      | j                  j+                  ||||	|      S t        |      dkD  rt        |	      dkD  rt	        d|      t        |	      dk7  s|rt	        d|      | j                  j-                  |||||      }|S c c}w )N>   r   rsub
reversesubr   >   rb  rc  FrJ   z-Substitution statements cannot contain valuesr   rR   T)r   r   r   r   r   z3Expected "by", "from" or explicit lookup referencesz4Reverse chaining substitutions do not support "from"r   z%Expected a single glyph before "from"z)Expected a single glyphclass after "from"rA   z\Expected a glyph class with %d elements after "by", but found a glyph class with %d elementsrB   zEmpty class in replacementz!Expected a glyph class with 1 or z3 elements after "by", but found a glyph class with z	 elementsz\In reverse chaining single substitutions, only a single glyph or glyph class can be replacedzlIn reverse chaining single substitutions, the replacement (after "by") must be a single glyph or glyph classz8Reverse chaining substitutions cannot call named lookupszJDirect substitution of multiple glyphs by multiple glyphs is not supportedzInvalid substitution statement)r[   r\   r   r   r   r2   r~   r   rY   r}   r$   r7  r(   AlternateSubstStatementr   r   rL  SingleSubstStatementMultipleSubstStatementLigatureSubstStatementsorted ReverseChainSingleSubstStatementChainContextSubstStatement)r8   rB   rI  
old_prefixoldr   r   
old_suffixr   newkeywordr   r   num_lookupsis_deletionr   replacementscountnrules                       r   parse_substitute_zParser.parse_substitute_C  sM   "MMMM++//%;; %%u%5	
v;!?  t#**40G""c)++Tt+T

2 ""c) '**62G))5)ABCGC s8q=W!E((  f%JH  3x1}CFOO$5 6! ;%&MxXX3x1}%?  8833CFJA 4   g?1?@s8q=ZA>CK 3s8q=SX]{a?O#a&//+,FA 12L< A%+c&k96{c,//%?6{C$567 	  8800S*jXPX 1   3s8q=[A-=8822A#! 3    3s8q=SX\kQ>NA)*E AJJL))*FQQqzz|$)c!**,.?5.H);E7 C88;AJJL8I7J)U  	 8822A#! 3   C1CACFOO%&!+q 8822SV__&'*#! 3   3x1}%I 
 3x1}%% 	  a%NPX  DQ!234F!$s1v'8"9:L< A%+c&k96{c,//%?6{C$567 	  88<<JS8 =   s8a<CHqL!#  s8q=K!"BHMM xx22Z8 3 
 K @s   W;W;c                     | j                  d      sJ | j                  }| j                  d       | j                  j	                  |      S )NsubtablerR   rA   )r]   r\   r}   r(   SubtableStatement)r8   rB   s     r   parse_subtable_zParser.parse_subtable_  sG    ##J///++C xx))8)<<r?   c                    | j                  d      sJ | j                  }| j                         }| j                         }d}d}| j                  t
        j                  t
        j                  fv s|dk7  r | j                         }| j                         }| j                  d       | j                  j                  |||||      S )N
parametersg        r   rR   rA   )r]   r\   expect_decipoint_r   r1   r   r/  FLOATr}   r(   SizeParameters)r8   rB   
DesignSizeSubfamilyID
RangeStartRangeEnds         r   parse_size_parameters_zParser.parse_size_parameters_  s     ##L111++++-
))+
  U\\5;;$??;RSCS//1J--/HC xx&&ZH ' 
 	
r?   c                     | j                  d      sJ | j                  }| j                         \  }}}}| j                  j	                  d|||||      S )NsizemenunamesizerA   )r]   r\   parse_name_r(   FeatureNameStatement)r8   rB   
platformID	platEncIDlangIDstrings         r   parse_size_menuname_zParser.parse_size_menuname_  sa    ##N333++040@0@0B-
Ivvxx,,J	66H - 
 	
r?   c           	         | j                  d      sJ | j                  | j                         }}| j                  j	                  ||      }| j                  d       | j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                  dj                  |      }|r	 ||       nt        d|j!                         z  |      | j                  d       | j                         }||k7  r't        d|j!                         z  | j                        | j                  d       |S )	NrP   rA   {)GDEFheadhheavhearo   BASEzOS/2STATz"table %s" is not supportedr   Expected "%s"rR   )r]   r\   r   r(   
TableBlockr}   parse_table_GDEF_parse_table_head_parse_table_hhea_parse_table_vhea_parse_table_name_parse_table_BASE_parse_table_OS_2_parse_table_STAT_r:  r   strip)r8   rB   ro   rP   handlerr   s         r   rh   zParser.parse_table_  s8   ##G,,,1143C3C3E$##D8#<C ****************	
 #d) 	 EN!-

<h  	C ""$d?!$**,.0H0H  	C r?   c                 H   |j                   }| j                  dk7  s| j                  rz| j                  d       | j                  t
        j                  u rA|j                  | j                  j                  | j                  | j                               n| j                  d      r |j                  | j                                n| j                  d      r |j                  | j                                n| j                  d      r |j                  | j                                nX| j                  d      r |j                  | j!                                n'| j                  d	k(  r`t#        d
| j                        | j                  dk7  rk| j                  ryy y )Nr   Tr   rA   r   r   r  r  rR   z<Expected Attach, LigatureCaretByIndex, or LigatureCaretByPos)rV   r2   r3   r7   rW   r   rX   rY   r(   rZ   r[   r\   r]   r   r   r  r  r   r8   rP   rV   s      r   r  zParser.parse_table_GDEF_;  sM   %%
#%););.##u}}4!!HH$$T__t?W?W$X %%h/!!$"4"4"67%%o6!!$";";"=>%%&<=!!$"B"B"DE%%&:;!!$"@"@"BCC'%U,, # #%););r?   c                    |j                   }| j                  dk7  s| j                  r| j                  d       | j                  t
        j                  u rA|j                  | j                  j                  | j                  | j                               nW| j                  d      r |j                  | j                                n&| j                  dk(  rt        d| j                        | j                  dk7  r| j                  ry y )Nr   Tr   rA   FontRevisionrR   zExpected FontRevision)rV   r2   r3   r7   rW   r   rX   rY   r(   rZ   r[   r\   r]   parse_FontRevision_r   r  s      r   r  zParser.parse_table_head_S  s    %%
#%););.##u}}4!!HH$$T__t?W?W$X %%n5!!$":":"<=C'%&=t?W?WXX #%););r?   c                 $   |j                   }d}| j                  dk7  s| j                  rf| j                  d       | j                  t
        j                  u rA|j                  | j                  j                  | j                  | j                               n| j                  t
        j                  u r| j                  |v r| j                  j                         }| j                         }|j                  | j                  j                  ||| j                               | j                  dk7  r=t!        d| j"                        | j                  dk(  rLt!        d| j                        | j                  dk7  rW| j                  rey y )	N)CaretOffsetAscender	DescenderLineGapr   Tr   rA   rR   Incomplete statementz4Expected CaretOffset, Ascender, Descender or LineGap)rV   r2   r3   r7   rW   r   rX   rY   r(   rZ   r[   r\   rj   lowerr   	HheaFieldr   r4   r8   rP   rV   fieldskeyr1  s         r   r  zParser.parse_table_hhea_b  sP   %%
D#%););.##u}}4!!HH$$T__t?W?W$X %%368Qoo++-++-!!HH&&sED<T<T&U ##s*).0I0I  C'%M,, ' #%););r?   c                 $   |j                   }d}| j                  dk7  s| j                  rf| j                  d       | j                  t
        j                  u rA|j                  | j                  j                  | j                  | j                               n| j                  t
        j                  u r| j                  |v r| j                  j                         }| j                         }|j                  | j                  j                  ||| j                               | j                  dk7  r=t!        d| j"                        | j                  dk(  rLt!        d| j                        | j                  dk7  rW| j                  rey y )	N)VertTypoAscenderVertTypoDescenderVertTypoLineGapr   Tr   rA   rR   r  z?Expected VertTypoAscender, VertTypoDescender or VertTypoLineGap)rV   r2   r3   r7   rW   r   rX   rY   r(   rZ   r[   r\   rj   r  r   	VheaFieldr   r4   r  s         r   r  zParser.parse_table_vhea_}  sR   %%
M#%););.##u}}4!!HH$$T__t?W?W$X %%368Qoo++-++-!!HH&&sED<T<T&U ##s*).0I0I  C'%;,, ' #%););r?   c                 "   |j                   }| j                  dk7  s| j                  r| j                  d       | j                  t
        j                  u rA|j                  | j                  j                  | j                  | j                               n[| j                  d      r$| j                         }|r8|j                  |       n&| j                  dk(  rt        d| j                        | j                  dk7  r| j                  ry y )Nr   Tr   rA   nameidrR   zExpected nameid)rV   r2   r3   r7   rW   r   rX   rY   r(   rZ   r[   r\   r]   parse_nameid_r   )r8   rP   rV   	statements       r   r  zParser.parse_table_name_  s    %%
#%););.##u}}4!!HH$$T__t?W?W$X %%h/ ..0	%%i0C'%&79Q9QRR #%););r?   c                    d}d}| j                   t        j                  v ri| j                         }| j                  }|dvrt        d|      | j                   t        j                  v r/| j                         }| j                         }nd}| j                  }|dk(  r|xs d}|xs d}n|xs d}|xs d}| j                         }| j                  d       t        |||      }|t        d	|      | j                  ||      }||||fS )
z~Parses a name record. See `section 9.e <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#9.e>`_.Nr      Expected platform id 1 or 3r  r   r   	  rR   Unsupported encoding)
r1   r   NUMBERSexpect_any_number_r\   r   expect_string_r}   r   unescape_string_r8   r  r  r  rB   r  encoding	unescapeds           r   r  zParser.parse_name_  s   	  EMM1002J//H'%&CXNN$$5 335	002J//H?!QI[qF!QI%vF$$&C z9f=!"8(CC))&(;	9fi77r?   c                    d }d }| j                   t        j                  v ri| j                         }| j                  }|dvrt        d|      | j                   t        j                  v r/| j                         }| j                         }nd}| j                  }|dk(  r|xs d}|xs d}n|xs d}|xs d}| j                         }t        |||      }|t        d|      | j                  ||      }||||fS )Nr  r  r  r   r   r  r  )	r1   r   r  r  r\   r   r  r   r  r  s           r   parse_stat_name_zParser.parse_stat_name_  s   	  EMM1002J//H'%&CXNN$$5 335	002J//H?!QI[qF!QI%vF$$&z9f=!"8(CC))&(;	9fi77r?   c                    | j                   dk(  sJ | j                          | j                  | j                         }}|dkD  rt        d| j                        | j	                         \  }}}}| j
                  j                  ||||||      S )Nr  i  z*Name id value cannot be greater than 32767rA   )r[   r\   r  r   r  r(   
NameRecord)r8   rB   nameIDr  r  r  r  s          r   r  zParser.parse_nameid_  s    (*;DOO;*33T5L5L5N&E>!<d>V>V  150@0@0B-
Ivvxx""J	66H # 
 	
r?   c                      dk(  r"t        j                  d j                  |      }n fd}t        j                  d||      }t        |dd      }t	        |d      S )N	utf_16_bez\\[0-9a-fA-F]{4}c                 (    j                  |       S r   )unescape_byte_)mr  r8   s    r   <lambda>z)Parser.unescape_string_.<locals>.<lambda>  s    !4!4Q!A r?   z\\[0-9a-fA-F]{2}surrogatepass)rer   unescape_unichr_r
   r   )r8   r  r  r   unescapeutf16s   ` `   r   r  zParser.unescape_string_  sY    {"*D,A,A6JAAH*Hf=A ;8UK((r?   c                 T    | j                  d      dd  }t        t        |d            S Nr   r      )groupchrint)matchru  s     r   r  zParser.unescape_unichr_  s&    KKN123q":r?   c                 r    | j                  d      dd  }t        t        |d            j                  |      S r  )r  r	   r  decode)r  r  ru  s      r   r  zParser.unescape_byte_  s2    KKN12s1bz"))(33r?   c                    |j                   }| j                  dk7  s| j                  r| j                  d       | j                  t
        j                  u rB|j                  | j                  j                  | j                  | j                               n| j                  d      r| j                         }n| j                  d      rS| j                  t                    }|j                  | j                  j!                  ||d| j                               n| j                  d      r| j                         }nu| j                  d	      rS| j                  t                    }|j                  | j                  j!                  ||d| j                               n| j                  d
k(  r| j                  dk7  r| j                  ry y )Nr   Tr   rA   HorizAxis.BaseTagListHorizAxis.BaseScriptListFVertAxis.BaseTagListVertAxis.BaseScriptListrR   )rV   r2   r3   r7   rW   r   rX   rY   r(   rZ   r[   r\   r]   parse_base_tag_list_parse_base_script_list_r$   BaseAxis)r8   rP   rV   horiz_baseshoriz_scripts
vert_basesvert_scriptss          r   r  zParser.parse_table_BASE_	  s   %%
#%););.##u}}4!!HH$$T__t?W?W$X %%&=>"779%%&@A $ < <S=M N!!HH%%#%!%!9!9	 &  %%&<=!668
%%&?@#;;C
OL!!HH%%"$!%!9!9	 &  C'? #%););r?   c                 $   |j                   }d}d}| j                  dk7  s| j                  r| j                  d       | j                  t
        j                  u rB|j                  | j                  j                  | j                  | j                               nT| j                  t
        j                  u r&| j                  j                         }d }| j                  |v r| j                         }n| j                  d      r2g }t!        d      D ]!  }|j                  | j                                # np| j                  |v rAg }| j                  d	k7  rQ|j                  | j                                | j                  d	k7  r/n!| j                  d
      r| j#                         }|j                  | j                  j%                  ||| j                               n| j                  d	k(  r| j                  dk7  r| j                  ry y )N)FSTypeTypoAscenderTypoDescenderTypoLineGap	winAscent
winDescentXHeight	CapHeightWeightClass
WidthClassLowerOpSizeUpperOpSize)UnicodeRangeCodePageRanger   Tr   rA   Panose
   rR   Vendor)rV   r2   r3   r7   rW   r   rX   rY   r(   rZ   r[   r\   rj   r  r   r]   r   r  OS2Field)r8   rP   rV   numbersr   r  r1  r   s           r   r  zParser.parse_table_OS_2_,  s   %%

 3#%););.##u}}4!!HH$$T__t?W?W$X %%3oo++-??g- //1E))(3E"2Y <T%8%8%:;<__.E**c1T%8%8%:; **c1))(3 //1E!!HH%%c54;S;S%T C'3 #%););r?   c                 `   | j                  d      sJ | j                  d       g }| j                  dk7  s| j                  r| j	                          | j                  d      rR| j                         \  }}}}| j                  j                  d||||| j                        }|j                  |       n3| j                  dk7  r$t        d| j                   d	| j                        | j                  dk7  r| j                  r| j                  d       |st        d
| j                        |S )NElidedFallbackNamer  r   ro   statrA   rR   Unexpected token z in ElidedFallbackNameExpected "name")r]   r}   r2   r3   r7   r  r(   STATNameStatementr\   rY   r[   r   )r8   namesr  r  r  r  
nameRecords          r   parse_STAT_ElidedFallbackNamez$Parser.parse_STAT_ElidedFallbackNameX  s(   ##$8999C #%););!##F+8<8M8M8O5
Ivv!XX77!55 8 
 Z(??c))+DOO+<<VW00  #%););& 	C !"3T5M5MNNr?   c                 T   | j                  d      sJ g }| j                         }|dvr)|j                         st        j	                  d| d       | j                         }| j                  d       | j                  dk7  s| j                  r| j                          | j                  t        j                  u rH| j                  d      rT| j                  }| j                         \  }}}}| j                  j!                  d|||||	      }	|j#                  |	       n3| j$                  d
k(  rt'        d| j$                   | j                        | j                  dk7  r| j                  r| j                  d       | j                  j)                  |||| j                        S )N
DesignAxis)italopszslntwdthwghtzUnregistered axis tag z should be uppercase.r  r   ro   r  rA   rR   zExpected "name", got )r]   r   isupperr   r   r   r}   r2   r3   r7   rW   r   rX   r\   r  r(   r  rY   r[   r   STATDesignAxisStatement)
r8   r	  axisTag	axisOrderrB   r  r  r  r  ro   s
             r   parse_STAT_design_axiszParser.parse_STAT_design_axist  s   ##L111""$CCOO%KK0	9NOP'')	C #%););!##u}}4%%f-338<8M8M8O5
Ivvxx11J	66H 2  T"C'%+DOO+<=t?W?W  #%););$ 	C xx//Yt'?'?
 	
r?   c                    | j                  d      sJ | j                  d       g }g }d}| j                  dk7  s| j                  r=| j	                  d       | j
                  t        j                  u rK| j                  d      rT| j                  }| j                         \  }}}}| j                  j                  d|||||	      }	|j                  |	       n| j                  d
      r"| j                         }|j                  |       nW| j                  d      r| j                         }n5| j                  dk(  rt!        d| j                   d| j                        | j                  dk7  r/| j                  r=| j                  d       |st!        d| j                        |st!        d| j                        t#        |      dkD  r|D ]G  }t#        |j$                        dkD  st!        dt#        |j$                         d| j                         g }
|D ]=  }|j&                  }||
v rt!        d| d| j                        |
j                  |       ? | j                  j)                  |||| j                        S )N	AxisValuer  r   r   Tr   ro   r  rA   rB   flagrR   r  z in AxisValuezExpected "Axis Name"zExpected "Axis location"r   z?Only one value is allowed in a Format 4 Axis Value Record, but z were found.	Axis tag z already defined.)r]   r}   r2   r3   r7   rW   r   rX   r\   r  r(   r  rY   parse_STAT_locationexpect_stat_flagsr[   r   r$   r   r   STATAxisValueStatement)r8   	locationsr	  r3  rB   r  r  r  r  ro   format4_tagsr   s               r   parse_STAT_axis_value_zParser.parse_STAT_axis_value_  s   ##K000C 	#%););.##u}}4%%f-338<8M8M8O5
Ivvxx11J	66H 2  T"%%j1335  *%%f-..0C'%''88IJ,, ' #%););. 	C !"8$:R:RSS!"<d>V>VWWy>A% x'!+);x/0> 00	  L% )ll,&)#C5(==t?W?W  ##C() xx..9eT%=%=
 	
r?   c           	         g }| j                         }t        |j                               dk7  r$t        d| j                   d| j
                        | j                  dk7  r| j                  t        j                  u r"| j                         }|j                  |       nb| j                  t        j                  u r"| j                         }|j                  |       n$t        d| j                   d| j                        | j                  dk7  rt        |      dk(  r0|\  }}}||k  s||kD  r t        d| d	| d
| d| j                        | j                  j!                  ||      S )Nr%  r  z must be 4 charactersrR   zUnexpected value "z". Expected integer or float.r  zDefault value z is outside of specified range r   .)r   r$   r  r   r[   r\   r2   r1   r   r  expect_float_rY   r/  r   r4   r(   AxisValueLocationStatement)r8   r   r   r1  nominalmin_valmax_vals          r   r  zParser.parse_STAT_location  sn    syy{q !DOO,,EE(( 
 #%$$3**,e$&&%,,6++-e$%()9)9(: ;1 1--  #% v;!(.%GWg Gg$5%$WI .*iq	, --	  xx223??r?   c                 <   |j                   }g }| j                  dk7  s| j                  rr| j                  d       | j                  t
        j                  u rB|j                  | j                  j                  | j                  | j                               n| j                  t
        j                  u r| j                  d      r<| j                         }|j                  | j                  j                  |             nx| j                  d      rM| j!                         }|j                  | j                  j#                  |             | j%                  d       n| j                  d      rN| j'                         }|j                  |j(                         |j                  |       | j%                  d       n| j                  d	      rv| j+                         }|j,                  D ]4  }|j(                  |vst/        d
|j(                   d| j                         |j                  |       | j%                  d       n4t/        d| j                   | j                        | j                  dk(  rn| j                  dk7  rc| j                  rqy y )Nr   Tr   rA   r  ElidedFallbackNameIDrR   r  r  zDesignAxis not defined for r#  r  )rV   r2   r3   r7   rW   r   rX   rY   r(   rZ   r[   r\   rj   r]   r  r  r   r*  r}   r  r   r!  r  r   )	r8   rP   rV   design_axesr	  r1  
designAxisaxisValueRecordrB   s	            r   r  zParser.parse_table_STAT_  s+   %%
#%););.##u}}4!!HH$$T__t?W?W$X %%3''(<= >>@E%%dhh&A&A%&HI))*@A //1E%%dhh&C&CE&JK'',)),7!%!<!<!>J&&z~~6%%j1'',))+6&*&A&A&CO$3$=$= #<<{: #2 =a P $ 8 8# 	 %%o6'',)+DOO+<=t?W?W  C'I #%););r?   c                     | j                   dv sJ | j                          g }| j                  dk7  r/|j                  | j                                | j                  dk7  r/| j	                  d       |S )N)r  r  rR   )r[   r2   rY   r^  r}   )r8   basess     r   r  zParser.parse_base_tag_list_  sx     #
 
 	 ??	 
 #%LL0023 #%C r?   c                 *   | j                   dv sJ | j                          | j                  |      g}| j                  dk(  rA| j                  d       |j	                  | j                  |             | j                  dk(  rA| j                  d       |S )N)r  r  r   rR   )r[   parse_base_script_record_r2   r}   rY   )r8   rt  scriptss      r   r  zParser.parse_base_script_list_$  s     #
 
 	 ??	 
 2259;#%$NN499%@A #% 	C r?   c                     | j                         }| j                         }t        |      D cg c]  }| j                          }}|||fS c c}w r   )r^  r   r   )r8   rt  
script_tagbase_tagr   coordss         r   r1  z Parser.parse_base_script_record_0  sP    ,,.
**,16u>A$%%'>>8V++ ?s   Ac                    d }| j                  d       | j                  d       | j                  dk(  r| j                  d       n| j                         | j                         fg}| j                  dk(  rP| j                  d       |j	                  | j                         | j                         f       | j                  dk(  rPt        |      }| j                  d       |S )Nrt   devicerv   r   rw   )r}   r~   r2   r   rY   tuple)r8   results     r   r   zParser.parse_device_6  s    C X&v%  (**,d.A.A.CDEF""c)##C(t224d6I6I6KLM ""c) 6]FC r?   c                 ~    | j                   t        j                  u xs  | j                  dk(  xs | j                  dk(  S )Nrt   ()r1   r   r/  r2   r8   s    r   r   zParser.is_next_value_E  s?    !!U\\1 '3&'3&	
r?   c                    | j                   t        j                  u r| j                  dk(  s| j                   t        j                  u r`| j                  d      | j                  }}|r | j                  j                  |||      }|S | j                  j                  |||      }|S | j                  d       | j                  }| j                   t        j                  u r| j                         }|dk(  r+| j                  d       | j                  j                         S | j                  j                  |      }|t        d	|z  | j                        |j                  }|j                   |j"                  }	}|j$                  |j&                  }}
nK| j                  d      | j                  d      | j                  d      | j                  d      f\  }}	}
}| j                  dk(  r| j)                         | j)                         | j)                         | j)                         f\  }}}}t+        |r|nd
|r|nd
z   |r|nd
z   |r|nd
z   D cg c]  \  }}|	 c}}      }|d   dk  s|d   dkD  rt        d| j                        d\  }}}}| j                  d       | j                  j                  ||	|
|||||||
      S c c}}w )Nr<  Tr{   )yAdvancerK   rB   )xAdvancerK   rB   rt   rv   rw   zUnknown valueRecordDef "%s"rd  r   ir      z+Device value out of valid range (-128..127))NNNN)rK   rB   )r1   r   rl   r2   r/  r   r\   r(   ValueRecordr}   rj   r   r/   r   r   r1  
xPlacement
yPlacementr@  r?  r   ri  )r8   rK   numberrB   valro   vrdr1  rC  rD  r@  r?  
xPlaDevice
yPlaDevice
xAdvDevice
yAdvDevicer  delta	allDeltass                      r   r   zParser.parse_valuerecord_L  s   !!U\\1d6F6F#6M""ell2##T#2(( F hh**#h +  J hh**#h +  JC ++  EJJ.$$&Dv~##C(xx++--$$,,T2C{%1D8$:R:R  IIE&+&6&68H8H
J"'..%..hH ##T#2##T#2##T#2##T#2	:6J
Hh s"""$""$""$""$	>:J
J
  7A
b%/zR(9%/zR(9 &0zR(9#e I |d"imc&9%A,, 
 >V:J
J
C xx## $ 
 	
#s   K
c                    | j                  d      sJ | j                  }| j                  |      }| j                         }| j	                  d       | j
                  j                  |||      }| j                  j                  ||       |S )NrQ   rR   rA   )	r]   r\   r   r   r}   r(   ValueRecordDefinitionr/   r   )r8   rK   rB   r1  ro   rG  s         r   ri   z$Parser.parse_valuerecord_definition_  s    ##$4555++''1  "C hh,,T58,L!!$,
r?   c                     | j                   dk(  sJ | j                  }| j                         }| j                         }| j	                  d       | j
                  j                  |||      S )NrH   rR   rA   )r[   r\   r^  r  r}   r(   LanguageSystemStatement)r8   rB   r]  r	  s       r   rc   zParser.parse_languagesystem_  sf    "2222++((*,,.C xx//8/TTr?   c                    |r| j                   dk(  sJ | j                   dk(  sJ | j                  }| j                         }|dv }d }d }d}|| j                  v r|}n|| j                  v r|}n|dk(  rd}|r| j                         }d}	| j                  dk(  r| j                  d       d}	|r | j                  j                  ||	|      }
n| j                  j                  ||	|      }
| j                  |
||||       |
S )	NrO   rM   >   valtvhalvkrnvpalFr  Tr  )r   rB   )r[   r\   r   SS_FEATURE_TAGSCV_FEATURE_TAGSr   r2   r~   r(   VariationBlockFeatureBlockr  )r8   rO   rB   r   rK   stylisticset
cv_featuresize_featurerN   r   r!  s              r   rf   zParser.parse_feature_block_  s)   ??k111??i///++ ::
$&&&LD(((JF]L,,.L~-  0 MHH++\ , E HH))=8 * E 	%<zRr?   c                     | j                   dk(  sJ | j                          | j                  }| j                         }| j                  d       | j                  j                  ||      S )NrM   rR   rA   )r[   r\   r   r}   r(   FeatureReferenceStatement)r8   rB   featureNames      r   parse_feature_reference_zParser.parse_feature_reference_  s^    )+<T__<+++&&(C xx11+1QQr?   c           
      $   | j                   dk(  sJ | j                          | j                  j                  || j                   | j                        }| j	                  d       | j
                  D ]  }|j                           | j                  dk7  s| j                  r,| j                  d       | j                  t        j                  u rK|j                  j                  | j                  j                  | j                   | j                               n| j!                  d      r\| j                  }| j#                         \  }}}}|j                  j                  | j                  j%                  ||||||             n'| j                   dk(  rt'        d	| j                        | j                  dk7  r| j                  r,| j	                  d       | j
                  D ]  }|j)                           | j	                  d       |S )
zParses a ``featureNames`` statement found in stylistic set features.
        See section `8.c <https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#8.c>`_.
        featureNamesrA   r  r   Tr   ro   rR   r  )r[   r(   NestedBlockr\   r}   r0   enter_scoper2   r3   r7   rW   r   rX   rV   rY   rZ   r]   r  r  r   
exit_scope)	r8   r   r!  symtabrB   r  r  r  r  s	            r   parse_featureNames_zParser.parse_featureNames_  s    .0A$//A0$$4+C+C % 
 	C )) 	!F 	!#%););.##u}}4  ''HH$$T__t?W?W$X %%f-338<8H8H8J5
Ivv  ''HH11ZFFX 2 
 C'%&79Q9QRR# #%););$ 	C )) 	 F	 C r?   c                 x   | j                   dk(  sJ | j                          | j                  j                  || j                   | j                        }| j	                  d       | j
                  D ]  }|j                           |j                  }| j                  dk7  s| j                  rJ| j                  d       | j                  t        j                  u rA|j                  | j                  j                  | j                   | j                               n| j!                  h d      r,|j                  | j#                  || j                                n}| j!                  d      r!|j                  | j%                  |             nK| j                   d	k(  rt'        d
j)                  | j                  | j                         | j                        | j                  dk7  r<| j                  rJ| j	                  d       | j
                  D ]  }|j+                           | j	                  d	       |S )NcvParametersrA   r  r   Tr   >   SampleTextNameIDFeatUILabelNameIDParamUILabelNameIDFeatUITooltipTextNameID	CharacterrR   zExpected statement: got {} {})r[   r(   rd  r\   r}   r0   re  rV   r2   r3   r7   rW   r   rX   rY   rZ   r]   parse_cvNameIDs_parse_cvCharacter_r   rm   rf  )r8   r   r!  rg  rV   s        r   parse_cvParameters_zParser.parse_cvParameters_  s    .0A$//A0$$4+C+C % 
 	C )) 	!F 	! %%
#%););.##u}}4!!HH$$T__t?W?W$X %% !!$"7"7T__"MN%%k2!!$"9"9#">?C'%3::,,doo ,,	 ) #%););6 	C )) 	 F	 C r?   c                    | j                   |k(  sJ | j                          | j                  j                  ||| j                        }| j	                  d       | j
                  D ]  }|j                           | j                  dk7  s| j                  r-| j                  d       | j                  t        j                  u rK|j                  j                  | j                  j                  | j                   | j                               n| j!                  d      r]| j                  }| j#                         \  }}}}	|j                  j                  | j                  j%                  |||||	||             n'| j                   dk(  rt'        d| j                        | j                  dk7  r| j                  r-| j	                  d       | j
                  D ]  }|j)                           | j	                  d       |S )	NrA   r  r   Tr   ro   rR   r  )r[   r(   rd  r\   r}   r0   re  r2   r3   r7   rW   r   rX   rV   rY   rZ   r]   r  CVParametersNameStatementr   rf  )
r8   r   
block_namer!  rg  rB   r  r  r  r  s
             r   rp  zParser.parse_cvNameIDs_*  s   *,=doo=,$$S*t?W?W$XC )) 	!F 	!#%););.##u}}4  ''HH$$T__t?W?W$X %%f-338<8H8H8J5
Ivv  ''HH66"!"!) 7 
 C'%&79Q9QRR/ #%););0 	C )) 	 F	 C r?   c                 *   | j                   dk(  sJ | j                          | j                  | j                         }}| j                  d       d|cxk\  rdk\  sn t	        dj                  dd      |      | j                  j                  |||      S )Nro  rR   i r   z/Character value must be between {:#x} and {:#x}rA   )r[   r\   r  r}   r   rm   r(   CharacterStatement)r8   r   rB   	characters       r   rq  zParser.parse_cvCharacter_N  s    +->t>-"668O8O8Q)C I**!""(&H"5 
 xx**9cH*MMr?   c                     | j                   dk(  sJ | j                          | j                  | j                         }}| j                  d       |dk  rt	        d|      | j
                  j                  ||      S )Nr  rR   r   z&Font revision numbers must be positiverA   )r[   r\   r$  r}   r   r(   FontRevisionStatement)r8   rB   versions      r   r  zParser.parse_FontRevision_Z  st     .0A$//A0 44d6H6H6J'C a<!"JHUUxx--g-IIr?   c                    | j                         }i }| j                  d       | j                  dk7  rJ| j                          | j                  t
        j                  urt        d| j                        | j                  }||v rt        d| | j                        | j                  t
        j                  u r| j                         }n.| j                  t
        j                  u r| j                  d      }| j                  t
        j                  u r| j                         }n.| j                  t
        j                  u r| j                  d      }| j                  d       f||<   | j                  dk7  rJ| j                  d       | j                         }||k7  rt        d|z  | j                        | j                  j!                  ||      S )	Nr  r   Expected an axis namezRepeated condition for axis Fr{   rR   r  )r   r}   r2   r7   rW   r   rj   r   r\   r[   r1   r  r$  r/  r   r(   ConditionsetStatement)r8   ro   
conditionsaxis	min_value	max_value	finalnames          r   rg   zParser.parse_conditionset_d  s     "
C #%!##5::5%&=t?W?WXX??Dz!%24&94;S;S  $$3 ..0	&&%,,6 ///?	$$3 ..0	&&%,,6 ///?	$ )95Jt- #%0 	C %%'	!/D"8$:R:RSSxx--dJ??r?   c                 <   | j                  d       | j                  D ]  }|j                           |j                  }| j                  dk7  s| j
                  r| j                  d       | j                  t        j                  u rB|j                  | j                  j                  | j                  | j                               nR| j                  t        j                  u r!|j                  | j!                                n| j#                  d      r!|j                  | j%                                n| j#                  ddh      r#|j                  | j'                  |	             n| j#                  d
      r!|j                  | j)                                n{| j#                  d      r!|j                  | j+                                nI| j#                  d      r!|j                  | j-                                n| j#                  d      r"|j                  | j/                  |             n| j#                  d      r!|j                  | j1                                n| j#                  d      r!|j                  | j3                                n| j#                  ddh      r$|j                  | j5                  d|             nI| j#                  d      r!|j                  | j7                                n| j#                  h d      r!|j                  | j9                                n| j#                  d      r!|j                  | j;                                n| j#                  d      r"|j                  | j=                  |             n~|r3| j#                  d      r"|j                  | j?                  |             nI|r3| j#                  d      r"|j                  | jA                  |             n|r1| j#                  d      r |j                  | jC                                n|r1| j#                  d      r |j                  | jE                                n| j                  t        jF                  u rG| j                  | jH                  v r/|j                   | jH                  | j                     |              nK| j                  dk(  rtK        djM                  | j                  | j                        | j                        | j                  dk7  r| j
                  r| j                  d       | j                  D ]  }|jO                           | jQ                         }||jR                  jU                         k7  r1tK        d|jR                  jU                         z  | j                        | j                  d       d}	d}
|D ]  }tW        || j                  jX                        r.t[        |j\                  |j^                  |j`                  g       }	QtW        || j                  jb                        srt[        |j\                  |j^                  |j`                  g       }
 |	r|
rg }|j                  D ]  }tW        || j                  jX                        r|jd                  d   jg                         }|jh                  d   jg                         }tk        |      d k(  r|tk        |      z  }tm        |      D ]a  \  }}|j                  | j                  jc                  |j\                  ||j^                  ||   g|j`                  |jn                               c |j                  |        ||_        y y y )!Nr  r   Tr   rA   rG   r   r   rJ   rM   r   r	  rI   r#  rL   r   r   Fr   r]  >   r   rb  rc  r   ry  rQ   rc  rj  r}  r  rR   z7Expected glyph class definition or statement: got {} {}r  r   r   )8r}   r0   re  rV   r2   r3   r7   rW   r   rX   rY   r(   rZ   r[   r\   r_   r`   r]   rb   r   ra  r  r  rd   r5  re   r   r`  rw  r{  ri   rh  rr  r  r  rj   rk   r   rm   rf  r   ro   r  r   rf  r   r   r   rC  rg  r   r7  rs  r$   r   rB   )r8   r!  rK   r[  r]  r\  rg  rV   ro   
has_singlehas_multipler   r   rs  r   r   s                   r   r  zParser.parse_block_  s3    	C )) 	!F 	! %%
#%););.##u}}4!!HH$$T__t?W?W$X %%)9)99!!$"C"C"EF%%k2!!$"7"7"9:%%v{&;<!!$"7"7"7"JK%%i0!!$"?"?"AB%%h/!!$"4"4"67%%j1!!$"6"6"89%%h/!!$"4"4X">?%%l3!!$"8"8":;%%k2!!$"7"7"9:%%uj&9:!!((EH(M %%h/!!$"4"4"67%%&QR!!$"8"8":;%%j1!!$"6"6"89%%&67!!$"D"DX"NO$"6"6~"F!!$":":<"HI 4 4^ D!!$":"::"FG$"6"6|"D!!$"="="?@$"6"6~"F!!$";";"=>$$

2OOt6!!"B$//$//"B4"HIC'%MTT,,doo ,,	 i #%););v 	C )) 	 F	    "5::##%%!%**"2"2"44d6N6N  	C  
 	KA!TXX::;!$ahh!,,%G!HH
Atxx>>?#&!((ALL'I#JJ		K ,J%% )a!>!>?XXa[113F#$>>!#4#=#=#?L<(A-$F3$-f$5 
5")) HH;; ! % !!-a 1 !)* < 	
 %%a(%)&  *E+ ':r?   c                     | j                   t        j                  u r2t        |t	        d            r| j
                  |k(  S | j
                  |v S y)Nr   F)rW   r   rj   r   typer[   )r8   r   s     r   r]   zParser.is_cur_keyword_  sC    5::-!T"X&!++!++r?   c                     | j                          | j                  t        j                  urt	        d| j
                        | j                  S )NzExpected @NAME)r7   rW   r   r_   r   r\   r[   r=  s    r   r8  zParser.expect_class_name_  s@    u'7'77!"2D4L4LMMr?   c                     | j                          | j                  t        j                  u r| j                  S t        d| j                        )NzExpected a CID)r7   rW   r   r   r[   r   r\   r=  s    r   r   zParser.expect_cid_  s>    599,??".0H0HIIr?   c                     | j                          | j                  t        j                  urt	        d| j
                        | j                  S )NzExpected file name)r7   rW   r   FILENAMEr   r\   r[   r=  s    r   r  zParser.expect_filename_  s>    u~~5!"68P8PQQr?   c                    | j                          | j                  t        j                  u rZ| j                  j                  d      | _        t        | j                        dkD  rt        d| j                        | j                  S | j                  t        j                  u rd| j                  z  S t        d| j                        )N\?   z1Glyph names must not be longer than 63 characterscid%05dzExpected a glyph name or CID)
r7   rW   r   rj   r[   lstripr$   r   r\   r   r=  s    r   r   zParser.expect_glyph_  s    5::-"oo44T:DO4??#b(%G,,  ??"!!UYY.t..<d>V>VWWr?   c                     | j                   r?|D ]9  }|| j                   v r|| j                  vs!| j                  | j                  |<   ; yy)zAdds a glyph name (just `start`) or glyph names of a
        range (`start` and `end`) which are not in the glyph set
        to the "missing list" for future error reporting.

        If no glyph set is present, does nothing.
        N)r'   r6   r\   )r8   r	  ro   s      r   r   z$Parser.check_glyph_name_in_glyph_set%  sT      B4+++t||+)-)A)ADLL&	B r?   c                    | j                         }| j                  j                  |      }|t        d|z  | j                        t        || j                  j                        st        d|z  | j                        |S )NzUnknown markClass @%sz@%s is not a markClass)r8  r-   r   r   r\   r   r(   r   )r8   ro   mcs      r   r   z"Parser.expect_markClass_reference_3  s    &&(''-:!'$.0H0H  "dhh001!(4/1I1I  	r?   c                    | j                          | j                  t        j                  urt	        d| j
                        t        | j                        dkD  rt	        d| j
                        | j                  dz   d d S )NzExpected a tagr%  z'Tags cannot be longer than 4 charactersz    )r7   rW   r   rj   r   r\   r$   r[   r=  s    r   r   zParser.expect_tag_@  su    uzz1!"2D4L4LMMt!#!94;S;S  &("1--r?   c                 \    | j                         }|dk(  rt        d| j                        |S )Ndfltz4"dflt" is not a valid script tag; use "DFLT" insteadr   r   r\   r8   r   s     r   r^  zParser.expect_script_tag_J  s7     &=!F((  
r?   c                 \    | j                         }|dk(  rt        d| j                        |S )NDFLTz6"DFLT" is not a valid language tag; use "dflt" insteadr  r  s     r   r  zParser.expect_language_tag_S  s7     &=!H((  
r?   c                     | j                          | j                  t        j                  u r| j                  |k(  r|S t        d|z  | j                        )NzExpected '%s')r7   rW   r   rl   r[   r   r\   )r8   symbols     r   r}   zParser.expect_symbol_\  sH    5<</DOOv4MMo68P8PQQr?   c                     | j                          | j                  t        j                  u r| j                  |k(  r| j                  S t        d|z  | j                        )Nr  r7   rW   r   rj   r[   r   r\   )r8   rp  s     r   r~   zParser.expect_keyword_b  sM    5::-$//W2L??"o79Q9QRRr?   c                     | j                          | j                  t        j                  u r| j                  S t        d| j                        )NzExpected a namer  r=  s    r   r   zParser.expect_name_h  s>    5::-??"/1I1IJJr?   c                    | j                          | j                  t        j                  u r| j                  S |r;| j                  t        j
                  u r| j                  dk(  r| j                         S t        d| j                        )Nr<  zExpected a number)	r7   rW   r   r/  r[   rl   expect_variable_scalar_r   r\   )r8   r|   s     r   r   zParser.expect_number_n  sm    5<</??",,<TWAW//11143K3KLLr?   c                     | j                          t               }	 | j                  t        j                  k(  r| j
                  dk(  r	 |S | j                         \  }}|j                  ||       U)NrT   )r7   r   rW   r   rl   r[   expect_master_	add_value)r8   scalarrB   r1  s       r   r  zParser.expect_variable_scalar_v  si    !##u||338N  #113OHeXu-	 r?   c                    i }	 | j                   t        j                  urt        d| j                        | j
                  }| j                          | j                   t        j                  u r| j
                  dk(  st        d| j                        | j                         }|||<   | j                  t        j                  u r| j                  d   dk(  rnc| j                          | j                   t        j                  u r| j
                  dk(  st        d| j                        | j                          6| j                          t        | j
                  dd        }| j                          ||fS )	Nr}  r   zExpected an equals signr   :r   z#Expected an comma or an equals signr   )rW   r   rj   r   r\   r[   r7   rl   r   r1   r2   r  )r8   rB   r  r1  s       r   r  zParser.expect_master_  sI   ##5::5%&=t?W?WXX??D!((ELL8T__PS=S%-t/G/G  '')E"HTN$$

2t7G7G7Jc7Q!((ELL8T__PS=S%94;S;S  !' ( 	DOOAB'(r?   c                     | j                          | j                  t        j                  v r| j                  S t        d| j                        )Nz/Expected a decimal, hexadecimal or octal number)r7   rW   r   r  r[   r   r\   r=  s    r   r  zParser.expect_any_number_  sB    5==0??"=t?W?W
 	
r?   c                     | j                          | j                  t        j                  u r| j                  S t        d| j                        )Nz Expected a floating-point number)r7   rW   r   r  r[   r   r\   r=  s    r   r$  zParser.expect_float_  sB    5;;.??".0H0H
 	
r?   c                     | j                   t        j                  k(  r| j                         S | j                   t        j                  u r| j                         dz  S t        d| j                        )Nr  ,Expected an integer or floating-point numberr1   r   r  r$  r/  r   r   r\   r=  s    r   r~  zParser.expect_decipoint_  sa      EKK/%%''""ell2&&(2--!>@X@X r?   c                     d}ddd}| j                   dk7  rZ| j                   |v r| j                         }|||   z  }n#t        d| j                   | j                        | j                   dk7  rZ|S )Nr   r   r$  )OlderSiblingFontAttributeElidableAxisValueNamerR   zUnexpected STAT flag )r2   r   r   r[   r\   )r8   r1  r3  ro   s       r   r  zParser.expect_stat_flags  s    )*%&
 #%5(((*d+%+DOO+<=t?W?W  #% r?   c                     | j                   t        j                  k(  r| j                         S | j                   t        j                  u r| j                         S t        d| j                        )Nr  r  r=  s    r   expect_stat_values_zParser.expect_stat_values_  s\      EKK/%%''""ell2&&((!>@X@X r?   c                     | j                          | j                  t        j                  u r| j                  S t        d| j                        )NzExpected a string)r7   rW   r   STRINGr[   r   r\   r=  s    r   r  zParser.expect_string_  s>    5<</??"143K3KLLr?   c                 2   |rJ| j                   r>t        j                  | _        | j                   j	                  d      \  | _        | _        y | j                  | j                  | j                  c| _        | _        | _        	 	 t        | j                        \  | _        | _        | _	        | j                  t        j                  k7  ry | j                   j                  | j                  | j                  f       y# t        $ r d\  | _        | _        Y jw xY w)Nr   r   )r3   r   rX   rW   r#   r[   r\   r1   r2   r4   nextr5   StopIterationrY   )r8   r    s     r   r7   zParser.advance_lexer_  s   **#(==D 8<8J8J8N8Nq8Q5DOT5 %%  )) LD $/43K
 G
 %	)$- $$5%%t'7'79R9R&ST  ! G:F7%t'7Gs   (C; ;DDc                 H    dj                  t        t        |                   S )z'abc' --> 'cba'r   )r%   reversedrL  )r   s    r   reverse_string_zParser.reverse_string_  s     wwxQ())r?   c                     t               }||kD  rt        d|      t        ||dz         D ]  }|j                  d|z          |S )z>(location, 999, 1001) --> ["cid00999", "cid01000", "cid01001"]z*Bad range: start should be less than limitr   r  )rL  r   r   rY   )r8   rB   r   r   r:  r   s         r   r   zParser.make_cid_range_  sS    5=!<h  	* 	+CMM)c/*	+r?   c                 &   t               }t        |      t        |      k7  rt        d|d|d|      | j                  }t        j
                  j                  ||g      } |t        j
                  j                   ||       ||      g            }t        |      dkD  r1|t        |      t        |        }|t        |      t        |        }	n|t        |      d }|t        |      d }	||	k\  rt        d|      t        j                  d      }
|
j                  |      rP|
j                  |	      r?t        t        |      t        |	      dz         D ]  }|j                  d	|||fz          |S t        j                  d
      }|j                  |      rP|j                  |	      r?t        t        |      t        |	      dz         D ]  }|j                  d	|||fz          |S t        j                  d      }|j                  |      rm|j                  |	      r\t        t        |d      t        |	d      dz         D ]4  }dt        |      z   t        |       d }|j                  |||       6 |S t        d|d|d|      )z?(location, "a.sc", "d.sc") --> ["a.sc", "b.sc", "c.sc", "d.sc"]zBad range: "z" and "z" should have the same lengthr   Nz+Start of range must be smaller than its endz^[A-Z]$r   z%s%c%sz^[a-z]$z^[0-9]{1,3}$r  000r   r   )rL  r$   r   r  ospathcommonprefixr  compiler  r   ordrY   r  r   )r8   rB   r   r   r:  revr   r   start_rangelimit_range	uppercasec	lowercasedigitsr   rE  s                   r   r   zParser.make_glyph_range_  sW   u:U#!JOQVW 
 ""%%uen5RWW))3u:s5z*BCDv;?Fs6{l;KFs6{l;KF.KF.K+%!=x  JJz*	??;'IOOK,H3{+S-=-AB >h&!V)<<=>MJJz*	??;'IOOK,H3{+S-=-AB >h&!V)<<=>MO,<<$k)B3{B/["1E1IJ C#a&.3{+;*;*=>&&&ABC MeUCXNNr?   )rd  TN)F)NFN)i__name__
__module____qualname____doc__rk   r(   r   rW  rX  r>   rr   r   r   rb   ra   r   r   r   r`   r   r   r   r   r   r  r^   r  r  r  rd   r5  re   r   rD  rE  rF  rG  r`  rw  r{  r  r  rh   r  r  r  r  r  r  r  r  r  staticmethodr  r  r  r  r  r  r!  r  r  r  r  r1  r   r   r   ri   rc   rf   ra  rh  rr  rp  rq  r  rg   r  r]   r8  r   r  r   r   r   r   r^  r  r}   r~   r   r   r  r  r  r$  r~  r  r  r  r7   r  r   r   )r   r   s   00r   r   r      s   0 J
C-21f-=>x!|>O-21f-=>x!|>O KO+B=~4
l
"
H	RH
8(TbH[Gz&
A
YW27
r,3
j
 MQ"RCxt=
$
<0Y68S"8@8:


)   4 4!F*X8 
D6
p@B'R

,
L
\	U$LR!F+Z"H
NJ#@L RVr*hJXB.RSKM6

 MU0 * *	+OgF ?>s
   E8E>r   c                   *    e Zd Zd Zd Zd Zd Zd Zy)r+   c                     i g| _         y r   scopes_r=  s    r   r>   zSymbolTable.__init__,	  s    tr?   c                 :    | j                   j                  i        y r   )r  rY   r=  s    r   re  zSymbolTable.enter_scope/	  s    Br?   c                 8    | j                   j                          y r   )r  r#   r=  s    r   rf  zSymbolTable.exit_scope2	  s    r?   c                 (    || j                   d   |<   y )Nr   r  )r8   ro   items      r   r   zSymbolTable.define5	  s    !%Rr?   c                 f    t        | j                        D ]  }|j                  |      }|s|c S  y r   )r  r  r:  )r8   ro   scoper  s       r   r   zSymbolTable.resolve8	  s4    dll+ 	E99T?D	 r?   N)r  r  r  r>   re  rf  r   r   rd  r?   r   r+   r+   +	  s     &r?   r+   )fontTools.feaLib.errorr   fontTools.feaLib.lexerr   r   r   fontTools.feaLib.variableScalarr   fontTools.misc.encodingToolsr   fontTools.misc.textToolsr	   r
   r   fontTools.feaLib.astfeaLibr(   loggingr  r  	getLoggerr  r   objectr   r+   rd  r?   r   <module>r     s[    2 K K : 4 < < " "  	 	 g!Y$OV Y$OxH& r?   