a
    w=ic                    @   s   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  mZ d dlZd dlZd dlZeeZG dd deZG d	d
 d
eZdS )    )FeatureLibError)LexerIncludingLexerNonIncludingLexer)VariableScalar)getEncoding)bytechrtobytestostrNc                   @   sH  e Zd ZdZi ZeZdd eddD Zdd eddD ZdddZ	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zdd"d#Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Z d<d= Z!d>d? Z"d@dA Z#dBdC Z$dDdE Z%dFdG Z&dHdI Z'dJdK Z(dLdM Z)dNdO Z*dPdQ Z+dRdS Z,dTdU Z-dVdW Z.dXdY Z/dZd[ Z0d\d] Z1d^d_ Z2e3d`da Z4e3dbdc Z5ddde Z6dfdg Z7dhdi Z8djdk Z9dldm Z:dndo Z;dpdq Z<drds Z=dtdu Z>dvdw Z?dxdy Z@dzd{ ZAd|d} ZBd~d ZCdd ZDdddZEdd ZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdddZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZdddZ[dd Z\dd Z]dd Z^dd Z_dd Z`dd Zadd Zbdd ZcdddZde3ddÄ Zeddń ZfddǄ Zgd
S )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.
    c                 C   s   h | ]}d | qS )zss%02d .0ir   r   h/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/fontTools/feaLib/parser.py	<setcomp>*       zParser.<setcomp>      c                 C   s   h | ]}d | qS )zcv%02dr   r   r   r   r   r   +   r   d   r   TNc                 K   s   d|v r4ddl m} |dd |r*td|d}|rhtdt|dkrLdnd	d
dd |D f t|| _| j	 | _
t | _t | _t | _t | _| j| jh| _d\| _| _g | _d | _|rtnt}|||d| _i | _| jdd d S )NZglyphMapr   )deprecateArgumentz#use 'glyphNames' (iterable) insteadz?'glyphNames' and (deprecated) 'glyphMap' are mutually exclusivez"unsupported keyword argument%s: %sr    sz, c                 s   s   | ]}t |V  qd S N)repr)r   kr   r   r   	<genexpr>=   r   z"Parser.__init__.<locals>.<genexpr>NN)
includeDirTcomments)ZfontTools.misc.loggingToolsr   	TypeErrorpoplenjoinsetglyphNames_astZ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_)selfZfeaturefileZ
glyphNamesZfollowIncludesr   kwargsr   Z
lexerClassr   r   r   __init__-   s8    

&
zParser.__init__c                 C   sB  | j j}| jdus| jr| jdd | jtju rN|| j	j
| j| jd q| drh||   q| jtju r||   q| dr||   q| dr||   q| dr||   q| d	r|| jd
d q| dr||   q| dr(||   q| drD||   q| drd|| jdd q| dr||   q| dr|| jd
d q| jtju r| j| jv r|| j| j |  q| jtju r| jdkrqqtd| j| j| jq| jr<dd | j  D }tdd!| d| j S )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ZanonZ	anonymous	anchorDeflanguagesystemlookupFvertical	markClassfeatureconditionset	variation)rE   tablevalueRecordDef;zbExpected feature, languagesystem, lookup, markClass, table, or glyph class definition, got {} "{}"c                 S   s   g | ]\}}d ||f qS )z %s (first found at %s)r   )r   namelocr   r   r   
<listcomp>   s   z Parser.parse.<locals>.<listcomp>zMThe following glyph names are referenced but are missing from the glyph set:

)"r(   
statementsr/   r1   r5   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   formatr4   itemsr$   )r6   rM   errorr   r   r   parseO   sn    






zParser.parsec           	   	   C   s   |  d | d | j}| jdkr<| d |  d d S | jtjkr|  }| j	|}|d u rtt
d| | j|  d | jj|j|j||jd d |dS | jdd| jdd }}d }| jd	kr| d	 |  }| jdkr|  }|  }nd
\}}|  d | jj||d ||||dS )N<anchorNULL>zUnknown anchor "%s")rI   contourpointxDeviceTableyDeviceTabler:   Tvariablerl   r   )expect_symbol_expect_keyword_rS   r0   r/   r   ra   expect_name_r*   resolver   r'   ZAnchorxyrl   expect_number_parse_device_)	r6   r:   rI   	anchordefru   rv   rl   rm   rn   r   r   r   parse_anchor_   sV    












zParser.parse_anchor_c                 C   sP   g }| j dkrL|  }|d u r*| j dkr*q| d |  }|||f q|S )Nrh   mark)r0   rz   rr   expect_markClass_reference_rP   )r6   ZanchorMarksri   rB   r   r   r   parse_anchor_marks_   s    

zParser.parse_anchor_marks_c                 C   s   |  dsJ | j}|  |   }}d }| jdkrF| d |  }|  }| d | jj|||||d}| j	
|| |S )Nr=   rl   rH   )rl   r:   )rT   rS   rw   r0   rr   rs   rq   r'   ZAnchorDefinitionr*   define)r6   r:   ru   rv   rl   rI   ry   r   r   r   rY      s    



zParser.parse_anchordef_c                 C   sn   |  dsJ |  }| j|\}}}|   | d |  }||ksRJ d| d | jj|||dS )Nr<   }z-bad splitting in Lexer.scan_anonymous_block()rH   r9   )rT   expect_tag_r3   Zscan_anonymous_blockr5   rq   r'   ZAnonymousBlock)r6   tag_contentr:   end_tagr   r   r   rX      s    

