a
    —Æàg¢€ ã                   @   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                   @   sP  e Zd ZdZi ZeZdd„ eddƒD ƒZdd„ eddƒD ƒZdÊ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dd „ ZdËd"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_„ Z2d`da„ Z3e4dbdc„ ƒZ5e4ddde„ ƒZ6dfdg„ Z7dhdi„ Z8djdk„ Z9dldm„ Z:dndo„ Z;dpdq„ Z<drds„ Z=dtdu„ Z>dvdw„ Z?dxdy„ Z@dzd{„ ZAd|d}„ ZBd~d„ ZCd€d�„ ZDd‚dƒ„ ZEdÌd„d…„ZFd†d‡„ ZGdˆd‰„ ZHdŠd‹„ ZIdŒd�„ ZJdŽd�„ ZKd�d‘„ ZLd’d“„ ZMdÍd”d•„ZNd–d—„ ZOd˜d™„ ZPdšd›„ ZQdœd�„ ZRdždŸ„ ZSd d¡„ ZTd¢d£„ ZUd¤d¥„ ZVd¦d§„ ZWd¨d©„ ZXdªd«„ ZYd¬d­„ ZZd®d¯„ Z[dÎd°d±„Z\d²d³„ Z]d´dµ„ Z^d¶d·„ Z_d¸d¹„ Z`dºd»„ Zad¼d½„ Zbd¾d¿„ ZcdÀdÁ„ ZddÏdÂdÃ„Zee4dÄdÅ„ ƒZfdÆdÇ„ ZgdÈdÉ„ Zhd
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   úP/var/www/sistema_ama/venv/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 | _|rÌt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�ròqqtd | j| j¡| jƒ‚q| j�r<dd„ | j  ¡ D ƒ}tdd !|¡ dƒ‚| j S )z»Parse the file, and return a :class:`fontTools.feaLib.ast.FeatureFile`
        object representing the root of the abstract syntax tree containing the
        parsed contents of the file.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   ÚparseN   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r¤t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 rœt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�sÜt 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 �rÌtd| j | jƒ‚t|| jjƒ�rð| jj|| jd�}n| jj|| jd�}| "|¡ qìt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 rÎg }
|  d¡ |	sèt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|ƒ… ƒ�rˆtd
| jƒ‚|t|ƒt|ƒt|ƒ … }t|ƒ�rÞt|t|ƒt|ƒ d … ƒ�rØt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>   r“   rH   ÚbyÚfromTr†   ú'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.zƒPositioning 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�\}}}}}}t|ƒr8td|› d�|ƒ‚|svtd|› d�|ƒ}	t t|	ƒ¡ |dd … |dd…  }}|||f}
|
S )	NFr@   z(No lookups can be specified for "ignore ú"zAmbiguous "ignore z)", there should be least one marked glyphr   r   )rS   rÀ   r¹   r   rª   r«   r¬   )r6   Úsubr:   rº   rŠ   r»   r¼   r½   r¾   rf   ÚchainContextr   r   r   Úparse_ignore_glyph_pattern_  s"    ÿÿ
þ
z"Parser.parse_ignore_glyph_pattern_c                 C   sF   | j }|  |¡g}| jdkr8|  d¡ | |  |¡¡ q|  d¡ |S )Nr“   rH   )rS   rÄ   r0   rq   rP   )r6   rÂ   r:   rÃ   r   r   r   Úparse_ignore_context_!  s    


zParser.parse_ignore_context_c                 C   st   |   d¡sJ ‚| j}|  ¡  | jdv r@|  d¡}| jj||d�S | jdv rd|  d¡}| jj||d�S td| jƒ‚d S )NÚignore)Ú
substituterÂ   rÂ   r9   )ÚpositionÚposrÉ   z#Expected "substitute" or "position")	rT   rS   r5   rR   rÅ   r'   ZIgnoreSubstStatementZIgnorePosStatementr   )r6   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   9  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_@  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_O  s    


z"Parser.parse_ligatureCaretByIndex_c                 C   sh   |   d¡sJ ‚| j}| jdd�}| jdd�g}| jdkrL| | jdd�¡ q.|  d¡ | jj|||d�S )NÚLigatureCaretByPosTr†   ro   rH   r9   )	rT   rS   rˆ   rw   r0   rP   rq   r'   ZLigatureCaretByPosStatementrÔ   r   r   r   Úparse_ligatureCaretByPos_Y  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[   c  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 rŒtd| j
 | jƒ‚| | j