zParser.parse_anonymous_c                 C   s`   |  dsJ | j}| jdd}|  h}| jdkrD||   q*| d | jj|||dS )NAttachTaccept_glyphnamerH   r9   )	rT   rS   parse_glyphclass_rw   r0   addrq   r'   ZAttachStatement)r6   r:   glyphsZcontourPointsr   r   r   parse_attach_   s    


zParser.parse_attach_c                 C   s$   | j dv sJ |   | jd|dS )N>   	enumerateenumT
enumeratedrA   )rR   r5   parse_position_)r6   rA   r   r   r   parse_enumerate_   s    zParser.parse_enumerate_c                 C   s   |  dsJ | j}| jdkr,| jdd}nd }| d | jdkrR| jdd}nd }| d | jdkrx| jdd}nd }| d | jdkr| jdd}nd }| d | jj|||||dS )NGlyphClassDef,Fr   rH   r9   )rT   rS   r0   r   rq   r'   ZGlyphClassDefStatement)r6   r:   Z
baseGlyphsZligatureGlyphsZ
markGlyphsZcomponentGlyphsr   r   r   parse_GlyphClassDef_   s*    








zParser.parse_GlyphClassDef_c                 C   sR   | j | j }}| d | jdd}| d | jj|||d}| j|| |S )N=Fr   rH   r9   )rS   rR   rq   r   r'   ZGlyphClassDefinitionr+   r~   )r6   r:   rI   r   
glyphclassr   r   r   rW     s    

z#Parser.parse_glyphclass_definition_c           	      C   s   | d}g }tt|D ]L}d|d| d||d   }}|| jv r|| jv r|||f qt|dkr|d \}}||fS t|dkrtd| |n&ddd |D }td||f |d S )	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 c                 S   s   g | ]\}}d ||f qS )z	"%s - %s"r   )r   r   lr   r   r   rK   F  r   z-Parser.split_glyph_range_.<locals>.<listcomp>zBAmbiguous glyph range "%s"; please use %s to clarify what you mean)splitranger#   r$   r&   rP   r   )	r6   rI   r:   partsZ	solutionsr   startlimitrangesr   r   r   split_glyph_range_#  s.    
&zParser.split_glyph_range_Fc              	   C   s2  |r`| j tjtjfv r`|r<| jdkr<|   | jj| jdS | 	 }| 
| | jj|| jdS | j tju r|   | j| j}|d u rtd| j | jt|| jjr| jj|| jdS | jj|| jdS | d | j}| jj|d}| jdkr$| j tju r| 	 }| j}d|v rh| jrh|| jvrh| ||\}}| 
|| |||| ||| n| jdkr|}| d | 	 }| 
|| |||| ||| n@d|v r| jstttd|| | 
| || q| j tju r| 	 }| jdkrh| j}	| j}
| d |  }| 
d|
d	d|d	 | |
|| !|	|
| n"d| jd	}| 
| || q| j tju r|   | j| j}|d u rtd| j | jt|| jjr| jj|| jd}n| jj|| jd}|"| qtd
| j| j#q| d |S )Nrj   r9   zUnknown glyph class @%s[]r   z.Ambiguous glyph name that looks like a range: cidZ05dzBExpected glyph name, glyph range, or glyph class reference, found )$r/   r   ra   CIDr0   r5   r'   	NullGlyphrS   expect_glyph_check_glyph_name_in_glyph_setZ	GlyphNamerV   r+   rt   rR   r   
isinstance	MarkClassZMarkClassNameZGlyphClassNamerq   Z
GlyphClassr&   r   Z	add_rangemake_glyph_range_logwarningstrrP   expect_cid_Zadd_cid_rangemake_cid_range_Z	add_classr2   )r6   r   accept_nullglyphgcr:   r   r   r   Zrange_locationZrange_startZ	range_endZ
glyph_namer   r   r   r   M  s    







zParser.parse_glyphclass_c                 C   sR  g g g g g f\}}}}}d}| j dvr2| jdd}d}	| j dkrT| d d }}	|	rt|rhtd| j|| n|r|| n
|| |  r|| | n
|d  d }
| j dkr"|
d u rg }
| d |	std| j| 	 }| j
|}|d u rtd	| | j|
| q|	r||
 q|sf|sf|g ksLJ g |d gt| |g |fS t|d t| rtd
| j|t|t|t|  }t|rt|t|t| d  rtd| j|}n`|r(|d r(t|dkst|d d rtd| j|dd  }nt|r>td| j||||||fS d S )NF>   fromr   rH   byTr   'z_Unsupported contextual target sequence: at most one run of marked (') glyph/class names allowedr?   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   )r0   r   rq   r   rS   rP   is_next_value_parse_valuerecord_rr   rs   r,   rt   r#   any)r6   rA   prefixr   lookupsvaluessuffixhasMarksr   ZmarkedZ
lookuplistlookup_namer?   Zmarked_valuesr   r   r   parse_glyph_pattern_  s    







 
zParser.parse_glyph_pattern_c           
      C   s   | j }| jdd\}}}}}}|||fg}t|}	| jdkr|| d | jdd\}}}}}}||||f |	pxt|}	q2| d ||	fS )NFr@   r   rH   )rS   r   r   r0   rq   rP   )
r6   r:   r   r   r   r   r   r   chainContext
hasLookupsr   r   r   parse_chain_context_  s(    



zParser.parse_chain_context_c                 C   s   |  dsJ | j}|   | jdv rP|  \}}|r@td|| jj||dS | jdv r|  \}}|rttd|| jj||dS td| jd S )Nignore)
substitutesubz,No lookups can be specified for "ignore sub"r9   )positionposz,No lookups can be specified for "ignore pos"z#Expected "substitute" or "position")	rT   rS   r5   rR   r   r   r'   ZIgnoreSubstStatementZIgnorePosStatement)r6   r:   r   r   r   r   r   parse_ignore_#  s(    

zParser.parse_ignore_c                 C   s*   | j dksJ | j}|  }tj||dS )Nr;   r9   )rR   rS   expect_filename_r'   ZIncludeStatement)r6   r:   filenamer   r   r   rU   :  s    zParser.parse_include_c                 C   sp   |  dsJ | j}|  }d\}}| jdv r:|  dk}| jdkrR| d d}| d | jj||||dS )	Nlanguage)TF>   Zexclude_dfltinclude_dfltr   requiredTrH   r9   )	rT   rS   expect_language_tag_r0   rs   rr   rq   r'   ZLanguageStatement)r6   r:   r   include_defaultr   r   r   r   parse_language_A  s    



zParser.parse_language_c                 C   s`   |  dsJ | j}| jdd}|  g}| jdkrD||   q*| d | jj|||dS )NLigatureCaretByIndexTr   rH   r9   )	rT   rS   r   rw   r0   rP   rq   r'   ZLigatureCaretByIndexStatementr6   r:   r   Zcaretsr   r   r   parse_ligatureCaretByIndex_P  s    


z"Parser.parse_ligatureCaretByIndex_c                 C   s`   |  dsJ | j}| jdd}|  g}| jdkrD||   q*| d | jj|||dS )NLigatureCaretByPosTr   rH   r9   )	rT   rS   r   rw   r0   rP   rq   r'   ZLigatureCaretByPosStatementr   r   r   r   parse_ligatureCaretByPos_Z  s    