¡ | j
dkrº|  d¡ | jdd�}qd| j
dkrÜ|  d¡ | jdd�}qd| j
|v rüd}|||  ¡  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	|ƒr¼t	|ƒr¦t
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rØt|ƒsØtd| jƒ‚|
d
k�rT|rðt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�r’t|	d tjƒ�r’g }	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 |�s6t
|ƒdk�r6t
|	ƒdk�r6|dk�r6t
|d  ¡ ƒ}|	D ]b}t| ¡ ƒ�sÒtd|ƒ‚t
| ¡ ƒdk�r¶t
| ¡ ƒ|k�r¶td|› dt
| ¡ ƒ› d�|ƒ‚�q¶| jj||d ||	||d�S |�s t
|ƒdk�r t
|	ƒdk�r t
|	d  ¡ ƒdk�r |dk�r | jj|||t|	d  ¡ ƒd ||d�S |�rnt
|ƒdk�r¾td|ƒ‚t
|	ƒdk�rÖtd|ƒ‚|dk�rêtd|ƒ‚tt|d  ¡ ƒƒ}tt|	d  ¡ ƒƒ}t
|ƒdk�r,|t
|ƒ }t
|ƒt
|ƒk�rXtdt
|ƒt
|ƒf |ƒ‚| jj||||	|d�S t
|ƒdk�r”t
|	ƒdk�r”td|ƒ‚t
|	ƒdk�s¨|�r²t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   v  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   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)rR   rS   rÀ   r¹   r   r0   rr   rˆ   rP   rq   r#   rç   r'   ZAlternateSubstStatementr§   r¤   rô   ÚSingleSubstStatementÚMultipleSubstStatementZLigatureSubstStatementÚsortedZ ReverseChainSingleSubstStatementZChainContextSubstStatement)r6   r:   ró   Z
old_prefixÚoldr»   r¼   Ú
old_suffixr¾   ÚnewÚkeywordr±   Znum_lookupsZis_deletionrŠ   ÚreplacementsÚcountÚnZruler   r   r   Úparse_substitute_C  s0   

ùÿ





þ
ÿ$
ÿÿ ,þüÿú,
$
ÿýúÿ
þ
ýüûú
ýü
ÿþü
ÿý

ÿ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r²t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rÀq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  ;  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  S  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rÂtd| jƒ‚q
| j
dkr¶q
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  b  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rÂtd| jƒ‚q
| j
dkr¶q
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  }  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}|p„d}|  ¡ }|  d¡ t|||ƒ}|du r¶t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 3r.  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}|p„d}|  ¡ }t|||ƒ}|d u r¬td|ƒ‚|  ||¡}||||fS )Nr-  r/  r.  r   r   r0  r1  )	r/   r   r2  r3  rS   r   r4  r   r5  r6  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   r3  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©r7  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  r7  r   ÚunescapeÚutf16r   r<  r   r5  ó  s    zParser.unescape_string_c                 C   s    |   d¡dd … }tt|dƒƒS ©Nr   r   é   )ÚgroupÚchrÚint)Úmatchr  r   r   r   r@  ÿ  s    zParser.unescape_unichr_c                 C   s&   |   d¡dd … }tt|dƒƒ |¡S rC  )rE  r   rG  Údecode)rH  r7  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¡r°g }tdƒD ]}| |  ¡ ¡ qšn<| j
|v rÚg }| jd	krì| |  ¡ ¡ q¾n|  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š   r4  ZOS2Field)r6   rF   rM   Z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¡ |s°td
| jƒ‚|S )NÚElidedFallbackNamer  r   rI   Ústatr9   rH   úUnexpected token z in ElidedFallbackNameúExpected "name")rT   rq   r0   r1   r5   r8  r'   ÚSTATNameStatementrS   rP   rR   r   )r6   Únamesr  r  r  r  Z
nameRecordr   r   r   Úparse_STAT_ElidedFallbackNameX  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rÈqNqNt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   rR  r9   rH   zExpected "name", got )rT   r€   Úisupperrª   r«   rw   rq   r0   r1   r5   rN   r   rO   rS   r8  r'   rU  rP   rR   r   ZSTATDesignAxisStatement)
r6   rV  ZaxisTagZ	axisOrderr:   r  r  r  r  rI   r   r   r   Úparse_STAT_design_axist  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rÔq$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 �rŽtd|› d�| jƒ‚|
 |¡ �qf| j
 |||| j¡S )NÚ	AxisValuer  r   r   Tr   rI   rR  r9   r:   ÚflagrH   rS  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   r8  r'   rU  rP   Úparse_STAT_locationÚexpect_stat_flagsrR   r   r#   r¼   r�   ZSTATAxisValueStatement)r6   Ú	locationsrV  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rÚtd|› d	|› d