z Parser.parse_ligatureCaretByPos_c                 C   s   |  dsJ | j|   }}| jdkrf| j|}|d u rLtd| | j| d | jj	||dS d}| jdkr| 
d d}| jj|||d}| || | j|| |S )Nr?   rH   r   r9   FuseExtensionT)rT   rS   rs   r0   r,   rt   r   rq   r'   ZLookupReferenceStatementrr   ZLookupBlockparse_block_r~   )r6   rA   r:   rI   r?   use_extensionblockr   r   r   r[   d  s$    




zParser.parse_lookup_c                 C   sJ  |  dsJ | j}| jtjkrB|  }| d | jj||dS d}d\}}}dddd	d
}t	 }| j
dkr| j
|v rtd| j
 | j|| j
 | j
dkr| d | jdd}qd| j
dkr| d | jdd}qd| j
|v rd}|||   B }qdtd| j
 | jqd| d t|||gs6td| j| jj||||dS )N
lookupflagrH   r9   F)r   NNr            )ZRightToLeftZIgnoreBaseGlyphsZIgnoreLigaturesZIgnoreMarksz%s can be specified only onceZMarkAttachmentTyper   ZUseMarkFilteringSetTz#"%s" is not a recognized lookupflagzlookupflag must have a value)markAttachmentmarkFilteringSetr:   )rT   rS   r/   r   NUMBERrw   rq   r'   ZLookupFlagStatementr%   r0   r   r2   r   rr   r   rs   r   )r6   r:   valueZ
value_seenr   r   flagsseenr   r   r   parse_lookupflag_}  sZ    








zParser.parse_lookupflag_c                 C   s   |  dsJ | j}| jdd}| s2td||  }|  }| d | jj	
|}|d u r| j|}|| jj	|< | j|| | jj||||d}|| |S )NrB   Tr   z*Empty glyph class in mark class definitionrH   r9   )rT   rS   r   glyphSetr   rz   expect_class_name_rq   r(   ZmarkClassesgetr'   r   r+   r~   ZMarkClassDefinitionZaddDefinition)r6   r:   r   ri   rI   rB   Zmcdefr   r   r   r\     s$    


zParser.parse_markClass_c           
      C   sH  | j dv sJ | jdkr$| ||S | jdkr:| ||S | jdkrP| ||S | jdkrf| ||S | j}| |\}}}}}}	| d t	|rt	|rt
d|| jj|||||dS |s|st|d	kr|	s|d
 d u r|  | jj|d
 |d
 |d |d ||dS |r(t
d|| jjtt|||||	|dS )N>   r   r   cursivebaseligaturer{   rH   z3If "lookup" is present, no values must be specifiedr9   r   r   r   )r   r:   z2"enumerate" is only allowed with pair positionings
forceChainr:   )rR   r0   parse_position_cursive_parse_position_base_parse_position_ligature_parse_position_mark_rS   r   rq   r   r   r'   ZChainContextPosStatementr#   reverseZPairPosStatementZSinglePosStatementlistzip)
r6   r   rA   r:   r   r   r   r   r   r   r   r   r   r     sX    





 	zParser.parse_position_c                 C   sX   | j }| d |rtd|| jdd}|  }|  }| d | jj||||dS )Nr   z>"enumerate" is not allowed with cursive attachment positioningTr   rH   r9   )rS   rr   r   r   rz   rq   r'   ZCursivePosStatement)r6   r   rA   r:   r   ZentryAnchorZ
exitAnchorr   r   r   r     s    

zParser.parse_position_cursive_c                 C   sN   | j }| d |rtd|| jdd}|  }| d | jj|||dS )Nr   zC"enumerate" is not allowed with mark-to-base attachment positioningTr   rH   r9   )rS   rr   r   r   r}   rq   r'   ZMarkBasePosStatement)r6   r   rA   r:   r   marksr   r   r   r     s    

zParser.parse_position_base_c                 C   st   | j }| d |rtd|| jdd}|  g}| jdkrX| d ||   q4| d | jj	|||dS )Nr   zG"enumerate" is not allowed with mark-to-ligature attachment positioningTr   ZligComponentrH   r9   )
rS   rr   r   r   r}   r0   rP   rq   r'   ZMarkLigPosStatement)r6   r   rA   r:   Z	ligaturesr   r   r   r   r     s    




zParser.parse_position_ligature_c                 C   sN   | j }| d |rtd|| jdd}|  }| d | jj|||dS )Nr{   zC"enumerate" is not allowed with mark-to-mark attachment positioningTr   rH   r9   )rS   rr   r   r   r}   rq   r'   ZMarkMarkPosStatement)r6   r   rA   r:   Z	baseMarksr   r   r   r   r   .  s    