|› d�| jƒ‚| j ||¡S )NrÞ   r]  z must be 4 charactersrH   zUnexpected value "z". Expected integer or float.r.  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   r^  Î  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   rQ  ÚElidedFallbackNameIDrH   rX  r[  zDesignAxis not defined for rb  rS  )rM   r0   r1   r5   rN   r   rO   rP   r'   rQ   rR   rS   ra   rT   rW  rQ  rw   rd  rq   rZ  r�   ra  r`  r   )	r6   rF   rM   Zdesign_axesrV  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)rJ  rL  rH   )rR   r0   rP   rø   rq   )r6   Úbasesr   r   r   rN    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)rK  rM  r“   rH   )rR   Úparse_base_script_record_r0   rq   rP   )r6   r  Úscriptsr   r   r   rO  $  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   3  r   z4Parser.parse_base_script_record_.<locals>.<listcomp>)rø   rš   )r6   r  Z
script_tagZbase_tagZcoordsr   rh  r   rf  0  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   Útuple)r6   Úresultr   r   r   rx   6  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   rh  r   r   r   r·   E  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 rÈt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�rÌtd| jƒ‚nd\}}}}|  	d¡ | jj||	|
|||||||d�
S )Nrk  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   |  s   ÿz-Parser.parse_valuerecord_.<locals>.<listcomp>r   r   i€ÿÿÿr¶   é   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Ú
yPlacementrm  rl  rx   rþ   )r6   rA   Únumberr:   ÚvalrI   Úvrdrã   rp  rq  rm  rl  Z
xPlaDeviceZ
yPlaDeviceZ
xAdvDeviceZ
yAdvDeviceZ	allDeltasr   r   r   r¸   L  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   rt  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vhalZvaltZvkrnFr  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rÞqHqHtd	| jƒ‚qH|  d¡ | jD ]}| ¡  qü|  d¡ |S )
z¾Parses 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   rT  )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ràqNqNtd
 | j| j ¡| jƒ‚qN|  d¡ | jD ]}| ¡  �q
|  d	¡ |S )NÚcvParametersr9   r  r   Tr   >   ZFeatUILabelNameIDZSampleTextNameIDZFeatUITooltipTextNameIDZParamUILabelNameIDÚ	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rÞqFqFtd| jƒ‚qF|  d¡ | jD ]}| ¡  qü|  d¡ |S )	Nr9   r  r   Tr   rI   rH   rT  )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   r3  rq   r   rd   r'   ZCharacterStatement)r6   r�   r:   Ú	characterr   r   r   r„  N  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   rc  rq   r   r'   ZFontRevisionStatement)r6   r:   Úversionr   r   r   r%  Z  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rþt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  rc  râ   rw   r'   ZConditionsetStatement)r6   rI   Z
conditionsÚaxisZ	min_valueZ	max_valueZ	finalnamer   r   r   r^   d  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�rÖq$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,ƒ�r€t-|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‘   rz  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   rw  ry  rx  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   rh  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   rh  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   rh  r   r   r   rË     s    zParser.expect_filename_c                 C   sF   |   ¡  | jtju r | j d¡S | jtju r6d| j S td| jƒ‚d S )Nú\úcid%05dzExpected a glyph name or CID)	r5   rN   r   ra   rR   Úlstripr£   r   rS   rh  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 )zëAdds 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   rV  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   rh  r   r   r   r€   :  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ø   D  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Ð   M  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   V  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‘  rh  r   r   r   rs   b  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 )Nrk  zExpected a number)	r5   rN   r   râ   rR   rc   Úexpect_variable_scalar_r   rS   )r6   rp   r   r   r   rw   h  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’  p  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s¢t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   rG  )r6   r:   r‰  rã   r   r   r   r”  z  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   r2  rR   r   rS   rh  r   r   r   r3  •  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   rh  r   r   r   rc  �  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 )NrP  ú,Expected an integer or floating-point number©r/   r   r  rc  râ   rw   r   rS   rh  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   r_  ¯  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—  rh  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   rh  r   r   r   r4  É  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rŽq¤| 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�   rj  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rÆt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ê| 	|	¡�rêt
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}$rP  Z000z%s%s%szBad range: "%s-%s")rô   r#   r   r�  ÚosÚpathÚcommonprefixr?  ÚcompilerH  rš   ÚordrP   rG  r¬   )r6   r:   rœ   r�   rj  Úrevrº   r½   Zstart_rangeZlimit_rangeZ	uppercaseÚcZ	lowercaseÚdigitsr   rr  r   r   r   r©   ÷  sF    
þÿ


zParser.make_glyph_range_)r   TN)F)F)NFN)F)F)iÚ__name__Ú
__module__Ú__qualname__Ú__doc__rb   r'   rš   ru  rv  r8   rg   rz   r}   rY   rX   r‹   r‘   r”   rW   rŸ   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  r8  r,  r5  Ústaticmethodr@  r:  r  r  rW  rZ  ra  r^  r   rN  rO  rf  rx   r·   r¸   r`   rZ   r]   rz  r€  r…  rƒ  r„  r%  r^   rÙ   rT   rè   r­   rË   r¥   r¦   r|   r€   rø   rÐ   rq   rr   rs   rw   r’  r”  r3  rc  r
  r_  r˜  r4  r5   r�  r®   r©   r   r   r   r   r      sÔ    ÿ
!?6
*
d]	

95 ; 

#,"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_rh  r   r   r   r8   &	  s    zSymbolTable.__init__c                 C   s   | j  i ¡ d S r   )r¬  rP   rh  r   r   r   r}  )	  s    zSymbolTable.enter_scopec                 C   s   | j  ¡  d S r   )r¬  r"   rh  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   Zscoper­  r   r   r   rt   2	  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ž  r?  Ú	getLoggerr¦  rª   Úobjectr   r)   r   r   r   r   Ú<module>   s:   
                  (