zParser.parse_position_mark_c                 C   s8   |  dsJ | j|   }}| d | jj||dS )NscriptrH   r9   )rT   rS   expect_script_tag_rq   r'   ZScriptStatement)r6   r:   r   r   r   r   parse_script_<  s    
zParser.parse_script_c                 C   s  | j dv sJ | j}| j dv }| jdd\}}}}}}t|rHtd|g }	| jdkr| d}
| jdkr| jddd	}|	| q`n(| jd
kr| d
}
| jddg}	nd }
| 	d t
|	dkrt|std| j|
d
krT|rtd|t
|dkst
|d  dkrtd|t
|	dkr6td|| jj||d ||	d |dS t
dd |D }d}t
|	dkrt|	d tjrg }	d}|s<t
|dkr<t
|	dkr<|dkr<t|d  }t|	d  }t
|dkr|t
| }t
|t
|kr$tdt
|t
|f || jj||	||||dS |rvt
|dkrv|dkrv| jj||d |d||dS |s*t
|dkr*t
|d  dkr*t
|	dkr*tdd |	D dkr*|dkr*|	D ]}t| std|q| jj|t|d  d |tdd |	D ||dS |st
|dkrt
|	dkrt
|	d  dkr|dkr| jj|||t|	d  d ||dS |rbt
|dkrtd|t
|	dkrtd||dkrtd|tt|d  }tt|	d  }t
|dkr |t
| }t
|t
|krLtdt
|t
|f || jj||||	|dS t
|dkrt
|	dkrtd|t
|	dks|rtd|| jj|||||d}|S ) N>   
reversesubrsubr   r   >   r   r   Fr@   z-Substitution statements cannot contain valuesr   rH   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"r9   c                 S   s   g | ]}|d ur|qS r   r   )r   r   r   r   r   rK   u  r   z,Parser.parse_substitute_.<locals>.<listcomp>z\Expected a glyph class with %d elements after "by", but found a glyph class with %d elementsr   r   c                 S   s   g | ]}t | qS r   )r#   r   r   nr   r   r   rK     r   zEmpty class in replacementc                 S   s   g | ]}t | d  qS )r   )r   r   r   r   r   r   rK     r   z\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)rR   rS   r   r   r   r0   rr   r   rP   rq   r#   r   r'   ZAlternateSubstStatementr   r   r   SingleSubstStatementMultipleSubstStatementmaxtupleZLigatureSubstStatementsortedZ ReverseChainSingleSubstStatementZChainContextSubstStatement)r6   r:   r   Z
old_prefixoldr   r   
old_suffixr   newkeywordr   Znum_lookupsZis_deletionr   replacementsr   ruler   r   r   parse_substitute_B  s6   








$
 ,








zParser.parse_substitute_c                 C   s,   |  dsJ | j}| d | jj|dS )NsubtablerH   r9   )rT   rS   rq   r'   ZSubtableStatement)r6   r:   r   r   r   parse_subtable_  s    
zParser.parse_subtable_c                 C   sv   |  dsJ | j}|  }|  }d}d}| jtjtjfv sF|dkrV|  }|  }| d | j	j
|||||dS )N
parametersg        r   rH   r9   )rT   rS   expect_decipoint_rw   r/   r   r   FLOATrq   r'   ZSizeParameters)r6   r:   Z
DesignSizeZSubfamilyIDZ
RangeStartZRangeEndr   r   r   parse_size_parameters_  s    

zParser.parse_size_parameters_c                 C   s<   |  dsJ | j}|  \}}}}| jjd|||||dS )Nsizemenunamesizer9   )rT   rS   parse_name_r'   FeatureNameStatement)r6   r:   
platformID	platEncIDlangIDstringr   r   r   parse_size_menuname_  s    zParser.parse_size_menuname_c              	   C   s   |  dsJ | j|   }}| jj||d}| d | j| j| j| j	| j
| j| j| jd|}|rr|| ntd|  || d |  }||krtd|  | j| d |S )	NrF   r9   {)ZGDEFheadZhheaZvhearI   ZBASEzOS/2ZSTATz"table %s" is not supportedr   Expected "%s"rH   )rT   rS   r   r'   Z
TableBlockrq   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)r6   r:   rI   rF   handlerr   r   r   r   r_     s8    
	



zParser.parse_table_c                 C   s   |j }| jdks| jr| jdd | jtju rJ|| jj	| j
| jd q| drd||   q| dr~||   q| dr||   q| dr||   q| j
d	krqqtd
| jqd S )Nr   Tr   r9   r   r   r   r   rH   z<Expected Attach, LigatureCaretByIndex, or LigatureCaretByPos)rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   rT   r   r   r   r   r   r6   rF   rM   r   r   r   r  5  s*    




zParser.parse_table_GDEF_c                 C   s   |j }| jdks| jr| jdd | jtju rJ|| jj	| j
| jd q| drd||   q| j
dkrrqqtd| jqd S )Nr   Tr   r9   FontRevisionrH   zExpected FontRevision)rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   rT   parse_FontRevision_r   r%  r   r   r   r  M  s    

zParser.parse_table_head_c                 C   s   |j }d}| jdks| jr| jdd | jtju rN|| jj	| j
| jd q
| jtju r| j
|v r| j
 }|  }|| jj||| jd | jdkrtd| jq
| j
dkrq
q
td| jq
d S )	N)ZCaretOffsetZAscenderZ	DescenderZLineGapr   Tr   r9   rH   Incomplete statementz4Expected CaretOffset, Ascender, Descender or LineGap)rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   ra   lowerrw   Z	HheaFieldr   r2   r6   rF   rM   fieldskeyr   r   r   r   r  \  s0    


zParser.parse_table_hhea_c                 C   s   |j }d}| jdks| jr| jdd | jtju rN|| jj	| j
| jd q
| jtju r| j
|v r| j
 }|  }|| jj||| jd | jdkrtd| jq
| j
dkrq
q
td| jq
d S )	N)ZVertTypoAscenderZVertTypoDescenderZVertTypoLineGapr   Tr   r9   rH   r(  z?Expected VertTypoAscender, VertTypoDescender or VertTypoLineGap)rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   ra   r)  rw   Z	VheaFieldr   r2   r*  r   r   r   r  w  s0    


zParser.parse_table_vhea_c                 C   s   |j }| jdks| jr| jdd | jtju rJ|| jj	| j
| jd q| drl|  }|r|| q| j
dkrzqqtd| jqd S )Nr   Tr   r9   nameidrH   zExpected nameid)rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   rT   parse_nameid_r   )r6   rF   rM   Z	statementr   r   r   r    s    

zParser.parse_table_name_c                 C   s   d}d}| j tjv rR|  }| j}|dvr4td|| j tjv r\|  }|  }n
d}| j}|dkrv|pjd}|prd}n|p|d}|pd}|  }| d t|||}|du rtd	|| 	||}||||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 3r0  r   r   	  rH   Unsupported encoding)
r/   r   NUMBERSexpect_any_number_rS   r   expect_string_rq   r   unescape_string_r6   r  r  r  r:   r  encodingZ	unescapedr   r   r   r    s0    




zParser.parse_name_c                 C   s   d }d }| j tjv rR|  }| j}|dvr4td|| j tjv r\|  }|  }n
d}| j}|dkrv|pjd}|prd}n|p|d}|pd}|  }t|||}|d u rtd|| ||}||||fS )Nr/  r1  r0  r   r   r2  r3  )	r/   r   r4  r5  rS   r   r6  r   r7  r8  r   r   r   parse_stat_name_  s.    



zParser.parse_stat_name_c                 C   s`   | j dksJ | j | j|   }}|dkr8td| j|  \}}}}| jj||||||dS )Nr-  i  z*Name id value cannot be greater than 32767r9   )rR   rS   r5  r   r  r'   Z
NameRecord)r6   r:   ZnameIDr  r  r  r  r   r   r   r.    s    zParser.parse_nameid_c                    sL    dkrt dj|}n fdd}t d||}t|dd}t|dS )N	utf_16_bez\\[0-9a-fA-F]{4}c                    s    |  S r   )unescape_byte_)mr9  r6   r   r   <lambda>  r   z)Parser.unescape_string_.<locals>.<lambda>z\\[0-9a-fA-F]{2}surrogatepass)rer   unescape_unichr_r	   r
   )r6   r  r9  r   unescapeutf16r   r>  r   r7    s    zParser.unescape_string_c                 C   s    |  ddd  }tt|dS Nr   r      )groupchrint)matchr   r   r   r   rB    s    zParser.unescape_unichr_c                 C   s&   |  ddd  }tt|d|S rE  )rG  r   rI  decode)rJ  r9  r   r   r   r   r<    s    zParser.unescape_byte_c                 C   s   |j }| jdks| jr| jdd | jtju rJ|| jj	| j
| jd q| dr^|  }q| dr| t|}|| jj||d| jd q| dr|  }q| d	r| t|}|| jj||d| jd q| j
d
krqqd S )Nr   Tr   r9   HorizAxis.BaseTagListHorizAxis.BaseScriptListFVertAxis.BaseTagListVertAxis.BaseScriptListrH   )rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   rT   parse_base_tag_list_parse_base_script_list_r#   ZBaseAxis)r6   rF   rM   Zhoriz_basesZhoriz_scriptsZ
vert_basesZvert_scriptsr   r   r   r     sB    






zParser.parse_table_BASE_c                 C   s  |j }d}d}| jdks | jr| jdd | jtju rT|| jj	| j
| jd q| jtju r| j
 }d }| j
|v r|  }nh| drg }tdD ]}||   qn<| j
|v rg }| jd	kr||   qn| d
r|  }|| jj||| jd q| j
d	krqqd S )N)ZFSTypeZTypoAscenderZTypoDescenderZTypoLineGapZ	winAscentZ
winDescentZXHeightZ	CapHeightZWeightClassZ
WidthClassZLowerOpSizeZUpperOpSize)ZUnicodeRangeZCodePageRanger   Tr   r9   ZPanose
   rH   ZVendor)rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   ra   r)  rw   rT   r   r6  ZOS2Field)r6   rF   rM   numbersr   r,  r   r   r   r   r   r!  &  s:    







zParser.parse_table_OS_2_c                 C   s   |  dsJ | d g }| jdks,| jr|   |  drt|  \}}}}| jjd||||| jd}|	| q| j
dkrtd| j
 d	| jq| d |std
| j|S )NElidedFallbackNamer  r   rI   statr9   rH   Unexpected token z in ElidedFallbackNameExpected "name")rT   rq   r0   r1   r5   r:  r'   STATNameStatementrS   rP   rR   r   )r6   namesr  r  r  r  Z
nameRecordr   r   r   parse_STAT_ElidedFallbackNameR  s2    



z$Parser.parse_STAT_ElidedFallbackNamec           
      C   s   |  dsJ g }|  }|dvr<| s<td| d |  }| d | jdks^| jr| 	  | j
tju rvqNqN|  dr| j}|  \}}}}| jjd|||||d	}	||	 qN| jd
krqNqNtd| j | jqN| d | j|||| jS )N
DesignAxis)ZitalZopszZslntZwdthZwghtzUnregistered axis tag z should be uppercase.r  r   rI   rU  r9   rH   zExpected "name", got )rT   r   isupperr   r   rw   rq   r0   r1   r5   rN   r   rO   rS   r:  r'   rX  rP   rR   r   ZSTATDesignAxisStatement)
r6   rY  ZaxisTagZ	axisOrderr:   r  r  r  r  rI   r   r   r   parse_STAT_design_axisn  s<    




zParser.parse_STAT_design_axisc                 C   s  |  dsJ | d g }g }d}| jdks4| jr| jdd | jtju rPq$q$|  dr| j}| 	 \}}}}| j
jd|||||d	}	||	 q$|  d
r|  }|| q$|  dr|  }q$| jdkrq$q$td| j d| jq$| d |std| j|std| jt|dkr|D ]0}t|jdkr,tdt|j d| jq,g }
|D ]4}|j}||
v rtd| d| j|
| qf| j
|||| jS )N	AxisValuer  r   r   Tr   rI   rU  r9   r:   flagrH   rV  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.)rT   rq   r0   r1   r5   rN   r   rO   rS   r:  r'   rX  rP   parse_STAT_locationexpect_stat_flagsrR   r   r#   r   r   ZSTATAxisValueStatement)r6   	locationsrY  r   r:   r  r  r  r  rI   Zformat4_tagsr   r   r   r   parse_STAT_axis_value_  sh    








zParser.parse_STAT_axis_value_c                 C   s   g }|   }t| dkr2td| j d| j| jdkr| jtj	u r\| 
 }|| q2| jtju r||  }|| q2td| j d| jq2t|dkr|\}}}||k s||krtd| d	| d
| d| j| j||S )Nr   r`  z must be 4 charactersrH   zUnexpected value "z". Expected integer or float.r0  zDefault value z is outside of specified range r   .)r   r#   r#  r   rR   rS   r0   r/   r   r  expect_float_rP   r   rw   r2   r'   ZAxisValueLocationStatement)r6   r   r   r   ZnominalZmin_valZmax_valr   r   r   ra    s<    

zParser.parse_STAT_locationc           	      C   sj  |j }g }| jdks| jrf| jdd | jtju rP|| jj	| j
| jd q
| jtju rX| dr|  }|| j| n| dr|  }|| j| | d n| dr|  }||j || | d nn| d	rB|  }|jD ](}|j|vrtd
|j d| jq|| | d ntd| j
 | jq
| j
dkr
q
q
d S )Nr   Tr   r9   rT  ElidedFallbackNameIDrH   r[  r^  zDesignAxis not defined for re  rV  )rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   ra   rT   rZ  rT  rw   rg  rq   r]  r   rd  rc  r   )	r6   rF   rM   Zdesign_axesrY  r   Z
designAxisZaxisValueRecordr:   r   r   r   r"    sH    






zParser.parse_table_STAT_c                 C   s@   | j dv sJ | j g }| jdkr2||   q| d |S )N)rL  rN  rH   )rR   r0   rP   r   rq   )r6   basesr   r   r   rP    s    

zParser.parse_base_tag_list_c                 C   sT   | j dv sJ | j | |g}| jdkrF| d || | q | d |S )N)rM  rO  r   rH   )rR   parse_base_script_record_r0   rq   rP   )r6   countscriptsr   r   r   rQ    s    


zParser.parse_base_script_list_c                    s0      }   } fddt|D }|||fS )Nc                    s   g | ]}   qS r   )rw   r   r6   r   r   rK   -  r   z4Parser.parse_base_script_record_.<locals>.<listcomp>)r   r   )r6   rj  Z
script_tagZbase_tagZcoordsr   rl  r   ri  *  s    z Parser.parse_base_script_record_c                 C   s   d }|  d | d | jdkr.| d nF|  |  fg}| jdkrl|  d ||  |  f q@t|}|  d |S )Nrh   Zdevicerj   r   rk   )rq   rr   r0   rw   rP   r   )r6   resultr   r   r   rx   0  s    





zParser.parse_device_c                 C   s    | j tju p| jdkp| jdkS )Nrh   ()r/   r   r   r0   rl  r   r   r   r   ?  s
    zParser.is_next_value_c                 C   s  | j tju r| jdks"| j tju rd| jdd| j }}|rN| jj|||d}n| jj|||d}|S | 	d | j}| j tj
u r|  }|dkr| 	d | j S | j|}|d u rtd	| | j|j}|j|j }}	|j|j }
}n4| jdd| jdd| jdd| jddf\}}	}
}| jdkr|  |  |  |  f\}}}}td
d |rb|nd|rn|nd |r||nd |r|nd D }|d dk s|d dkrtd| jnd\}}}}| 	d | jj||	|
|||||||d
S )Nrn  Tro   )yAdvancerA   r:   )xAdvancerA   r:   rh   rj   rk   zUnknown valueRecordDef "%s"c                 S   s   g | ]\}}|qS r   r   )r   r  deltar   r   r   rK   v  s   z-Parser.parse_valuerecord_.<locals>.<listcomp>r   r   ir      z+Device value out of valid range (-128..127))NNNN)rA   r:   )r/   r   rc   r0   r   rw   rS   r'   ZValueRecordrq   ra   rs   r-   rt   r   r   
xPlacement
yPlacementrp  ro  rx   r  )r6   rA   numberr:   valrI   vrdr   rs  rt  rp  ro  Z
xPlaDeviceZ
yPlaDeviceZ
xAdvDeviceZ
yAdvDeviceZ	allDeltasr   r   r   r   F  s    










	
zParser.parse_valuerecord_c                 C   sT   |  dsJ | j}| |}|  }| d | jj|||d}| j|| |S )NrG   rH   r9   )	rT   rS   r   rs   rq   r'   ZValueRecordDefinitionr-   r~   )r6   rA   r:   r   rI   rw  r   r   r   r`     s    

z$Parser.parse_valuerecord_definition_c                 C   s@   | j dksJ | j}|  }|  }| d | jj|||dS )Nr>   rH   r9   )rR   rS   r   r   rq   r'   ZLanguageSystemStatement)r6   r:   r   r   r   r   r   rZ     s    
zParser.parse_languagesystem_c                 C   s   |r| j dks"J n| j dks"J | j}|  }|dv }d }d }d}|| jv rT|}n|| jv rd|}n|dkrpd}|r||  }d}	| jdkr| d d}	|r| jj	|||	|d}
n| jj
||	|d}
| |
|||| |
S )	NrE   rC   >   ZvpalZvkrnZvhalZvaltFr  Tr   )r   r:   )rR   rS   r   SS_FEATURE_TAGSCV_FEATURE_TAGSrs   r0   rr   r'   ZVariationBlockZFeatureBlockr   )r6   rE   r:   r   rA   stylisticset
cv_featuresize_featurerD   r   r   r   r   r   r]     s<    



zParser.parse_feature_block_c                 C   s<   | j dksJ | j | j}|  }| d | jj||dS )NrC   rH   r9   )rR   rS   r   rq   r'   ZFeatureReferenceStatement)r6   r:   ZfeatureNamer   r   r   parse_feature_reference_  s
    
zParser.parse_feature_reference_c           	   
   C   s  | j dksJ | j | jj|| j | jd}| d | jD ]}|  q:| jdksX| jr| j	dd | j
tju r|j| jj| j | jd qH| dr| j}|  \}}}}|j| jj||||||d qH| j dkrqHqHtd	| jqH| d | jD ]}|  q| 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>`_.featureNamesr9   r  r   Tr   rI   rH   rW  )rR   r'   NestedBlockrS   rq   r.   enter_scoper0   r1   r5   rN   r   rO   rM   rP   rQ   rT   r  r  r   
exit_scope)	r6   r   r   symtabr:   r  r  r  r  r   r   r   parse_featureNames_  s:    









zParser.parse_featureNames_c                 C   s(  | j dksJ | j | jj|| j | jd}| d | jD ]}|  q:|j}| jdks^| j	r| j
dd | jtju r|| jj| j | jd qN| h dr|| || j  qN| dr|| | qN| j d	krqNqNtd
| j| j | jqN| d | jD ]}|  q
| d	 |S )NcvParametersr9   r  r   Tr   >   ZSampleTextNameIDZParamUILabelNameIDZFeatUITooltipTextNameIDZFeatUILabelNameID	CharacterrH   zExpected statement: got {} {})rR   r'   r  rS   rq   r.   r  rM   r0   r1   r5   rN   r   rO   rP   rQ   rT   parse_cvNameIDs_parse_cvCharacter_r   rd   r  )r6   r   r   r  rM   r   r   r   parse_cvParameters_  sB    








zParser.parse_cvParameters_c           
      C   s  | j |ksJ | j | jj||| jd}| d | jD ]}|  q8| jdksV| jr| j	dd | j
tju r|j| jj| j | jd qF| dr| j}|  \}}}}	|j| jj|||||	||d qF| j dkrqFqFtd| jqF| d | jD ]}|  q| d |S )	Nr9   r  r   Tr   rI   rH   rW  )rR   r'   r  rS   rq   r.   r  r0   r1   r5   rN   r   rO   rM   rP   rQ   rT   r  ZCVParametersNameStatementr   r  )
r6   r   Z
block_namer   r  r:   r  r  r  r  r   r   r   r  #  sB    








zParser.parse_cvNameIDs_c                 C   sh   | j dksJ | j | j|   }}| d d|  krBdksVn tddd|| jj|||dS )Nr  rH   i r   z/Character value must be between {:#x} and {:#x}r9   )rR   rS   r5  rq   r   rd   r'   ZCharacterStatement)r6   r   r:   	characterr   r   r   r  G  s    
zParser.parse_cvCharacter_c                 C   sP   | j dksJ | j | j|   }}| d |dkr@td|| jj||dS )Nr&  rH   r   z&Font revision numbers must be positiver9   )rR   rS   rf  rq   r   r'   ZFontRevisionStatement)r6   r:   versionr   r   r   r'  S  s    

zParser.parse_FontRevision_c                 C   s  |   }i }| d | jdkr|   | jtjur@td| j| j	}||v r`td| | j| j
tju rv|  }n| j
tju r| jdd}| j
tju r|  }n| j
tju r| jdd}| d ||f||< q| d |   }||krtd| | j| j||S )	Nr  r   Expected an axis namezRepeated condition for axis Fro   rH   r  )rs   rq   r0   r5   rN   r   ra   r   rS   rR   r/   r  rf  r   rw   r'   ZConditionsetStatement)r6   rI   Z
conditionsaxis	min_value	max_valueZ	finalnamer   r   r   r^   ]  s6    





zParser.parse_conditionset_c                 C   sd  |  d | jD ]}|  q|j}| jdks6| jr| jdd | jtj	u rj|
| jj| j| jd q$| jtju r|
|   q$| dr|
|   q$| ddhr|
| j|d	 q$| d
r|
|   q$| d r|
|   q$| dr|
|   q$| dr2|
| | q$| drN|
|   q$| drj|
|   q$| ddhr|
| jd|d q$| dr|
|   q$| h dr|
|   q$| dr|
|   q$| dr|
| | q$|r*| dr*|
| | q$|rN| drN|
|  | q$|rp| drp|
| !  q$|r| dr|
| "  q$| jtj#u r| j| j$v r|
| j$| j |  q$| jdkrq$q$t%d&| j| j| jq$|  d | jD ]}|'  q | ( }||j)* kr>t%d|j)*  | j|  d d}	d}
|D ]T}t+|| jj,rt-|j.|j/|j0g }	n&t+|| jj1rTt-|j.|j/|j0g }
qT|	r`|
r`g }|jD ]}t+|| jj,rL|j2d 3 }|j4d 3 }t5|d kr
|t5|9 }t6|D ]6\}}|
| jj1|j.||j/|| g|j0|j7d qn
|
| q||_d S )!Nr  r   Tr   r9   r=   r   r   r@   rC   r   r   r?   r   rB   r   r   Fr   r   >   r   r   r   r   r	  rG   r~  r  r  r  rH   z7Expected glyph class definition or statement: got {} {}r  r   r   )8rq   r.   r  rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   rV   rW   rT   rY   r   r}  r   r   r[   r   r\   r   r   r  r
  r`   r  r  r  r  ra   rb   r   rd   r  rs   rI   r#  r   r   r   r   r   r   r   r   r   r  r#   r   r:   )r6   r   rA   rz  r|  r{  r  rM   rI   Z
has_singleZhas_multipler   r   r  r   r   r   r   r   r     s    











zParser.parse_block_c                 C   s2   | j tju r.t|tdr$| j|kS | j|v S dS )Nr   F)rN   r   ra   r   typerR   )r6   r   r   r   r   rT     s
    

zParser.is_cur_keyword_c                 C   s&   |    | jtjur td| j| jS )NzExpected @NAME)r5   rN   r   rV   r   rS   rR   rl  r   r   r   r     s    zParser.expect_class_name_c                 C   s*   |    | jtju r| jS td| jd S )NzExpected a CID)r5   rN   r   r   rR   r   rS   rl  r   r   r   r     s    zParser.expect_cid_c                 C   s&   |    | jtjur td| j| jS )NzExpected file name)r5   rN   r   ZFILENAMEr   rS   rR   rl  r   r   r   r   
  s    zParser.expect_filename_c                 C   sh   |    | jtju rB| jd| _t| jdkr<td| j| jS | jtj	u rXd| j S td| jd S )N\?   z1Glyph names must not be longer than 63 characterscid%05dzExpected a glyph name or CID)
r5   rN   r   ra   rR   lstripr#   r   rS   r   rl  r   r   r   r     s    
zParser.expect_glyph_c                 G   s6   | j r2|D ]&}|| j v rq
|| jvr
| j| j|< q
dS )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&   r4   rS   )r6   rY  rI   r   r   r   r     s    

z$Parser.check_glyph_name_in_glyph_setc                 C   sN   |   }| j|}|d u r,td| | jt|| jjsJtd| | j|S )NzUnknown markClass @%sz@%s is not a markClass)r   r+   rt   r   rS   r   r'   r   )r6   rI   Zmcr   r   r   r|   ,  s    

z"Parser.expect_markClass_reference_c                 C   sL   |    | jtjur td| jt| jdkr:td| j| jd d d S )NzExpected a tagr   z'Tags cannot be longer than 4 charactersz    )r5   rN   r   ra   r   rS   r#   rR   rl  r   r   r   r   9  s    zParser.expect_tag_c                 C   s    |   }|dkrtd| j|S )NZdfltz4"dflt" is not a valid script tag; use "DFLT" insteadr   r   rS   r6   r   r   r   r   r   C  s    zParser.expect_script_tag_c                 C   s    |   }|dkrtd| j|S )NZDFLTz6"DFLT" is not a valid language tag; use "dflt" insteadr  r  r   r   r   r   L  s    zParser.expect_language_tag_c                 C   s6   |    | jtju r"| j|kr"|S td| | jd S )NzExpected '%s')r5   rN   r   rc   rR   r   rS   )r6   symbolr   r   r   rq   U  s    zParser.expect_symbol_c                 C   s8   |    | jtju r$| j|kr$| jS td| | jd S )Nr  r5   rN   r   ra   rR   r   rS   )r6   r  r   r   r   rr   [  s    zParser.expect_keyword_c                 C   s*   |    | jtju r| jS td| jd S )NzExpected a namer  rl  r   r   r   rs   a  s    zParser.expect_name_c                 C   sL   |    | jtju r| jS |r<| jtju r<| jdkr<|  S td| jd S )Nrn  zExpected a number)	r5   rN   r   r   rR   rc   expect_variable_scalar_r   rS   )r6   rp   r   r   r   rw   g  s    zParser.expect_number_c                 C   sD   |    t }| jtjkr&| jdkr&q@|  \}}||| q|S )N))r5   r   rN   r   rc   rR   expect_master_Z	add_value)r6   Zscalarr:   r   r   r   r   r  o  s    zParser.expect_variable_scalar_c                 C   s   i }| j tjurtd| j| j}|   | j tju r@| jdksLtd| j|  }|||< | j	tju rx| j
d dkrxq|   | j tju r| jdkstd| j|   q|   t| jdd  }|   ||fS )	Nr  r   zExpected an equals signr   :r   z#Expected an comma or an equals signr   )rN   r   ra   r   rS   rR   r5   rc   rw   r/   r0   rI  )r6   r:   r  r   r   r   r   r  y  s.    
zParser.expect_master_c                 C   s*   |    | jtjv r| jS td| jd S )Nz/Expected a decimal, hexadecimal or octal number)r5   rN   r   r4  rR   r   rS   rl  r   r   r   r5    s    zParser.expect_any_number_c                 C   s*   |    | jtju r| jS td| jd S )Nz Expected a floating-point number)r5   rN   r   r  rR   r   rS   rl  r   r   r   rf    s    zParser.expect_float_c                 C   s<   | j tjkr|  S | j tju r,|  d S td| jd S )NrR  ,Expected an integer or floating-point numberr/   r   r  rf  r   rw   r   rS   rl  r   r   r   r    s    zParser.expect_decipoint_c                 C   sR   d}ddd}| j dkrN| j |v r8|  }||| B }qtd| j | jq|S )Nr   r   r   )ZOlderSiblingFontAttributeZElidableAxisValueNamerH   zUnexpected STAT flag )r0   rs   r   rR   rS   )r6   r   r   rI   r   r   r   rb    s    

zParser.expect_stat_flagsc                 C   s8   | j tjkr|  S | j tju r(|  S td| jd S )Nr  r  rl  r   r   r   expect_stat_values_  s    zParser.expect_stat_values_c                 C   s*   |    | jtju r| jS td| jd S )NzExpected a string)r5   rN   r   STRINGrR   r   rS   rl  r   r   r   r6    s    zParser.expect_string_c                 C   s   |r*| j r*tj| _| j d\| _| _d S | j| j| j	  | _| _| _zt
| j\| _| _| _	W n ty~   d\| _| _Y n0 | jtjkrq| j | j| j	f qFd S )Nr   r   )r1   r   rO   rN   r"   rR   rS   r/   r0   r2   nextr3   StopIterationrP   )r6   r    r   r   r   r5     s(    
zParser.advance_lexer_c                 C   s   d tt| S )z'abc' --> 'cba'r   )r$   reversedr   )r   r   r   r   reverse_string_  s    zParser.reverse_string_c                 C   s>   t  }||krtd|t||d D ]}|d|  q&|S )z>(location, 999, 1001) --> ["cid00999", "cid01000", "cid01001"]z*Bad range: start should be less than limitr   r  )r   r   r   rP   )r6   r:   r   r   rm  r   r   r   r   r     s    zParser.make_cid_range_c                 C   s   t  }t|t|kr(td||f || j}tj||g}|tj||||g}t|dkr|t|t|  }|t|t|  }	n |t|d }|t|d }	||	krtd|td}
|
	|r|
	|	rt
t|t|	d D ]}|d|||f  q|S td}|	|rt|	|	rtt
t|t|	d D ]}|d|||f  qT|S td	}|	|r|	|	rt
t|d
t|	d
d D ]4}dt| t| d }|d|||f  q|S td||f |dS )z?(location, "a.sc", "d.sc") --> ["a.sc", "b.sc", "c.sc", "d.sc"]z4Bad range: "%s" and "%s" 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}$rR  Z000z%s%s%szBad range: "%s-%s")r   r#   r   r  ospathcommonprefixrA  compilerJ  r   ordrP   rI  r   )r6   r:   r   r   rm  revr   r   Zstart_rangeZlimit_rangeZ	uppercasecZ	lowercasedigitsr   ru  r   r   r   r     sF    



zParser.make_glyph_range_)r   TN)F)F)NFN)F)F)h__name__
__module____qualname____doc__rb   r'   r   rx  ry  r8   rg   rz   r}   rY   rX   r   r   r   rW   r   r   r   r   r   rU   r   r   r   r[   r   r\   r   r   r   r   r   r   r  r
  r  r  r_   r  r  r  r  r  r  r:  r.  r7  staticmethodrB  r<  r   r!  rZ  r]  rd  ra  r"  rP  rQ  ri  rx   r   r   r`   rZ   r]   r}  r  r  r  r  r'  r^   r   rT   r   r   r   r   r   r|   r   r   r   rq   rr   rs   rw   r  r  r5  rf  r  rb  r  r6  r5   r  r   r   r   r   r   r   r      s    
">6
*
c]

95 6 

#,"8!)N
&"-$
& 
t
		





r   c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )r)   c                 C   s   i g| _ d S r   scopes_rl  r   r   r   r8   %	  s    zSymbolTable.__init__c                 C   s   | j i  d S r   )r  rP   rl  r   r   r   r  (	  s    zSymbolTable.enter_scopec                 C   s   | j   d S r   )r  r"   rl  r   r   r   r  +	  s    zSymbolTable.exit_scopec                 C   s   || j d |< d S )Nr   r  )r6   rI   itemr   r   r   r~   .	  s    zSymbolTable.definec                 C   s*   t | jD ]}||}|r
|  S q
d S r   )r  r  r   )r6   rI   scoper  r   r   r   rt   1	  s
    

zSymbolTable.resolveN)r  r  r  r8   r  r  r~   rt   r   r   r   r   r)   $	  s
   r)   )ZfontTools.feaLib.errorr   ZfontTools.feaLib.lexerr   r   r   ZfontTools.feaLib.variableScalarr   ZfontTools.misc.encodingToolsr   ZfontTools.misc.textToolsr   r	   r
   ZfontTools.feaLib.astZfeaLibr'   loggingr  rA  	getLoggerr  r   objectr   r)   r   r   r   r   <module>   s:   
                  '