# -*- coding: utf-8 -*-

"""
Copyright (c) 2018-2021 Philippe Schmouker, Typee project, http://www.typee.ovh

Permission is hereby granted,  free of charge,  to any person obtaining a copy
of this software and associated documentation files (the "Software"),  to deal
in the Software without restriction, including  without  limitation the rights
to use,  copy,  modify,  merge,  publish,  distribute, sublicense, and/or sell
copies of the Software,  and  to  permit  persons  to  whom  the  Software  is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT WARRANTY OF ANY  KIND,  EXPRESS  OR
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO  THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT  SHALL  THE
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM,  DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  TORT OR OTHERWISE, ARISING FROM,
OUT  OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""

#=============================================================================
from FrontEnd.IntermediateCode.fe_icode_token_node   import *
from FrontEnd.IntermediateCode.fe_tokenized_icode    import FETokenizedICode

from FrontEnd.IntermediateCode.fe_icblock            import FEICBlock
from FrontEnd.IntermediateCode.fe_icleaf             import FEICLeaf
from FrontEnd.IntermediateCode.fe_ictree             import FEICTree
from FrontEnd.Errors.fe_syntax_errors                import FESyntaxErrors


#=============================================================================
class FEParser:
    """
    This is the class of the Typee Front-End Parser.
    It is the second stage of the front-end pipeline  of  the  Typee 
    translator.
    It  parses Typee tokenized Intermediate Code as generated by the 
    Front-End  Scanner  and  syntaxically parses it to produce Typee 
    Syntaxic Intermediate Code that will be  then  analyzed  by  the
    Typee Front-End Elaborator.
    
    Currently, implements version 10 of Typee Grammar Specification.
    """
    
    #-------------------------------------------------------------------------
    def __init__(self, tokenized_intermediate_code: FETokenizedICode = None) -> None:
        '''
        Constructor.
        
        Args:
            tokenized_intermediate_code:FETokenizedICode
                A reference to the Front-End intermediate code to be parsed.
        '''
        self._tokenizedIC = tokenized_intermediate_code
   
    #-------------------------------------------------------------------------
    def parse(self, tokenized_intermediate_code: FETokenizedICode = None) -> tuple(FEICTree,int):
        '''
        Parses some Front-End Intermediate Code and generates the related
        Front-End Syntaxic Code.
        
        Args:
            tokenized_intermediate_code: FETokenizedICode
                A reference to the Front-End intermediate code to be parsed.
                If  None,  the intermediate code passed at construction time
                will be used.
        
        Returns:
            The  corresponding  Syntaxic  Code  as generated by this parser,
            associated with the detected errors count.
        
        Raises:
            AssertError: no  intermediate  code has been passed for parsing,
                either at construction time or at parsing time.
        '''
        self._tokenizedIC = tokenized_intermediate_code or self._tokenizedIC
        assert self._tokenizedIC is not None
        
        return self._parse_code_file()


    #=========================================================================
    #-------------------------------------------------------------------------
    def _abstract_or_final_qualif(self) -> bool:
        #=======================================================================
        # <abstract or final qualif> ::= <abstract qualifier>
        #                             |  EPS
        #=======================================================================
        if self._current.is_ABSTRACT() or self._current.is_FINAL():
            self._append_syntaxic_node()
            self._next_token_node()
        return True

    #-------------------------------------------------------------------------
    def _access_protection_statement(self) -> bool:
        #=======================================================================
        # <access protection statement> ::= ':' <access qualifier> ':'
        #=======================================================================
        if self._current.is_COLON():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._access_qualifier():
                self._append_error( FESyntaxErrors.ACCESS_QUALIFIER )
            if self._current.is_COLON():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.ACCESS_END )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _access_qualifier(self) -> bool:
        #=======================================================================
        # <protection qualifier>  ::= 'hidden'
        #                          |  'local'
        #                          |  'private'
        #                          |  'protected'
        #                          |  'public'
        #=======================================================================
        if self._current.is_HIDDEN() or self._current.is_PROTECTED() or self._current.is_PUBLIC(): ## (notice: previously scanned by Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _and_test(self) -> bool:
        #=======================================================================
        # <and test> ::= <not test> <and test'>
        #=======================================================================
        return self._not_test() and self._and_test1()

    #-------------------------------------------------------------------------
    def _and_test1(self) -> bool:
        #=======================================================================
        # <and test'> ::= 'and' <not test>
        #              |  EPS
        #=======================================================================
        if self._current.is_AND():
            self._append_syntaxic_node()
            self._next_token_node()
            self._not_test()
        return True

    #-------------------------------------------------------------------------
    def _arithmetic_expr(self) -> bool:
        #=======================================================================
        # <arithmetic expr> ::= <term> <arithmetic expr'>
        #=======================================================================
        return self._term() and self._arithmetic_expr1()

    #-------------------------------------------------------------------------
    def _arithmetic_expr1(self) -> bool:
        #=======================================================================
        # <artihmetic expr'>  ::= '+' <template args> <term> <arithmetic expr'>
        #                      |  '-' <template args> <term> <arithmetic expr'>
        #                      |  EPS
        #=======================================================================
        while self._current.is_MINUS() or self._current.is_PLUS():
            self._append_syntaxic_node()
            self._next_token_node()
            self._template_args() ## (notice: always returns True)
            if not self._term():
                self._append_error( FESyntaxErrors.ARITHM_EXPR )
        return True

    #-------------------------------------------------------------------------
    def _array_type(self) -> bool:
        #=======================================================================
        # <array type> ::= "array" <declared contained type>
        #=======================================================================
        if self._current.is_ARRAY():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._declared_contained_type():
                self._append_error( FESyntaxErrors.ARRAY_CONTAINED_TYPE )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _assert_statement(self) -> bool:
        #===============================================================================
        # <assert statement> ::= 'assert' <expression> <assert statement'>
        #===============================================================================
        if self._current.is_ASSERT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.ASSERT_EXPR )
            self._assert_statement1()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _assert_statement1(self) -> bool:
        #=======================================================================
        # <assert statement'> ::= ',' <expression>
        #                      |  EPS
        #=======================================================================
        if self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.ASSERT_COMMA_EXPR )
        return True

    #-------------------------------------------------------------------------
    def _assign_decl_def_funccall_statement(self) -> bool:
        #=======================================================================
        # <assign decl def func-call statement> ::= <access qualifier> <decl or def statement>
        #                                        |  <decl or def statement>
        #                                        |  <dotted name> <assign or func-call statement> <simple statement end>
        #=======================================================================
        if self._access_qualifier():
            if not self._decl_or_def_statement():
                self._append_error( FESyntaxErrors.PROTECTION_DECL_DEF )
            return True
        elif self._decl_or_def_statement():
            return True
        elif self._dotted_name():
            if not self._assign_or_funccall_statement():
                self._append_error( FESyntaxErrors.ASSIGN_FUNC_CALL )
            if not self._simple_statement_end():
                self._append_error( FESyntaxErrors.STATEMENT_END )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _assign_op(self) -> bool:
        #=======================================================================
        # <assign op> ::= '='
        #              |  <augmented assign op>
        #=======================================================================
        if self._current.is_ASSIGN():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return self._augmented_assign_op()

    #-------------------------------------------------------------------------
    def _assign_or_funccall_statement(self) -> bool:
        #=======================================================================
        # <assign or func-call statement> ::= <target list'> <assignment statement>
        #                                  |  <function call>
        #=======================================================================
        if self._target_list1():
            if not self._assignment_statement():
                self._append_error( FESyntaxErrors.ASSIGN_OPERATOR )
            return True
        elif self._function_call():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _assignment_statement(self) -> bool:
        #=======================================================================
        # <assignment statement> ::= <assign op> <expr list>
        #=======================================================================
        if self._assign_op():
            if not self._expr_list():
                self._append_error( FESyntaxErrors.ASSIGN_EXPR )
            return True
        else:
            return False
            
    #-------------------------------------------------------------------------
    def _atom(self) -> bool:
        #=======================================================================
        # <atom> ::= <decr> <dotted name> <incr or decr>
        #         |  <incr> <dotted name> <incr or decr>
        #         |  <enclosure>
        #         |  <reference>
        #         |  <scalar>
        #         |  <string>
        #         |  <boolean>
        #=======================================================================
        if self._decr():
            if not self._dotted_name():
                self._append_error( FESyntaxErrors.DECR_IDENT )
            return self._incr_or_decr()
        elif self._incr():
            if not self._dotted_name():
                self._append_error( FESyntaxErrors.INCR_IDENT )
            return self._incr_or_decr()
        else:
            return  self._enclosure() or \
                    self._reference() or \
                    self._scalar() or \
                    self._string() or \
                    self._boolean()
            
    #-------------------------------------------------------------------------
    def atom1(self) -> bool:
        #=======================================================================
        # <atom'> ::= <incr or decr>
        #          |  <for comprehension>
        #          |  '??' <expression> <atom''> 
        #=======================================================================
        if self._current.is_OP_2QUEST():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.OP_2QUEST_EXPR )
            return self._atom2()
        else:
            return self._for_comprehension() or self._incr_or_decr()
            ## CAUTION: this order of calls is MANDATORY
            
    #-------------------------------------------------------------------------
    def atom2(self) -> bool:
        #=======================================================================
        # <atom''> ::= '??' <expression> <atom''>
        #          |  EPS
        #=======================================================================
        while self._current.is_OP_2QUEST():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.OP_2QUEST_EXPR )
        return True

    #-------------------------------------------------------------------------
    def _atom_element(self) -> bool:
        #===============================================================================
        # <atom element> ::= <atom> 
        #                 |  <dotted name> <atom element'>
        #                 |  <const qualifier> <atom element''>
        #                 |  <atom element''>
        #===============================================================================
        if self._atom():
            return True
        elif self._dotted_name():
            return self._atom_element1()
        elif self._const_qualifier():
            if not self._atom_element2():
                self._append_error( FESyntaxErrors.SCALAR_TYPE )
            return True
        elif self._atom_element2():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _atom_element1(self) -> bool:
        #=======================================================================
        # <atom element'> ::= <atom'>
        #                  |  <atom element'''>
        #=======================================================================
        return self._atom1() or self._atom_element3()

    #-------------------------------------------------------------------------
    def _atom_element2(self) -> bool:
        #=======================================================================
        # <atom element''> ::= <scalar type'> <scalar type casting>
        #=======================================================================
        if self._scalar_type1():
            if not self._type_casting():
                self._append_error( FESyntaxErrors.CASTING_PAROP )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _atom_element3(self) -> bool:
        #=======================================================================
        # <atom element'''> ::= <function call> <atom element''''>
        #                     |  <is instance of>
        #                     |  <subscription or slicing> <atom element''''>
        #                     |  EPS
        #=======================================================================
        while self._function_call() or self._subscription_or_slicing():
            continue
        if self._is_instance_of():
            return True
        else:
            return True

    #-------------------------------------------------------------------------
    def _augmented_assign_op(self) -> bool:
        #===============================================================================
        # <augmented assign op> ::= '+='
        #                        |  '-='
        #                        |  '*='
        #                        |  '/='
        #                        |  '%='
        #                        |  '&='
        #                        |  '|='
        #                        |  '^='
        #                        |  '<<='
        #                        |  '<<<='
        #                        |  '>>='
        #                        |  '>>>='
        #                        |  '**='
        #                        |  '^^='
        #                        |  '@='
        #                        |  '@@='
        #                        |  '><='
        #                        |  '<>='
        #                        |  '!!='
        #                        |  '::='
        #                        |  '??='
        #===============================================================================
        if isinstance( self._current, (ICTokenNode_AUG_2AROB,
                                       ICTokenNode_AUG_2COLN,
                                       ICTokenNode_AUG_2EXCL, 
                                       ICTokenNode_AUG_2QUEST, 
                                       ICTokenNode_AUG_AROBASE,
                                       ICTokenNode_AUG_BITAND,
                                       ICTokenNode_AUG_BITOR,
                                       ICTokenNode_AUG_BITXOR,
                                       ICTokenNode_AUG_DIV,
                                       ICTokenNode_AUG_GRLE,
                                       ICTokenNode_AUG_LEGR,
                                       ICTokenNode_AUG_MINUS,
                                       ICTokenNode_AUG_MOD,
                                       ICTokenNode_AUG_MUL,
                                       ICTokenNode_AUG_PLUS,
                                       ICTokenNode_AUG_POWER,
                                       ICTokenNode_AUG_SHIFT0L,
                                       ICTokenNode_AUG_SHIFT0R,
                                       ICTokenNode_AUG_SHIFTL,
                                       ICTokenNode_AUG_SHIFTR) ):
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False


    #-------------------------------------------------------------------------
    def _auto_type(self) -> bool:
        #=======================================================================
        # <auto type> ::= '?' <auto type'>
        #=======================================================================
        if self._current.is_ANY_TYPE():
            self._append_syntaxic_node()
            self._next_token_node()
            self._auto_type1() ## (notice: always returns True)
            return True
        else:
            return False
        
    #-------------------------------------------------------------------------
    def _auto_type1(self) -> bool:
        #=======================================================================
        # <auto type'> ::= 'in' '(' <types list> ')'
        #               |  EPS
        #=======================================================================
        if self._current.is_IN():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.AUTO_IN_PAROP )
            if not self._types_list():
                self._append_error( FESyntaxErrors.AUTO_IN_TYPES_LIST )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.AUTO_IN_PARCL )
        return True

    #-------------------------------------------------------------------------
    def _bitand_expr(self) -> bool:
        #===============================================================================
        # <bitand expr> ::= <shift expr> <bitand expr'>
        #===============================================================================
        if self._shift_expr():
            self._bitand_expr1()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _bitand_expr1(self) -> bool:
        #=======================================================================
        # <bitand expr'>  ::= '&' <template args> <shift expr> <bitand expr'>
        #                  |  EPS
        #=======================================================================
        while self._current.is_BITAND():
            self._append_syntaxic_node()
            self._next_token_node()
            self._template_args()
            if not self._shift_expr():
                self._append_error( FESyntaxErrors.BITAND_EXPR )
        return True

    #-------------------------------------------------------------------------
    def _bitor_expr(self) -> bool:
        #=======================================================================
        # <bitor expr> ::= <bitxor expr> <bitor expr'>
        #=======================================================================
        if self._bitxor_expr():
            self._bitor_expr1()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _bitor_expr1(self) -> bool:
        #=======================================================================
        # <bitor expr'> ::= '|' <template args> <bitxor expr> <bitor expr'>
        #                |  EPS
        #=======================================================================
        while self._current.is_BITOR():
            self._append_syntaxic_node()
            self._next_token_node()
            self._template_args()
            if not self._bitxor_expr():
                self._append_error( FESyntaxErrors.BITOR_EXPR )
        return True

    #-------------------------------------------------------------------------
    def _bitxor_expr(self) -> bool:
        #=======================================================================
        # <bitxor expr> ::= <bitand expr> <bitxor expr'>
        #=======================================================================
        if self._bitand_expr():
            self._bitxor_expr1()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _bitxor_expr1(self) -> bool:
        #=======================================================================
        # <bitxor expr'> ::= '^' <template args> <bitand expr> <bitxor expr'>
        #                 |  EPS
        #=======================================================================
        while self._current.is_BITXOR():
            self._append_syntaxic_node()
            self._next_token_node()
            self._template_args()
            if not self._bitand_expr():
                self._append_error( FESyntaxErrors.BITXOR_EXPR )
        return True

    #-------------------------------------------------------------------------
    def _boolean(self) -> bool:
        #=======================================================================
        # <boolean> ::= <TRUE>  |  <FALSE>
        #=======================================================================
        return self._true() or self._false()

    #-------------------------------------------------------------------------
    def _bracket_form(self) -> bool:
        #=======================================================================
        # <bracket form> ::= '[' <expression> <list or map form> ']'
        #=======================================================================
        if self._current.is_BRACKETOP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.BRACKET_FORM_EXPR )
            if not self._list_or_map_form():
                self._append_error( FESyntaxErrors.BRACKET_FORM_LIST_OR_MAP )
            if self._current.is_BRACKETCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.BRACKET_ENDING )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _call_operator(self) -> bool:
        #=======================================================================
        # <call operator> ::= '(' ')'
        #=======================================================================
        if self._current.is_PAROP():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.CALL_OP )
            return True
        else:
            return False
                

    #-------------------------------------------------------------------------
    def _case(self) -> bool:
        #=======================================================================
        # <case> ::= 'case' <expr list> <statements block>
        #=======================================================================
        if self._current.is_CASE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expr_list():
                self._append_error( FESyntaxErrors.CASE_EXPR )
            if not self._statements_block():
                self._append_error( FESyntaxErrors.CASE_BODY )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _cast_op(self) -> bool:
        #=======================================================================
        # <cast op> ::= 'cast' <identifier>
        #=======================================================================
        if self._current.is_CAST():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_IDENT():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.CASTED_TYPE )
            return True
        else:
            return False            

    #-------------------------------------------------------------------------
    def _class_definition(self) -> bool:
        #=======================================================================
        # <class definition> ::= 'class' <identifier> <template def> <inheritance> <statements block>
        #=======================================================================
        if self._current.is_CLASS():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._current._identifier():
                self._append_error( FESyntaxErrors.CLASS_NAME )
            self._template_def()
            self._inheritance()
            if not self._statements_block():
                self._append_error( FESyntaxErrors.CLASS_BODY )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _comment(self) -> bool:
        #=======================================================================
        # <comment>   ::= '//' <comment'>
        #              |  '/*' <multi lines comment>
        # <comment'>    ::= <any non newline char> <comment'>
        #              |    <end line>
        #              |    <ENDOFFILE>
        #=======================================================================
        if self._current.is_COMMENT() or self._current.is_COMMENT_ML(): ## (notice: previously scanned by the Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _comparison(self) -> bool:
        #=======================================================================
        # <comparison> ::= <bitor expr> <comparison'>
        #=======================================================================
        return self._bitor_expr() and self._comparison1()

    #-------------------------------------------------------------------------
    def _comparison1(self) -> bool:
        #===============================================================================
        # <comparison'> ::= <comp operator> <template args> <bitor expr> <comparison'>
        #                |  <comp operator'> <spaced template args> <bitor expr> <comparison'>
        #                |  EPS
        #===============================================================================
        while True:
            if self._comp_operator():
                self._template_args()
                if not self._bitor_expr():
                    self._append_error( FESyntaxErrors.COMP_EXPR )
            elif self._comp_operator1():
                self._spaced_template_args()
                if not self._bitor_expr():
                    self._append_error( FESyntaxErrors.COMP_EXPR )
            else:
                break
        return True

    #-------------------------------------------------------------------------
    def _comp_operator(self) -> bool:
        #=======================================================================
        # <comp operator> ::= '<='  |  '=='  |  '!='  |  '>='
        #                  |  'in'
        #                  |  <is operator>
        #                  |  'not' 'in'
        #=======================================================================
        if self._current.is_LE() or \
            self._current.is_EQ() or \
            self._current.is_NE() or \
            self._current.is_GE() or \
                self._current.is_IN():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        elif self._current.is_NOT():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_IN():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.NOT_IN )
            return True
        else:
            return self._is_operator()

    #-------------------------------------------------------------------------
    def _comp_operator1(self) -> bool:
        #=======================================================================
        # <comp operator'> ::= '<'  |  '>'  |  '<=>'
        #=======================================================================
        if self._current.is_LT() or self._current.is_GT() or self._current.is_LEG():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False
        
    #-------------------------------------------------------------------------
    def _compound_statement(self) -> bool:
        #=======================================================================
        # <compound statement> ::= <assign decl def func-call statement>
        #                       |  <embed statement>
        #                       |  <exclude statement>
        #                       |  <for statement>
        #                       |  <forever statement>
        #                       |  <if statement>
        #                       |  <repeat statement>
        #                       |  <switch statement>
        #                       |  <try statement>
        #                       |  <while statement>
        #                       |  <with statement>
        #=======================================================================
        return self._assign_decl_def_funccall_statement() or \
                self._embed_statement() or \
                self._exclude_statement() or \
                self._for_statement() or \
                self._forever_statement() or \
                self._if_statement() or \
                self._repeat_statement() or \
                self._switch_statement() or \
                self._try_statement() or \
                self._while_statement() or \
                self._with_statement()

    #-------------------------------------------------------------------------
    def _condition(self) -> bool:
        #=======================================================================
        # <condition> ::= <or test> <condition'>
        #=======================================================================
        return self._or_test() and self._condition1()

    #-------------------------------------------------------------------------
    def _condition1(self) -> bool:
        #=======================================================================
        # <condition'> ::= 'if' <or test> <condition">
        #               |  EPS
        #=======================================================================
        if self._current.is_IF():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._or_test():
                self._append_error( FESyntaxErrors.IF_COND )
            return self._condition2()
        else:
            return True                

    #-------------------------------------------------------------------------
    def _condition2(self) -> bool:
        #===========================================================================
        # <condition"> ::= 'else' <expression>
        #               |  'otherwise' <expression>
        #===========================================================================
        if self._current.is_ELSE() or self._current.is_OTHERWISE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.IF_ELSE_EXPR if self._current.is_ELSE() \
                                                                else FESyntaxErrors.IF_OTHERWISE_EXPR )
            return True
        else:
            self._append_error( FESyntaxErrors.IF_ELSE )
            return True

    #-------------------------------------------------------------------------
    def _condition_or_unnamed_func(self) -> bool:
        #=======================================================================
        # <condition or unnamed func> ::= <or test>
        #                              |  <unnamed function>
        #=======================================================================
        return self._or_test() or self._unnamed_function()

    #-------------------------------------------------------------------------
    def _const_qualifier(self) -> bool:
        #=======================================================================
        # <const qualifier> ::= "const"
        #=======================================================================
        if self._current.is_CONST():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _contained_type(self) -> bool:
        #=======================================================================
        # <contained type> ::= <declared contained type>
        #                   |  EPS
        #=======================================================================
        self._declared_contained_type() ## (notice: returned value doesn't matter)
        return True

    #-------------------------------------------------------------------------
    def _container_type(self) -> bool:
        #=======================================================================
        # <container type> ::= <array_type>
        #                   |  <enum type>
        #                   |  <list type>
        #                   |  <map type>
        #                   |  <set type>
        #=======================================================================
        return self._array_type() or \
                self.enum_type()  or \
                self._list_type() or \
                self._map_type()  or \
                self._set_type()

    #-------------------------------------------------------------------------
    def _decl_constructor_or_decl_end(self) -> bool:
        #=======================================================================
        # <decl constructor or decl end> ::= <dotted name'> <decl or def statement'''>
        #                                 |  <function definition'>
        #=======================================================================
        if self._dotted_name1():
            if not self._decl_or_def_statement3():
                self._append_error( FESyntaxErrors.DECL_DEF_IDENT_OP )
            return True
        else:
            return self._function_definition1()

    #-------------------------------------------------------------------------
    def _decl_or_def_statement(self) -> bool:
        #=======================================================================
        # <decl or def statement> ::= <static qualifier> <decl or def statement'>
        #                          |  <class definition>
        #                          |  <decl or def statement'>
        #                          |  <forward decl>
        #=======================================================================
        if self._static_qualifier():
            if not self._decl_or_def_statement1():
                self._append_error( FESyntaxErrors.STATIC_DECL_DEF )
        else:
            return self._class_definition() or \
                    self._decl_or_def_statement1() or \
                    self._forward_decl()

    #-------------------------------------------------------------------------
    def _decl_or_def_statement1(self) -> bool:
        #=======================================================================
        # <decl or def statement'> ::= <abstract or final qualif> <method or operator definition>
        #                           |  <volatile qualifier> <TYPE> <identifier> <memory address> <simple statement end>
        #                           |  <type alias> <simple statement end>
        #                           |  <decl or def statement''>
        #=======================================================================
        if self._abstract_or_final_qualif():
            if not self._method_or_operator_definition():
                self._append_error( FESyntaxErrors.ABSTRACT_DEF )
            return True
        elif self._final_qualifier():
            if not self._method_or_operator_definition():
                self._append_error( FESyntaxErrors.FINAL_DEF )
            return True
        elif self._volatile_qualifier():
            if not self._TYPE():
                self._append_error( FESyntaxErrors.VOLATILE_TYPE )
            if not self._identifier():
                self._append_error( FESyntaxErrors.VAR_NAME )
                return True
            if not self._memory_address():
                self._append_error( FESyntaxErrors.VOLATILE_MEM_KW )
            if not self._simple_statement_end():
                self._append_error( FESyntaxErrors.STATEMENT_END )
            return True
        elif self._type_alias():
            if not self._simple_statement_end():
                self._append_error( FESyntaxErrors.STATEMENT_END )
            return True
        else:
            return self._decl_or_def_statement2()

    #-------------------------------------------------------------------------
    def _decl_or_def_statement2(self) -> bool:
        #=======================================================================
        # <decl or def statement''> ::= <TYPE'> <decl or def statement'''>
        #                            |  <enum definition>
        #                            |  <identifier> <decl constructor or decl end>
        #=======================================================================
        if self._TYPE1():
            if not self._decl_or_def_statement3():
                self._append_error( FESyntaxErrors.OP_IDENT_DECL_DEF )
            return True
        elif self._identifier():
            if not self._decl_constructor_or_decl_end():
                self._append_error( FESyntaxErrors.DECL_DEF_TYPE )
            return True
        elif self._enum_definition():
            return True
        else:
            self._append_error( FESyntaxErrors.VAR_TYPE )
            return False

    #-------------------------------------------------------------------------
    def _decl_or_def_statement3(self) -> bool:
        #=======================================================================
        # <decl or def statement'''> ::= <identifier> <decl or def statement''''>
        #                             |  <operator definition>
        #=======================================================================
        if self._identifier():
            return self._decl_or_def_statement4()
        else:
            return self._operator_definition()

    #-------------------------------------------------------------------------
    def _decl_or_def_statement4(self) -> bool:
        #=======================================================================
        # <decl or def statement''''> ::= <function definition>
        #                              |  <var declaration or assignment> <simple statement end>
        #=======================================================================
        if self._function_declaration():
            return True
        elif self._var_declaration_or_assignment():
            if not self._simple_statement_end():
                self._append_error( FESyntaxErrors.STATEMENT_END )
            return True
        else:
            return False
        
    #-------------------------------------------------------------------------
    def _declared_contained_type(self) -> bool:
        #=======================================================================
        # <declared contained type> ::= '<' <TYPE> '>'
        #=======================================================================
        if self._current.is_LT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._TYPE():
                self._append_error( FESyntaxErrors.CONTAINED_TYPE )
            if self._current.is_GT():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.CONTAINER_END )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _del_statement(self) -> bool:
        #=======================================================================
        # <del statement> ::= 'del' <identifiers list>
        #=======================================================================
        if self._current.is_DEL():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifiers_list():
                self._append_error( FESyntaxErrors.DEL_IDENT )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _dimensions(self) -> bool:
        #=======================================================================
        # <dimensions> ::= '[' <dimensions'> ']' <dimensions>
        #               |  EPS
        #=======================================================================
        while self._current.is_BRACKETOP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._dimensions1():
                if self._float_number():
                    self._append_error( FESyntaxErrors.DIMENSION_FLOAT )
                else:
                    self._append_error( FESyntaxErrors.DIMENSION_CONST )
            if self._current.is_BRACKETCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.DIMENSION_END )
        return True

    #-------------------------------------------------------------------------
    def _dimensions1(self) -> bool:
        #=======================================================================
        # <dimensions'> ::= <integer number>
        #                |  <dotted name>
        #=======================================================================
        if self._integer_number():
            return True
        elif self._dotted_name():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _dotted_as_name(self) -> bool:
        #=======================================================================
        # <dotted as name> ::= <dotted name> <dotted as name'>
        #=======================================================================
        if self._dotted_name():
            return self.dotted_as_name1() ## (notice: always returns True)
        else:
            return False

    #-------------------------------------------------------------------------
    def dotted_as_name1(self) -> bool:
        #=======================================================================
        # <dotted as name'> ::= 'as' <identifier>
        #                    |  EPS
        #=======================================================================
        if self._current.is_AS():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.AS_IDENT )
            return True
        else:
            return True

    #-------------------------------------------------------------------------
    def _dotted_as_names(self) -> bool:
        #=======================================================================
        # <dotted as names> ::= <dotted as name> <dotted as names'>
        #=======================================================================
        if self._dotted_as_name():
            return self._dotted_as_names1() ## (notice: always returns True)
        else:
            return False

    #-------------------------------------------------------------------------
    def _dotted_as_names1(self) -> bool:
        #=======================================================================
        # <dotted as names'> ::= ',' <dotted as name> <dotted as names'>
        #                     |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._dotted_as_name():
                self._append_error( FESyntaxErrors.DOTTED_AS )
        return True

    #-------------------------------------------------------------------------
    def _dotted_name(self) -> bool:
        #=======================================================================
        # <dotted name> ::= <identifier> <dotted name'>
        #=======================================================================
        if self._identifier():
            return self._dotted_name1() ## (notice: always returns True)
        else:
            return False

    #-------------------------------------------------------------------------
    def _dotted_name1(self) -> bool:
        #=======================================================================
        # <dotted name'> ::= '.' <identifier> <dotted name'>
        #                 | EPS
        #=======================================================================
        while self._current.is_DOT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self.identifier():
                self._append_error( FESyntaxErrors.DOTTED_IDENT )
        return True

    #-------------------------------------------------------------------------
    def _ellipsis(self) -> bool:
        #=======================================================================
        # <ellipsis> ::= '...'
        #=======================================================================
        if self._current.is_ELLIPSIS():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _embed_statement(self) -> bool:
        #=======================================================================
        # <embed statement> ::= 'embed' <language> <embed statement'>
        #=======================================================================
        if self._current.is_EMBED():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._language():
                self._append_error( FESyntaxErrors.EMBEDDED_LANGUAGE )
            if not self._embed_statement1():
                self._append_error( FESyntaxErrors.EMBEDDED_LANGUAGE_CODE )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _embed_statement1(self) -> bool:
        #=======================================================================
        # <embed statement'> ::= <dotted name> <simple statement end>
        #                     |  <embedded language code>
        #=======================================================================
        if self._dotted_name():
            if self._simple_statement_end():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.STATEMENT_END )
            return True
        elif self._embedded_language_code():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _embedded_language_code(self) -> bool:
        #===================================================================
        # <embedded language code>    ::= '{{' <embedded language code'>
        # <embedded language code'>   ::= <any embedded code char> <embeded language code'>
        #                              |  '}' <embedded language code">
        # <embedded language code">   ::= <any embedded code char> <embeded language code'>
        #                              |  '}' <embedded language exit>
        #===================================================================
        if self._current.is_EMBED_CODE():  ## (notice: previously scanned by the Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            return self._embedded_language_exit()
        elif self._current.is_UNEXPECTED():
            self._append_syntaxic_node()
            self._next_token_node()
            self._append_error( FESyntaxErrors.EMBEDDED_CODE_END )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _embedded_language_exit(self) -> bool:
        #=======================================================================
        # <embedded language exit> ::= 'exit'
        #                           |  EPS
        #=======================================================================
        if self._current.is_EXIT():
            self._append_syntaxic_node()
            self._next_token_node()
        return True

    #-------------------------------------------------------------------------
    def _empty_statement(self) -> bool:
        #=======================================================================
        # <empty statement> ::= <comment>
        #                    |  <NEWLINE>
        #=======================================================================
        if self._current.is_COMMENT() or self._current.is_COMMENT_ML(): ## (notice: previously scanned by Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._new_line():
                self._append_error( FESyntaxErrors.COMMENT_NL )
            return True
        elif self._current.is_NL():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _enclosure(self) -> bool:
        #=======================================================================
        # <enclosure> ::= <bracket form>
        #              |  <parenthesis form>
        #=======================================================================
        return self._bracket_form() or self._parenthesis_form()

    #-------------------------------------------------------------------------
    def _end_line(self) -> bool:
        #=======================================================================
        # <end line> ::= <NEWLINE>
        #             |  <ENDOFFILE>
        #=======================================================================
        if self._current.is_NL() or self._current.is_EOF():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _end_of_file(self) -> bool:
        #=======================================================================
        # <ENDOFFILE> ::= u0x00
        #=======================================================================
        if self._current.is_EOF():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _ensure_statement(self) -> bool:
        #=======================================================================
        # <ensure statement> ::= 'ensure' <expression> <ensure statement'>
        #=======================================================================
        if self._current.is_ENSURE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.ENSURE_EXPR )
            self._ensure_statement1() ##(notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _ensure_statement1(self) -> bool:
        #=======================================================================
        # <ensure statement'> ::= ',' <expression>
        #                      |  EPS
        #=======================================================================
        if self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.ENSURE_COMMA_EXPR )
        return True

    #-------------------------------------------------------------------------
    def _enum_definition(self) -> bool:
        #=======================================================================
        # <enum definition> ::= <enum type> <identifier> '{' <enum list> '}'
        #=======================================================================
        if self._current.is_ENUM():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_IDENT():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.ENUM_IDENT )
            if self._current.is_BRACKETOP:
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.ENUM_BRACKET_OP )
            if not self._enum_list():
                self._append_error( FESyntaxErrors.ENUM_LIST )
            if self._current.is_BRACKETCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.ENUM_BRACKET_CL )

    #-------------------------------------------------------------------------
    def _enum_item(self) -> bool:
        #=======================================================================
        # <enum item> ::= <identifier> <enum item'>
        #=======================================================================
        if self._current.is_IDENT():
            self._append_syntaxic_node()
            self._next_token_node()
            return self._enum_item1()
        else:
            return False

    #-------------------------------------------------------------------------
    def _enum_item1(self) -> bool:
        #=======================================================================
        # <enum item'> ::= '=' <expression>
        #               |  EPS
        #=======================================================================
        if self._current.is_ASSIGN():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.ENUM_EXPR )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _enum_list(self) -> bool:
        #=======================================================================
        # <enum list>  ::= <enum item> <enum list'>
        # <enum list'> ::= ',' <enum item> <enum list'>
        #               |  EPS
        #=======================================================================
        if self._enum_item():
            self._append_syntaxic_node()
            self._next_token_node()
            while self._current.is_COMMA():
                self._append_syntaxic_node()
                self._next_token_node()
                if self._enum_item():
                    self._append_syntaxic_node()
                    self._next_token_node()
                else:
                    self._append_error( FESyntaxErrors.ENUM_LIST_ITEM )
            return True
        else:
            return False                

    #-------------------------------------------------------------------------
    def _enum_type(self) -> bool:
        #=======================================================================
        # <enum type> ::= 'enum'
        #=======================================================================
        if self._current.is_ENUM():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _exclude_statement(self) -> bool:
        #=======================================================================
        # <exclude statement> ::= 'exclude' <languages> '{{' <statements list> '}}'        
        #=======================================================================
        if self._current.is_EXCLUDE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._languages():
                self._append_error( FESyntaxErrors.EXCLUDE_LANGS )
            if self._current.is_EMBED_CODE():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.EXCLUDE_EMBED )
            return True
        else:
            return False            

    #-------------------------------------------------------------------------
    def _expr_list(self) -> bool:
        #=======================================================================
        # <expr list> ::= <expression> <expr list'>
        #=======================================================================
        return self._expression() and self._expr_list1()

    #-------------------------------------------------------------------------
    def _expr_list1(self) -> bool:
        #=======================================================================
        # <expr list'> ::= ',' <expression> <expr list'>
        #               |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.LIST_COMMA_EXPR )
        return True

    #-------------------------------------------------------------------------
    def _expression(self) -> bool:
        #=======================================================================
        # <expression> ::= <condition>
        #               |  <unnamed func>
        #=======================================================================
        if self._condition():
            return True
        elif self._unnamed_func():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _factor(self) -> bool:
        #=======================================================================
        # <factor> ::= <atom element> <factor'>
        #=======================================================================
        if self._atom_element():
            self._factor1()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _factor1(self) -> bool:
        #=======================================================================
        # <factor'> ::= '**' <template args> <unary expr>
        #            |  '^^' <template args> <unary expr>
        #            |  EPS
        #=======================================================================
        if self._current.is_POWER():
            self._append_syntaxic_node()
            self._next_token_node()
            self._template_args()
            if not self._unary_expr():
                self._append_error( FESyntaxErrors.POWER_EXPR )
        return True
        
    #-------------------------------------------------------------------------
    def _false(self) -> bool:
        #=======================================================================
        # <FALSE> ::= 'False'
        #          |  'false'
        #=======================================================================
        if self._current.is_FALSE():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _file_endianness(self) -> bool:
        #=======================================================================
        # <file endianness> ::= '<' <expression> <file endianness'>
        #                    |  '>' <expression> <file endianness'>
        #=======================================================================
        if self._current.is_LT() or self._current.is_GT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.FILE_ENDIAN_EXPR )
            self._file_endianness1()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _file_endianness1(self) -> bool:
        #=======================================================================
        # <file endianness'> ::= '<<' <expression> <file endianness'>
        #                     |  '>>' <expression> <file endianness'>
        #                     |  '>>>' <expression> <file endianness'>
        #                     |  EPS
        #=======================================================================
        while self._current.is_SHIFTL() or \
                self._current.is_SHIFTR() or \
                self._current.is_SHIFT0R():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.FILE_STREAM_EXPR )
        return True
    
    #-------------------------------------------------------------------------
    def _file_flushing(self) -> bool:
        #=======================================================================
        # <file flushing> ::= '!' <dotted name> <file flushing'>
        #=======================================================================
        if self._current.is_EXCL():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._dotted_name():
                self._append_error( FESyntaxErrors.FILE_FLUSH_IDENT )
            self._file_flushing1();
            return True
        else:
            return False
        
    #-------------------------------------------------------------------------
    def _file_flushing1(self) -> bool:
        #=======================================================================
        # <file flushing'> ::= '(' <expression> <file flushing''> ')'
        #                   |  '[' <expression> ']' '=' <expression>
        #                   |  '>>' <expression>
        #                   |  '>>>' <expression>
        #                   |  EPS
        #=======================================================================
        if self._current.is_PAROP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.FILE_FLUSH_FUNC_CALL )
            self._file_flushing2()
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FILE_FLUSH_FUNC_END )
        elif self._current.is_BRACKETOP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.FILE_FLUSH_INDEX )
            if self._current.is_BRACKETCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FILE_FLUSH_INDEX_END )
            if self._current.is_ASSIGN():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FILE_FLUSH_INDEX_ASSIGN )
            if not self._expression():
                self._append_error( FESyntaxErrors.FILE_FLUSH_INDEX_EXPR )
        elif self._current.is_SHIFTR():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.FILE_FLUSH_STREAM_EXPR )
        elif self._current.is_SHIFT0R():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.FILE_FLUSH_APPEND_EXPR )
        return True
    
    #-------------------------------------------------------------------------
    def file_flushing2(self) -> bool:
        #=======================================================================
        # <file flushing''> ::= ',' <expression> <file flushing'>
        #                    |  EPS
        #=======================================================================
        if self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.FILE_FLUSH_FUNC_CALL )
            return self._file_flushing1()
        return True

    #-------------------------------------------------------------------------
    def _file_type(self) -> bool:
        #=======================================================================
        # <file type> ::= 'file' <contained type>
        #=======================================================================
        if self._current.is_FILE():
            self._append_syntaxic_node()
            self._next_token_node()
            self._contained_type() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _float_number(self) -> bool:
        if self._current.is_FLOAT():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _flow_statement(self) -> bool:
        #=======================================================================
        # <flow statement> ::= 'break'
        #                   |  'continue'
        #                   |  <raise statement>
        #                   |  <return statement>
        #=======================================================================
        if self._current.is_BREAK() or self._current.is_CONTINUE():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        elif self._raise_statement():
            return True
        elif self._return_statement():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _for_comprehension(self) -> bool:
        #=======================================================================
        # <for comprehension> ::= 'for' '(' <target list> 'in' <or test> <iter comprehension> ')'
        #=======================================================================
        if self._current.is_FOR():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FOR_PAROP )
            if not self._target_list():
                self._append_error( FESyntaxErrors.FOR_COMPR_TARGETS)
            if self._current.is_IN():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FOR_COMPR_IN )
            if not self._or_test():
                self._append_error( FESyntaxErrors.FOR_COMPR_CONDITION )
            self._iter_comprehension()
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FOR_PARCL )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _for_statement(self) -> bool:
        #=======================================================================
        # <for statement> ::= 'for' '(' <target list> 'in' <expr list> ')' <statements block> <for statement'>
        #=======================================================================
        if self._current.is_FOR():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FOR_PAROP )
            if not self._target_list():
                self._append_error( FESyntaxErrors.FOR_TARGETS )
            if self._current.is_IN():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FOR_IN )
            if not self._expr_list():
                self._append_error( FESyntaxErrors.FOR_EXPR)
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FOR_PARCL )
            if not self._statements_block():
                self._append_error( FESyntaxErrors.FOR_BODY )
            self._for_statement1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _for_statement1(self) -> bool:
        #=======================================================================
        # <for statement'> ::= 'otherwise' <statements block>
        #                   |  EPS
        #=======================================================================
        if self._current.is_OTHERWISE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._statements_block():
                self._append_error( FESyntaxErrors.FOR_ELSE_BODY )
        return True
        
    #-------------------------------------------------------------------------
    def _forever_statement(self) -> bool:
        #=======================================================================
        # <forever statement> ::= 'forever' '(' ')' <statements block>
        #=======================================================================
        if self._current.is_FOREVER():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FOREVER_PAROP )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FOREVER_PARCL )
            if not self._statements_block():
                self._append_error( FESyntaxErrors.FOREVER_BODY )
            return True
        else:
            return False
        
    #-------------------------------------------------------------------------
    def _forward_decl(self) -> bool:
        #=======================================================================
        # <forward decl> ::= <forward> <forward decl'>
        #=======================================================================
        if self._current.is_FORWARD():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._forward_decl1():
                self._append_error( FESyntaxErrors.FORWARD_DECL )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _forward_decl1(self) -> bool:
        #=======================================================================
        # <forward decl'> ::= <static qualifier> <forward decl''>
        #                  |  <forward decl''>
        #                  |  <fwd class decl>
        #=======================================================================
        if self._current.is_STATIC():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._forward_decl2():
                self._append_error( FESyntaxErrors.FORWARD_STATIC_DECL )
            return True
        else:
            return self._forward_decl2() or self._fwd_class_decl()

    #-------------------------------------------------------------------------
    def _forward_decl2(self) -> bool:
        #=======================================================================
        # <forward decl''> ::= <volatile qualifier> <type> <identifier>
        #                   |  <fwd type decl>
        #                   |  <forward decl'''>
        #=======================================================================
        if self._current.is_VOLATILE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._type():
                self._append_error( FESyntaxErrors.VOLATILE_TYPE )
            return True
        else:
            return self._fwd_type_decl() or self._forward_decl3()

    #-------------------------------------------------------------------------
    def _forward_decl3(self) -> bool:
        #=======================================================================
        # <forward decl'''> ::= <TYPE'> <forward decl''''>
        #                    |  <identifier> <fwd decl constructor>
        #=======================================================================
        if self._TYPE1():
            if not self._forward_decl4():
                self._append_error( FESyntaxErrors.FORWARD_TYPE_DECL )
            return True
        elif self._identifier():
            if not self._fwd_decl_constructor():
                self._append_error( FESyntaxErrors.FORWARD_DECL_CONSTR )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _forward_decl4(self) -> bool:
        #=======================================================================
        # <forward decl''''> ::= <identifier> <forward decl'''''>
        #                     |  <operator declaration>
        #=======================================================================
        if self._identifier():
            if not self._forward_decl5():
                self._append_error( FESyntaxErrors.FORWARD_FUNC_VAR_DECL )
            return True
        else:
            return self._operator_declaration()

    #-------------------------------------------------------------------------
    def _forward_decl5(self) -> bool:
        #=======================================================================
        # <forward decl'''''> ::= <function declaration>
        #                      |  <fwd var decl>
        #=======================================================================
        return self._function_declaration() or self._fwd_var_decl()

    #-------------------------------------------------------------------------
    def _function_args_declaration(self) -> bool:
        #=======================================================================
        # <function args declaration> ::= '(' <typed args list> ')'
        #=======================================================================
        if self._current.is_PAROP():
            self._append_syntaxic_node()
            self._next_token_node()
            self._typed_args_list()
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.FUNCTION_ARGS_END )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _function_call(self) -> bool:
        #=======================================================================
        # <function call> ::= <template args> '(' <function call args> ')'
        #=======================================================================
        if self._template_args():
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
                self._function_call_args()
                if self._current.is_PARCL():
                    self._append_syntaxic_node()
                    self._next_token_node()
                else:
                    self._append_error( FESyntaxErrors.FUNCTION_CALL_END )
            else:
                self._append_error( FESyntaxErrors.FUNCTION_CALL_BEGIN )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _function_call_args(self) -> bool:
        #=======================================================================
        # <function call args> ::= <expression> <function call args'>
        #                       |  EPS
        #=======================================================================
        if self._expression():
            return self._function_call_args1()
        else:
            return True

    #-------------------------------------------------------------------------
    def _function_call_args1(self) -> bool:
        #=======================================================================
        # <function call args'> ::= ',' <function call args">
        #                        |  <for comprehension>
        #                        |  EPS
        #=======================================================================
        if self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._function_call_args2():
                self._append_error( FESyntaxErrors.FUNCTION_ARGS_LIST )
            return True
        elif self._for_comprehension():
            return True
        else:
            return True        

    #-------------------------------------------------------------------------
    def _function_call_args2(self) -> bool:
        #=======================================================================
        # <function call args"> ::= <expression> <function call args'>
        #                        |  <ellipsis> <identifier>
        #=======================================================================
        if self._expression():
            self._function_call_args1()
            return True
        elif self._ellipsis():
            if not self._identifier():
                self._append_error( FESyntaxErrors.ELLIPSIS_IDENT )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _function_declaration(self) -> bool:
        #=======================================================================
        # <function declaration> ::= <template def> <function declaration'>
        #                         |  <function declaration'>
        #=======================================================================
        if self._template_def():
            return self._function_declaration1()
        else:
            return self._function_declaration1()

    #-------------------------------------------------------------------------
    def _function_declaration1(self) -> bool:
        #=======================================================================
        # <function declaration'> ::= <function args declaration>
        #=======================================================================
        return self._function_args_declaration()

    #-------------------------------------------------------------------------
    def _function_definition(self) -> bool:
        #=======================================================================
        # <function definition> ::= <template def> <function definition'>
        #                        |  <function definition'>
        #=======================================================================
        if self._template_def():
            return self._function_definition1()
        else:
            return self._function_definition1()

    #-------------------------------------------------------------------------
    def _function_definition1(self) -> bool:
        #=======================================================================
        # <function definition'> ::= <function args declaration> <function definition"> <statements block>
        #=======================================================================
        if not self._function_args_declaration():
            self._append_error( FESyntaxErrors.FUNCTION_ARGS )
        self._function_definition2()
        if not self._statements_block():
            self._append_error( FESyntaxErrors.FUNCTION_BODY )
        return True 

    #-------------------------------------------------------------------------
    def _function_definition2(self) -> bool:
        #=======================================================================
        # <function definition"> ::= 'exclude' <languages> | EPS
        #=======================================================================
        if self._current.is_EXCLUDE():
            if not self._languages():
                self._append_error( FESyntaxErrors.LANGUAGES_LIST )
        return True

    #-------------------------------------------------------------------------
    def _fwd_class_decl(self) -> bool:
        #=======================================================================
        # <fwd class decl>  ::= 'class' <identifier> <template def> <fwd class decl'>
        # <fwd class decl'> ::= <inheritance>
        #                    |  EPS
        #=======================================================================
        if self._current.is_CLASS():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.CLASS_NAME )
            self._template_def()
            return self._inheritance()
        else:
            return False

    #-------------------------------------------------------------------------
    def _fwd_decl_constructor(self) -> bool:
        #=======================================================================
        # <fwd decl constructor> ::= <dotted name'> <forward decl''''>
        #                         |  <function declaration'>
        #=======================================================================
        if self._dotted_name1():
            if not self._forward_decl4():
                self._append_error( FESyntaxErrors.FORWARD_DECL_FUNC_VAR_OP )
            return True
        else:
            return self._function_declaration1()

    #-------------------------------------------------------------------------
    def _fwd_var_decl(self) -> bool:
        #=======================================================================
        # <fwd var decl> ::= ',' <identifier> <fwd var decl>
        #                 |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.FORWARD_VARS_LIST )
        return True            

    #-------------------------------------------------------------------------
    def _generic_scalar_type(self) -> bool:
        #=======================================================================
        # <generic scalar type> ::= '_float_'              
        #                        |  '_int_'              
        #                        |  '_numeric_'              
        #                        |  '_uint_'              
        #=======================================================================
        if self._current.is_GENRIC_SCALAR_TYPE(): ## (notice: previously scanned by Front-End Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _identifier(self) -> bool:
        #=======================================================================
        # <identifier>  ::= '_' <identifier'>
        #                |  <alpha char> <identifier'>
        # <identifier'> ::= <alpha num char> <identifier'>
        #                |  '_' <identifier'>
        #                |  EPS
        #=======================================================================
        if self._current.is_IDENT():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            self._append_error( 'missing or incorrect identifier' )
            return True

    #-------------------------------------------------------------------------
    def _identifiers_list(self) -> bool:
        #=======================================================================
        # <identifiers list> ::= <dotted name> <identifiers list'>
        #=======================================================================
        if self._current._dotted_name():
            return self._identifiers_list1() ## (notice: always returns True)
        else:
            return False

    #-------------------------------------------------------------------------
    def _identifiers_list1(self) -> bool:
        #=======================================================================
        # <identifiers list'> ::= ',' <dotted name> <identifiers list'>
        #                      |    EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._dotted_name():
                self._append_error( FESyntaxErrors.LIST_COMMA_IDENT )
        return True

    #-------------------------------------------------------------------------
    def _if_comprehension(self) -> bool:
        #=======================================================================
        # <if comprehension> ::= 'if' '(' <condition or unnamed func> ')' <iter comprehension>
        #=======================================================================
        if self._current.is_IF():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.IF_CONDITION_BEGIN )
            if not self._condition_or_unnamed_func():
                self._append_error( FESyntaxErrors.IF_COMPR_COND )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.IF_CONDITION_END )
            self._iter_comprehension()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _if_statement(self) -> bool:
        #=======================================================================
        # <if statement> ::= 'if' '(' <expression> ')' <statements block> <if statement'>
        #=======================================================================
        if self._current.is_IF():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.IF_CONDITION_BEGIN )
            if not self._expression():
                self._append_error( FESyntaxErrors.IF_COND )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.IF_CONDITION_END )
            if not self._statements_block():
                self._append_error( FESyntaxErrors.IF_BODY )
            self._if_statement1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _if_statement1(self) -> bool:
        #=======================================================================
        # <if statement'> ::= 'elseif' '(' <expression> ')' <statements block> <if statement'>
        #                  |  'elif' '(' <expression> ')' <statements block> <if statement'>
        #                  |  'elsif' '(' <expression> ')' <statements block> <if statement'>
        #                  |  'else' <statements block>
        #                  |  'otherwise' <statements block>
        #                  |  EPS
        #=======================================================================
        while self._current.is_ELIF():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.ELIF_CONDITION_BEGIN )
            if not self._expression():
                self._append_error( FESyntaxErrors.ELIF_COND )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.ELIF_CONDITION_END )
            if not self._statements_block():
                self._append_error( FESyntaxErrors.ELIF_BODY )
        if self._current.is_ELSE() or self._current.is_OTHERWISE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._statements_block():
                self._append_error( FESyntaxErrors.ELSE_BODY if self._current.is_ELSE()
                                                             else FESyntaxErrors.OTHERWISE_BODY )
        return True

    #-------------------------------------------------------------------------
    def _import_as_name(self) -> bool:
        #=======================================================================
        # <import as name> ::= <identifier> <import as name'>
        #=======================================================================
        if self._identifier():
            return self._import_as_name1() ## (notice: always returns True)
        else:
            return False

    #-------------------------------------------------------------------------
    def _import_as_name1(self) -> bool:
        #=======================================================================
        # <import as name'> ::= 'as' <identifier>
        #                    |  EPS
        #=======================================================================
        if self._current.is_AS():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.AS_IDENT )
        return True

    #-------------------------------------------------------------------------
    def _import_as_names(self) -> bool:
        #=======================================================================
        # <import as names> ::= <import as name> <import as names'>
        #=======================================================================
        if self._import_as_name():
            self._import_as_names1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _import_as_names1(self) -> bool:
        #=======================================================================
        # <import as names'> ::= ',' <import as name> <import as names'>
        #                     |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._import_as_name():
                self._append_error( FESyntaxErrors.IMPORT_IDENT )
        return True

    #-------------------------------------------------------------------------
    def _import_but(self) -> bool:
        #===============================================================================
        # <import but> ::= 'but' <identifier> <import but'>
        #               |  EPS
        #===============================================================================
        if self._current.is_BUT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.IMPORT_BUT_IDENT )
            return self._import_but1()
        return True

    #-------------------------------------------------------------------------
    def _import_but1(self) -> bool:
        #===============================================================================
        # <import but'> ::= ',' <identifier> <import but'>
        #                |  EPS
        #===============================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.IMPORT_BUT_COMMA_IDENT )
        return True

    #-------------------------------------------------------------------------
    def _import_from(self) -> bool:
        #=======================================================================
        # <import from> ::= 'from' <import from'>
        #=======================================================================
        if self._current.is_FROM():
            self._append_syntaxic_node()
            self._next_token_node()
            self._import_from1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _import_from1(self) -> bool:
        #=======================================================================
        # <import from'> ::= '.' <import from'>
        #                 |  <import from''>
        #=======================================================================
        while self._current.is_DOT():
            self._append_syntaxic_node()
            self._next_token_node()
        return self._import_from2() ## (notice: always returns True)

    #-------------------------------------------------------------------------
    def _import_from2(self) -> bool:
        #=======================================================================
        # <import from''> ::= <dotted name> 'import' <import from'''>
        #=======================================================================
        if not self._dotted_name():
            self._append_error( FESyntaxErrors.FROM_IDENT_IMPORT )
        if self._current.is_IMPORT():
            self._append_syntaxic_node()
            self._next_token_node()
        else:
            self._append_error( FESyntaxErrors.FROM_IMPORT )
        if not self._import_from3():
            self._append_error( FESyntaxErrors.FROM_IMPORT_IDENT )
        return True

    #-------------------------------------------------------------------------
    def _import_from3(self) -> bool:
        #=======================================================================
        # <import from'''> ::= 'all' <import but>
        #                   |  '(' <import as names> ')'
        #                   |  <import as names>
        #=======================================================================
        if self._current.is_ALL():
            self._append_syntaxic_node()
            self._next_token_node()
            return self._import_but()
        elif self._current.is_PAROP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._import_as_names():
                self._append_error( FESyntaxErrors.FROM_IMPORT_LIST )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.UNPAIRED_PAROP )
            return True
        elif self._import_as_names():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _import_name(self) -> bool:
        #=======================================================================
        # <import name> ::= 'import' <dotted as names>
        #=======================================================================
        if self._current.is_IMPORT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._dotted_as_names():
                self._append_error( FESyntaxErrors.IMPORT_MODULE )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _import_statement(self) -> bool:
        #=======================================================================
        # <import statement> ::= <import name>
        #                     |  <import from>
        #=======================================================================
        return self._import_name() or self._import_from()

    #-------------------------------------------------------------------------
    def _incr_or_decr(self) -> bool:
        #=======================================================================
        # <incr or decr> ::= '--'  |  '++'  |  EPS
        #=======================================================================
        if self._current.is_INCR() or self._current.is_DECR():
            self._append_syntaxic_node()
            self._next_token_node()
        return True

    #-------------------------------------------------------------------------
    def _inheritance(self) -> bool:
        #=======================================================================
        # <inheritance> ::= ':' <inheritance item> <inheritance'>
        #                |  EPS
        #=======================================================================
        if self._current.is_COLON():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._inheritance_item():
                self._append_error( FESyntaxErrors.INHERITANCE_CLASS )
            self._inheritance1()
        return True
        
    #-------------------------------------------------------------------------
    def _inheritance1(self) -> bool:
        #=======================================================================
        # <inheritance'> ::= ',' <inheritence item> <inheritance'>
        #                 |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._inheritance_item():
                self._append_error( FESyntaxErrors.INHERITANCE_CLASS )
        return True

    #-------------------------------------------------------------------------
    def _inheritance_item(self) -> bool:
        #=======================================================================
        # <inheritance item> ::= <access qualifier> <inheritance item'>
        #                     |  <inheritance item'>
        #=======================================================================
        if self._access_qualifier():
            return self._inheritance_item1()
        else:
            return self._inheritance_item1()

    #-------------------------------------------------------------------------
    def _inheritance_item1(self) -> bool:
        #=======================================================================
        # <inheritance item'> ::= <dotted name> <template args>
        #=======================================================================
        if self._dotted_name():
            self._template_args()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _integer_number(self) -> bool:
        #=======================================================================
        # <integer number> ::= '1'...'9' <integer number'>
        #                   |  <octal hexa binary number>
        #=======================================================================
        if self._current.is_INTEGER(): ## (notice: previously scanned by Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False
        
    #-------------------------------------------------------------------------
    def _is_instance_of(self) -> bool:
        #=======================================================================
        # <is instance of> ::= '->' <dotted name>
        #=======================================================================
        if self._current.is_ISOF():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._dotted_name():
                self._append_error( FESyntaxErrors.INSTANCE_OF )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _is_operator(self) -> bool:
        #=======================================================================
        # <is operator> ::= 'is' <is operator'>
        #=======================================================================
        if self._current.is_IS():
            self._append_syntaxic_node()
            self._next_token_node()
            return self._is_operator1()
        else:
            return False

    #-------------------------------------------------------------------------
    def _is_operator1(self) -> bool:
        #=======================================================================
        # <is operator'> ::= 'not'
        #                 |  EPS
        #=======================================================================
        if self._current.is_NOT():
            self._append_syntaxic_node()
            self._next_token_node()
        return True

    #-------------------------------------------------------------------------
    def _iter_comprehension(self) -> bool:
        #=======================================================================
        # <iter comprehension> ::= <for comprehension>
        #                       |  <if comprehension>
        #                       |  EPS
        #=======================================================================
        if self._for_comprehension():
            return True
        elif self._if_comprehension():
            return True
        else:
            return True

    #-------------------------------------------------------------------------
    def _language(self) -> bool:
        #=======================================================================
        # <language> ::= 'cpp' | 'java' | 'python' | 'py' | 'javascript' | 'm6809'
        #=======================================================================
        if self._current.is_LANGUAGE(): ## (notice: previously scanned by the Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _list_form(self) -> bool:
        #=======================================================================
        # <list form>    ::= '[' <expression> <list or comprehension> ']'
        #=======================================================================
        if self._current.is_BRACKETOP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.LIST_EXPR )
            self._list_or_comprehension()
            if self._current.is_BRACKETCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.LIST_END )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _list_or_comprehension(self) -> bool:
        #=======================================================================
        # <list or comprehension> ::= <expr list'>
        #                          |  <for comprehension>
        #                          |  EPS
        #=======================================================================
        if self._expr_list1() or self._for_comprehension():
            return True
        else:
            return True

    #-------------------------------------------------------------------------
    def _list_or_map_form(self) -> bool:
        #=======================================================================
        # <list or map form> ::= <list form>
        #                      | <map form>
        #=======================================================================
        return self._list_form() or self._map_form()

    #-------------------------------------------------------------------------
    def _list_type(self) -> bool:
        #=======================================================================
        # <list type> ::= "list" <contained type>
        #=======================================================================
        if self._current.is_LIST():
            self._append_syntaxic_node()
            self._next_token_node()
            self._contained_type() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _list_type1(self) -> bool:
        #=======================================================================
        # <list type'>    ::= <declared contained type>
        #                  |    EPS
        #=======================================================================
        if self._declared_contained_type():
            return True
        else:
            return True

    #-------------------------------------------------------------------------
    def _map_form(self) -> bool:
        #=======================================================================
        # <map form> ::= ':' <expression> <map list or comprehension>
        #=======================================================================
        if self._current.is_COLON():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.MAP_EXPR )
            if not self._map_list_or_comprehension():
                self._append_error( FESyntaxErrors.MAP_LIST_COMPR )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _map_item(self) -> bool:
        #=======================================================================
        # <map item> ::= <expression> ':' <expression>
        #=======================================================================
        if self._expression():
            if self._current.is_COLON():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.MAP_ITEM_SEP )
            if not self._expression():
                self._append_error( FESyntaxErrors.MAP_EXPR )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _map_list(self) -> bool:
        #=======================================================================
        # <map list> ::= ',' <map item> <map list>
        #             |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._map_item():
                self._append_error( FESyntaxErrors.MAP_LIST_ITEM )
        return True

    #-------------------------------------------------------------------------
    def _map_list_or_comprehension(self) -> bool:
        #=======================================================================
        # <map list or comprehension> ::= ',' <map item> <map list>
        #                              |  <for comprehension>
        #=======================================================================
        if self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._map_item():
                self._append_error( FESyntaxErrors.MAP_LIST_ITEM )
            self._map_list()
            return True
        else:
            return self._for_comprehension()

    #-------------------------------------------------------------------------
    def _map_contained_types(self) -> bool:
        #=======================================================================
        # <map contained types> ::= '<' <TYPE> <map contained types'>
        #                        |  EPS
        #=======================================================================
        if self._current.is_LT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._TYPE():
                self._append_error( FESyntaxErrors.MAP_CONTAINED_TYPE )
            return self._map_contained_types_1()
        else:
            return False

    #-------------------------------------------------------------------------
    def _map_contained_types_1(self) -> bool:
        #=======================================================================
        # <map contained types'> ::= ',' <TYPE> '>'
        #                         |  '>'
        #=======================================================================
        if self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._TYPE():
                self._append_error( FESyntaxErrors.MAP_CONTAINED_VALUE_TYPE )
        if self._current.is_GT():
            self._append_syntaxic_node()
            self._next_token_node()
        else:
            self._append_error( FESyntaxErrors.MAP_CONTAINED_TYPE_END )
        return True

    #-------------------------------------------------------------------------
    def _map_type(self) -> bool:
        #=======================================================================
        # <<map type> ::= "map" <map contained types>
        #=======================================================================
        if self._current.is_MAP():
            self._append_syntaxic_node()
            self._next_token_node()
            self._map_contained_types() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _me(self) -> bool:
        #=======================================================================
        # <ME> ::= 'me'
        #=======================================================================
        if self._current.is_ME():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _memory_address(self) -> bool:
        #=======================================================================
        # <memory address> ::= '@' <integer number>
        #                   |  EPS
        #=======================================================================
        if self._current.is_AROBASE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._integer_number():
                self._append_error( FESyntaxErrors.VOLATILE_MEM_ADDR )
        return True

    #-------------------------------------------------------------------------
    def _method_or_operator_definition(self) -> bool:
        #=======================================================================
        # <method or operator definition> ::= <returned type> <method or operator definition'>
        #=======================================================================
        if self._returned_type():
            if not self._method_or_operator_definition1():
                self._append_error( FESyntaxErrors.METHOD_OPERATOR )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _method_or_operator_definition1(self) -> bool:
        #=======================================================================
        # <method or operator definition'> ::= <operator definition>
        #                                   |  <identifier> <function definition>
        #=======================================================================
        if self._operator_definition():
            return True
        elif self._current.is_IDENT():
            self._append_syntaxic_node()
            self._next_token_node()
            self._function_definition() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _new_line(self) -> bool:
        if self._current.is_NL():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _none(self) -> bool:
        #=======================================================================
        # <NONE> ::= "None"
        #         |  "none"
        #=======================================================================
        if self._current.is_NONE():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _nop_statement(self) -> bool:
        #=======================================================================
        # <nop statement> ::= 'nop'
        #                  |  'pass'
        #=======================================================================
        if self._current.is_NOP():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _not_test(self) -> bool:
        #=======================================================================
        # <not test> ::= 'not' <not test>
        #             |  <comparison>
        #=======================================================================
        if self._current.is_NOT():
            while self._current.is_NOT():
                self._append_syntaxic_node()
                self._next_token_node()
            if not self._comparison():
                self._append_error( FESyntaxErrors.NOT_COND )
            return True
        else:
            return self._comparison()

    #-------------------------------------------------------------------------
    def _operator(self) -> bool:
        #=======================================================================
        # <operator> ::= '<='  |  '=='  |  '!='  |  '>='
        #             |  '+'   |  '-'   |  '*'   |  '/'  |  '%'  |  '**'  |  '^^'
        #             |  '&'   |  '|'   |  '^'   |  '@'
        #             |  '@@'  |  '><'  |  '<>'  |  '::' |  '!!'
        #             |  '++'  |  '--'  |  '#'
        #             |  'in'
        #             |  <assign op>
        #             |  <cast op>
        #=======================================================================
        if isinstance( self._current, (ICTokenNode_LE      , ICTokenNode_EQ      ,
                                       ICTokenNode_NE      , ICTokenNode_GE      ,
                                       ICTokenNode_PLUS    , ICTokenNode_MINUS   ,
                                       ICTokenNode_MUL     , ICTokenNode_DIV     ,
                                       ICTokenNode_MOD     , ICTokenNode_POWER   ,
                                       ICTokenNode_BITAND  , ICTokenNode_BITOR   ,
                                       ICTokenNode_BITXOR  , ICTokenNode_AROBASE ,
                                       ICTokenNode_OP_2AROB, ICTokenNode_OP_GRLE ,
                                       ICTokenNode_OP_LEGR , ICTokenNode_OP_2COLN,
                                       ICTokenNode_OP_2EXCL, ICTokenNode_INCR    ,
                                       ICTokenNode_DECR    , ICTokenNode_HASH    ,
                                       ICTokenNode_IN                             ) ):
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        elif self._assign_op():
            return True
        elif self._cast_op():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _operator1(self) -> bool:
        #=======================================================================
        # <operator'> ::= '<' | '>' | '<<' | '<<<' | '>>' | '>>>' | '<=>'
        #=======================================================================
        if isinstance( self._current, (ICTokenNode_LT    , ICTokenNode_GT     ,
                                       ICTokenNode_SHIFTL, ICTokenNode_SHIFT0L,
                                       ICTokenNode_SHIFTR, ICTokenNode_SHIFT0R,
                                       ICTokenNode_LEG                         ) ):
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _operator_definition(self) -> bool:
        #=======================================================================
        # <operator definition> ::= 'operator' <operator definition'>
        #=======================================================================
        if self._current.is_OPERATOR():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._operator_definition1():
                self._append_error( FESyntaxErrors.OPERATOR_OP )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _operator_definition1(self) -> bool:
        #=======================================================================
        # <operator definition'> ::= <operator> <template def> <function args declaration> <statements block>
        #                         |  <operator'> <spaced template def> <function args declaration> <statements block>
        #                         |  <call operator> <template def> <statements block>
        #=======================================================================
        def _my_cont(check_args:bool) -> bool:
            if check_args and not self._function_args_declaration():
                self._append_error( FESyntaxErrors.OPERATOR_ARGS )
            if not self._statements_block():
                self._append_error( FESyntaxErrors.OPERATOR_BODY )
            return True

        if self._operator():
            self._template_def()
            return _my_cont( True )
        elif self._operator1():
            self._spaced_template_def()
            return _my_cont( True )
        elif self._call_operator():
            self._template_def()
            return _my_cont( False )
        else:
            return False

    #-------------------------------------------------------------------------
    def _or_test(self) -> bool:
        #=======================================================================
        # <or test> ::= <and test> <or test'>
        #=======================================================================
        return self._and_test() and self._or_test1()

    #-------------------------------------------------------------------------
    def _or_test1(self) -> bool:
        #=======================================================================
        # <or test'> ::= 'or' <and test>
        #             |  EPS
        #=======================================================================
        if self._current.is_OR():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._and_test():
                self._append_error( FESyntaxErrors.OR_TEST )
            return True
        else:
            return True

    #-------------------------------------------------------------------------
    def _parenthesis_form(self) -> bool:
        #=======================================================================
        # <parenthesis form> ::= '(' <expr list> ')'
        #=======================================================================
        if self._current.is_PAROP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expr_list():
                self._append_error( FESyntaxErrors.PARENTH_EXPR )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.UNPAIRED_PAROP )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _parse_code_file(self) -> tuple(FEICTree,int):
        #=======================================================================
        # <code file> ::=  <statements list> <ENDOFFILE>
        #=======================================================================
        # first, initializations
        self._out_syntax_ic = FEICTree()
        self._errors_count  = 0
        
        # then, let's parse the module file
        self._statements_list()
        if not self._end_of_file():
            self._append_error( FESyntaxErrors.END_OF_FILE )
        
        # finally, let's return the parsing results
        return (self._out_syntax_ic, self._errors_count)

    #-------------------------------------------------------------------------
    def _raise_statement(self) -> bool:
        #=======================================================================
        # <raise statement> ::= 'raise' <expression> <raise statement'>
        #=======================================================================
        if self._current.is_RAISE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.RAISE_EXPR )
            self._raise_statement1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _raise_statement1(self) -> bool:
        #=======================================================================
        # <raise statement'> ::= 'from' <expression>
        #                     |  EPS
        #=======================================================================
        if self._current.is_FROM():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.RAISE_FROM_EXPR )
            return True
        else:
            return True

    #-------------------------------------------------------------------------
    def _reference(self) -> bool:
        #=======================================================================
        # <reference> ::= '@' <dotted name>
        #=======================================================================
        if self._current.is_AROBASE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._dotted_name():
                self._append_error( FESyntaxErrors.REF_IDENT )
            return True
        else:
            return False


    #-------------------------------------------------------------------------
    def _repeat_statement(self) -> bool:
        #=======================================================================
        # <repeat statement> ::= 'repeat' <statements block> 'until' '(' <expression> ')' <simple statement end>
        #=======================================================================
        if self._current.is_REPEAT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._statements_block():
                self._append_error( FESyntaxErrors.REPEAT_BODY )
            if self._current.is_UNTIL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.REPEAT_UNTIL )
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.UNTIL_BEGIN )
            if not self._expression():
                self._append_error( FESyntaxErrors.UNTIL_EXPR )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.UNTIL_END )
            if self._simple_statement_end():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.UNTIL_STATEMENT_END )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _require_statement(self) -> bool:
        #=======================================================================
        # <require statement> ::= 'require' <expression> <require statement'>
        #=======================================================================
        if self._current.is_REQUIRE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.REQUIRE_EXPR )
            self._require_statement1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _require_statement1(self) -> bool:
        #=======================================================================
        # <require statement'> ::= ',' <expression>
        #                       |  EPS
        #=======================================================================
        if self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.REQUIRE_COMMA_EXPR )
        return True            

    #-------------------------------------------------------------------------
    def _return_statement(self) -> bool:
        #=======================================================================
        # <return statement> ::= 'ret' <return statement'>
        #                     |  'return' <return statement'>
        #=======================================================================
        if self._current.is_RETURN():
            self._append_syntaxic_node()
            self._next_token_node()
            self._return_statement1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _return_statement1(self) -> bool:
        #=======================================================================
        # <return statement'> ::= <expr list>
        #                      |  EPS
        #=======================================================================
        self._expr_list()
        return True

    #-------------------------------------------------------------------------
    def _returned_type(self) -> bool:
        #=======================================================================
        # <returned type> ::= <TYPE>
        #                  |  EPS
        #=======================================================================
        if self._TYPE():
            return True
        else:
            return True

    #-------------------------------------------------------------------------
    def _scalar(self) -> bool:
        #=======================================================================
        # <scalar> ::= <decimal number>
        #           |  <octal hexa binary number>
        #=======================================================================
        if self._current.is_INTEGER() or self._current.is_FLOAT(): ## (notice: previously scanned by Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _scalar_type(self) -> bool:
        #=======================================================================
        # <scalar type> ::= <scalar type'>  |  <generic scalar type>
        #=======================================================================
        return self._scalar_type1() or self._generic_scalar_type()

    #-------------------------------------------------------------------------
    def _scalar_type1(self) -> bool:
        #=======================================================================
        # <scalar type'>  ::= "bool"
        #                  |  "char"
        #                  |  "char16"
        #                  |  "float32"
        #                  |  "float64"
        #                  |  "int8"
        #                  |  "int16"
        #                  |  "int32"
        #                  |  "int64"
        #                  |  "slice"
        #                  |  "str"
        #                  |  "str16"
        #                  |  "uint8"
        #                  |  "uint16"
        #                  |  "uint32"
        #                  |  "uint64"
        #                  |  "_float_"
        #                  |  "_int_"
        #                  |  "_numeric_"
        #                  |  "_uint_"
        #=======================================================================
        if self._current.is_SCALAR_TYPE(): ## (notice: previously scanned by Front-End Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _scalar_type_or_dotted_name(self) -> bool:
        #=======================================================================
        # <scalar type or dotted name> ::= <scalar type>
        #                               |  <dotted name>
        #=======================================================================
        return self._scalar_type() or self._dotted_name()

    #-------------------------------------------------------------------------
    def _set_type(self) -> bool:
        #=======================================================================
        # <set type> ::= "set" <contained type>
        #=======================================================================
        if self._current.is_SET():
            self._append_syntaxic_node()
            self._next_token_node()
            self._contained_type() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _shift_expr(self) -> bool:
        #=======================================================================
        # <shift expr> ::= <arithmetic expr> <shift expr'>
        #=======================================================================
        if self._arithmetic_expr():
            return self._shift_expr1()
        else:
            return False

    #-------------------------------------------------------------------------
    def _shift_expr1(self) -> bool:
        #=======================================================================
        # <shift expr'>   ::= '<<'  <spaced template args> <arithmetic expr> <shift expr'>
        #                  |  '>>'  <template args> <arithmetic expr> <shift expr'>
        #                  |  '<<<' <spaced template args> <arithmetic expr> <shift expr'>
        #                  |  '>>>' <template args> <arithmetic expr> <shift expr'>
        #                  |  EPS
        #=======================================================================
        while True:
            if self._current.is_SHIFTL() or self._current.is_SHIFT0L():
                self._append_syntaxic_node()
                self._next_token_node()
                self._spaced_template_args()
            elif self._current.is_SHIFTR() or self._current.is_SHIFT0R():
                self._append_syntaxic_node()
                self._next_token_node()
                self._template_args()
            else:
                break
            if not self._arithmetic_expr():
                self._append_error( FESyntaxErrors.SHIFT_EXPR )

        return True

    #-------------------------------------------------------------------------
    def _simple_statement(self) -> bool:
        #=======================================================================
        # <simple statement> ::= <assert statement> <simple statement end>
        #                     |  <del statement> <simple statement end>
        #                     |  <ensure statement> <simple statement end>
        #                     |  <file endianness>
        #                     |  <file flushing>
        #                     |  <flow statement> <simple statement end>
        #                     |  <import statement> <simple statement end>
        #                     |  <nop statement> <simple statement end>
        #                     |  <access protection statement> <simple statement end>
        #                     |  <raise statement> <simple statement end>
        #                     |  <require statement> <simple statement end>
        #=======================================================================
        if self._assert_statement() or \
                self._del_statement() or \
                self._ensure_statement() or \
                self._file_endianness() or \
                self._file_flushing() or \
                self._flow_statement() or \
                self._import_statement() or \
                self._nop_statement() or \
                self._access_protection_statement() or \
                self._raise_statement() or \
                self._require_statement():
            if not self._simple_statement_end():
                self._append_error( FESyntaxErrors.STATEMENT_END )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _simple_statement_end(self) -> bool:
        #=======================================================================
        # <simple statement end> ::= ';'
        #=======================================================================
        if self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False   

    #-------------------------------------------------------------------------
    def _slice_end(self) -> bool:
        #=======================================================================
        # <slice end> ::= ']'
        #              |  ')'
        #=======================================================================
        if self._current.is_BRACKETCL() or self._current.is_PARCL():
            self._append_syntaxic_node()
            self._next_token_node()
        else:
            self._append_error( FESyntaxErrors.SLICE_END )
        return True 

    #-------------------------------------------------------------------------
    def _slice_form(self) -> bool:
        #=======================================================================
        # <slice form> ::= ':' <slice upper> <slice step>
        #=======================================================================
        if self._current.is_COLON():
            self._append_syntaxic_node()
            self._next_token_node()
            self._slice_upper()
            self._slice_step()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _slice_step(self) -> bool:
        #=======================================================================
        # <slice step> ::= ':' <slice step'>
        #               |  EPS
        #=======================================================================
        if self._current.is_COLON():
            self._append_syntaxic_node()
            self._next_token_node()
            self._slice_step1()
            return True

    #-------------------------------------------------------------------------
    def _slice_step1(self) -> bool:
        #=======================================================================
        # <slice step'> ::= <expression>
        #                |    EPS 
        #=======================================================================
        self._expression()
        return True

    #-------------------------------------------------------------------------
    def _slice_upper(self) -> bool:
        #=======================================================================
        # <slice upper> ::= <expression>
        #                |    EPS
        #=======================================================================
        self._expression()
        return True

    #-------------------------------------------------------------------------
    def _spaced_template_args(self) -> bool:
        #=======================================================================
        # <spaced template args> ::= ' <' <template args'> '>'
        #                         |    EPS
        #=======================================================================
        return self._template_args() ## (notice: space before < is mandatory and has already be skipped by Scanner)

    #-------------------------------------------------------------------------
    def _spaced_template_def(self) -> bool:
        #=======================================================================
        # <spaced template def>  ::= ' <' <template def'> '>'
        #                         |    EPS
        #=======================================================================
        return self._template_def() ## (notice: space before < is mandatory and has already be skipped by Scanner)

    #-------------------------------------------------------------------------
    def _statements_block(self) -> bool:
        #=======================================================================
        # <statements block> ::= '{' <statements list> '}'
        #                     |  <compound statement>
        #                     |  <empty statement> <statements block>
        #                     |  <simple statement>
        #=======================================================================
        if self._current.is_BRACEOP():
            self._append_new_block()
            self._next_token_node()
            if self._statements_list():
                if self._current.is_BRACECL():
                    self._append_syntaxic_node()
                    self._next_token_node()
                else:
                    self._append_error( FESyntaxErrors.BODY_END )
            self._up_to_parent_block()
            return True
        elif self._compound_statement() or self._simple_statement():
            return True
        elif self._empty_statement():
            return self._statements_block()
        else:
            return False

    #-------------------------------------------------------------------------
    def _statements_list(self) -> bool:
        #===============================================================================
        # <statements list> ::= <empty statement> <statements list>
        #                    |  <compound statement> <statements list>
        #                    |  <simple statement> <statements list>
        #                    |  <statements block> <statements list>
        #                    |  EPS
        #===============================================================================
        while self._empty_statement() or \
                self._compound_statement() or \
                self._simple_statement() or \
                self._statements_block():
            pass
        return True

    #-------------------------------------------------------------------------
    def _static_qualifier(self) -> bool:
        #=======================================================================
        # <static qualifier> ::= "static"
        #=======================================================================
        if self._current.is_STATIC():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False            

    #-------------------------------------------------------------------------
    def _string(self) -> bool:
        #=======================================================================
        # <string> ::= <single string> <string'> <string methods>
        #=======================================================================
        if self._current.is_STRING(): ## (notice: previously scanned by Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
            self._string1() ## (notice: always returns True)
            self._string_methods() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _string1(self) -> bool:
        #=======================================================================
        # <string'> ::= <single string> <string'>
        #            |  EPS
        #=======================================================================
        while self._current.is_STRING(): ## (notice: previously scanned by Scanner)
            self._append_syntaxic_node()
            self._next_token_node()
        return True

    #-------------------------------------------------------------------------
    def _string_methods(self) -> bool:
        #=======================================================================
        # <string methods> ::= '.' <identifier> <function call> <string methods'>
        #                   |  EPS
        #=======================================================================
        if self._current.is_DOT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.STRING_FUNC_IDENT )
            if not self._function_call():
                self._append_error( FESyntaxErrors.STRING_FUNC_ARGS )
            return self._string_methods1() ## (notice: always returns True)
        else:
            return True

    #-------------------------------------------------------------------------
    def _string_methods1(self) -> bool:
        #=======================================================================
        # <string methods'> ::= '.' <identifier> <function call> <string methods'>
        #                    |  EPS
        #=======================================================================
        while self._current.is_DOT():
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.STRING_FUNC_IDENT )
            if not self._function_call():
                self._append_error( FESyntaxErrors.STRING_FUNC_ARGS )
        return True

    #-------------------------------------------------------------------------
    def _subscription_or_slicing(self) -> bool:
        #=======================================================================
        # <subscription or slicing> ::= '[' <expression> <subscription or slicing'>
        #=======================================================================
        if self._current.is_BRACKETOP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.SUBSCR_SLICE_EXPR )
            self._subscription_or_slicing1()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _subscription_or_slicing1(self) -> bool:
        #=======================================================================
        # <subscription or slicing'> ::= <expr list'> ']'
        #                             |  <if comprehension>
        #                             |  <slice form> <slice end>
        #=======================================================================
        if self._expr_list1():
            if self._current.is_BRACKETCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.SUBCSR_SLICE_END )
            return True
        elif self._if_comprehension() or \
                self._slice_form() and self._slice_end():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _switch_block(self) -> bool:
        #=======================================================================
        # <switch block> ::= <case> <switch block>
        #                 |  EPS
        #=======================================================================
        while self._case():
            continue
        return True

    #-------------------------------------------------------------------------
    def _switch_statement(self) -> bool:
        #=======================================================================
        # <switch statement> ::= 'switch' '(' <expression> ')' '{' <switch block> '}' <switch statement'>
        #=======================================================================
        if self._current.is_SWITCH():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.SWITCH_EXPR_BEGIN )
            if not self._expression():
                self._append_error( FESyntaxErrors.SWITCH_EXPR )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.SWITCH_EXPR_END )
            if self._current.is_BRACEOP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.SWITCH_BODY_BEGIN )
            self._switch_block() ## (notice: always returns True)
            if self._current.is_BRACECL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.SWITCH_BODY_END )
            self._switch_statement1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _switch_statement1(self) -> bool:
        #=======================================================================
        # <switch statement'> ::= 'otherwise' <statements block>
        #                      |  EPS
        #=======================================================================
        if self._current.is_OTHERWISE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._statements_block():
                self._append_error( FESyntaxErrors.SWITCH_OTHERWISE_BODY )
        return True

    #-------------------------------------------------------------------------
    def _target(self) -> bool:
        #=======================================================================
        # <target> ::= <dotted name> <target'>
        #=======================================================================
        if not self._dotted_name():
            self._append_error( FESyntaxErrors.TARGET_IDENT )
        return self._target1() ## (notice: always returns True)

    #-------------------------------------------------------------------------
    def _target1(self) -> bool:
        #=======================================================================
        # <target'> ::= <subscription or slicing> <target'>
        #            |   EPS
        #=======================================================================
        while self._subscription_or_slicing():
            continue
        return True

    #-------------------------------------------------------------------------
    def _target_list(self) -> bool:
        #=======================================================================
        # <target list> ::= <typed target> <target list'>
        #=======================================================================
        if self._typed_target():
            self._target_list1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _target_list1(self) -> bool:
        #=======================================================================
        # <target list'> ::= ',' <typed target> <target list'>
        #                 |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._typed_target():
                self._append_error( FESyntaxErrors.TARGET_TYPE )
        return True

    #-------------------------------------------------------------------------
    def _template_args(self) -> bool:
        #=======================================================================
        # <template args> ::= '<' template args'>
        #                  |  EPS
        #=======================================================================
        if self._current.is_LT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._template_args1():
                self._append_error( FESyntaxErrors.TEMPLATE_ENDING )
        return True
        
    #-------------------------------------------------------------------------
    def _template_args1(self) -> bool:
        #=======================================================================
        # <template args'> ::= <condition> <template args">
        #                   |  '>'
        #=======================================================================
        if self.condition():
            return self._template_args2()
        elif self._current.is_GT():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _template_args2(self) -> bool:
        #=======================================================================
        # <template args"> ::= ',' <condition> <template args">
        #                   |  '>'
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._condition():
                self._append_error( FESyntaxErrors.TEMPLATE_COMMA_COND )
        if self._current.is_GT():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False
    #-------------------------------------------------------------------------
    def _template_def(self) -> bool:
        #=======================================================================
        # <template def> ::= '<' template def'>
        #                  |  EPS
        #=======================================================================
        if self._current.is_LT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._template_def1():
                self._append_error( FESyntaxErrors.TEMPLATE_ENDING )
        return True
        
    #-------------------------------------------------------------------------
    def _template_def1(self) -> bool:
        #=======================================================================
        # <template def'> ::= <template def''> <template def'''>
        #                  |  '>'
        #=======================================================================
        if self._template_def2():
            if not self._template_def3():
                self._append_error( FESyntaxErrors.TEMPLATE_DEF_IDENT_CONST )
            return True
        elif self._current.is_GT():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _template_def2(self) -> bool:
        #=======================================================================
        # <template def''> ::= <identifier>
        #                   |  <const qualifier> <template def const name>
        #=======================================================================
        if self._identifier():
            return True
        elif self._const_qualifier():
            if not self._template_def_const_name():
                self._append_error( FESyntaxErrors.TEMPLATE_DEF_CONST_TYPE)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _template_def3(self) -> bool:
        #=======================================================================
        # <template def'''> ::= ',' <template def''> <template def'''>
        #                    |  '>'
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._template_def2():
                self._append_error( FESyntaxErrors.TEMPLATE_DEF_IDENT_CONST )
        if self._current.is_GT():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _template_def_const_name(self) -> bool:
        #=======================================================================
        # <template def const name> ::= <scalar type or dotted name> <identifier> <template def const name'>
        #=======================================================================
        if self._scalar_type_or_dotted_name():
            if not self._identifier():
                self._append_error( FESyntaxErrors.TEMPLATE_CONST_IDENT )
            self._template_def_const_name1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _template_def_const_name1(self) -> bool:
        #=======================================================================
        # <template def const name'> ::= '=' <expression>
        #                             |  EPS
        #=======================================================================
        if self._current.is_ASSIGN():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.TEMPLATE_CONST_EXPR )
        return True

    #-------------------------------------------------------------------------
    def _templated_type(self) -> bool:
        #=======================================================================
        # <templated type> ::=  <dotted name> <templated type'>
        #=======================================================================
        if self._dotted_name():
            self._templated_type1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _templated_type1(self) -> bool:
        #=======================================================================
        # <templated type'> ::= '<' <types and exprs list> '>'
        #                    |  EPS
        #=======================================================================
        if self._current.is_LT():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._types_and_exprs_list():
                self._append_error( FESyntaxErrors.TEMPLATE_SPECIFICATION )
            if self._current.is_GT():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.TEMPLATE_ENDING )
        return True

    #-------------------------------------------------------------------------
    def _term(self) -> bool:
        #=======================================================================
        # <term> ::= <factor> <term'>
        #=======================================================================
        if self._factor():
            return self._term1() ## (notice: always returns True)
        else:
            return False

    #-------------------------------------------------------------------------
    def _term1(self) -> bool:
        #=======================================================================
        # <term'> ::= '*' <template args> <factor> <term'>
        #          |  '/' <template args> <factor> <term'>
        #          |  '%' <template args> <factor> <term'>
        #          |  '@' <template args> <factor> <term'>
        #          |  '><' <spaced template args> <factor> <term'>
        #          |  '!!' <template args> <factor> <term'>
        #          |  '::' <template args> <factor> <term'>
        #          |  EPS
        #=======================================================================
        while True:
            if self._current.is_MUL() or \
                self._current.is_DIV() or \
                self._current.is_MOD() or \
                self._current.is_AROBASE() or \
                self._current.is_OP_2EXCL() or \
                    self._current.is_OP_2COLN():
                self._append_syntaxic_node()
                self._next_token_node()
                self._template_args()
            elif self._current.is_OP_GRLE():
                self._append_syntaxic_node()
                self._next_token_node()
                self._spaced_template_args()
            else:
                break
            self._factor()
        return True

    #-------------------------------------------------------------------------
    def _true(self) -> bool:
        #=======================================================================
        # <TRUE> ::= 'True'
        #         |  'true'
        #=======================================================================
        if self._current.is_TRUE():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _try_except(self) -> bool:
        #=======================================================================
        # <try except> ::= 'except' <try except'>
        #=======================================================================
        if self._current.is_EXCEPT():
            self._append_syntaxic_node()
            self._next_token_node()
            self._try_except1()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _try_except1(self) -> bool:
        #=======================================================================
        # <try except'> ::= '(' <try except''> ')'
        #                |  EPS
        #=======================================================================
        if self._current.is_PAROP():
            self._append_syntaxic_node()
            self._next_token_node()
            self._try_except2()
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.EXCEPT_EXPR_END )
            return True
        else:
            return False            

    #-------------------------------------------------------------------------
    def _try_except2(self) -> bool:
        #=======================================================================
        # <try except''> ::= <expression> <try except'''> <try except''''>
        #                 |  'all' <try except'''>
        #                 |  EPS
        #=======================================================================
        if self._expression():
            self._try_except3() ## (notice: always returns True)
            self._try_except4() ## (notice: always returns True)
        elif self._current.is_ALL():
            self._append_syntaxic_node()
            self._next_token_node()
            self._try_except3()
        return True

    #-------------------------------------------------------------------------
    def _try_except3(self) -> bool:
        #=======================================================================
        # <try except'''> ::= ',' <expression> <try except'''>
        #                  |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.TRY_EXCEPT_LIST )
            self._try_except3()
        return True

    #-------------------------------------------------------------------------
    def _try_except4(self) -> bool:
        #=======================================================================
        # <try except''''> ::= 'as' <identifier>
        #                   |  EPS
        #=======================================================================
        if self._current.is_AS():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.TRY_AS_IDENT )
        return True
            
    #-------------------------------------------------------------------------
    def _try_finally(self) -> bool:
        #=======================================================================
        # <try finally> ::= 'finally'
        #=======================================================================
        if self._current.is_FINALLY():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _try_otherwise(self) -> bool:
        #=======================================================================
        # <try otherwise> ::= 'otherwise' '(' <try otherwise'> ')' 
        #=======================================================================
        if self._current.is_OTHERWISE():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.TRY_OTHER_PAROP )
            self._try_otherwise()
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.TRY_OTHER_PARCL )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _try_otherwise1(self) -> bool:
        #===============================================================================
        # <try otherwise'> ::= 'Exception' 'as' <identifier>
        #                   |  EPS
        #===============================================================================
        if self._current.is_IDENT():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_AS():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.TRY_OTHER_AS )
            if self._current.is_IDENT():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.TRY_OTHER_IDENT )
        return True

    #-------------------------------------------------------------------------
    def _try_statement(self) -> bool:
        #=======================================================================
        # <try statement> ::= 'try' <statements block> <try statement excepts>
        #                         <try statement otherwise> <try statement finally>
        #=======================================================================
        if self._current.is_TRY():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._statements_block():
                self._append_error( FESyntaxErrors.TRY_BODY )
            if not self._try_statement_excepts():
                self._append_error( FESyntaxErrors.TRY_EXCEPTS )
            self._try_statement_otherwise()
            self._try_statement_finally()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _try_statement_otherwise(self) -> bool:
        #=======================================================================
        # <try statement otherwise> ::= <try otherwise> <statements block>                                                                   ##
        #                            |  EPS                                                                                             ##
        #=======================================================================
        if self._try_otherwise():
            if not self._statements_block():
                self._append_error( FESyntaxErrors.TRY_OTHER_BODY )
        return True

    #-------------------------------------------------------------------------
    def _try_statement_excepts(self) -> bool:
        #=======================================================================
        # <try statement excepts> ::= <try except> <statements block> <try statements excepts'>
        #=======================================================================
        if self._try_except():
            if not self._statements_block():
                self._append_error( FESyntaxErrors.TRY_EXCEPT_BODY )
            return self._try_statement_excepts1()
        else:
            return False

    #-------------------------------------------------------------------------
    def _try_statement_excepts1(self) -> bool:
        #=======================================================================
        # <try statement excepts'> ::= <try except> <statements block> <try statement excepts'>                                        ##
        #                           |  EPS                                                                                             ##
        #=======================================================================
        while self._try_except():
            if not self._statements_block():
                self._append_error( FESyntaxErrors.TRY_EXCEPT_BODY )
        return True

    #-------------------------------------------------------------------------
    def _try_statement_finally(self) -> bool:
        #=======================================================================
        # <try statement finally> ::= <try finally> <statements block>                                                                ##
        #                          |  EPS                                                                                             ##
        #=======================================================================
        if self._try_finally():
            if not self._statements_block():
                self._append_error( FESyntaxErrors.TRY_FINALLY_BODY )
        return True

    #-------------------------------------------------------------------------
    def _TYPE(self) -> bool:
        #=======================================================================
        # <TYPE> ::= <const qualifier> <type>
        #         |  <type>
        #=======================================================================
        if self._const_qualifier():
            if not self._type():
                self._append_error( FESyntaxErrors.CONST_TYPE )
            return True
        else:
            return self._type()

    #-------------------------------------------------------------------------
    def _TYPE1(self) -> bool:
        #=======================================================================
        # <TYPE'> ::= <const qualifier> <type>
        #          |  <type'>
        #=======================================================================
        if self._const_qualifier():
            if not self._type():
                self._append_error( FESyntaxErrors.CONST_TYPE )
            return True
        else:
            return self._type1()

    #-------------------------------------------------------------------------
    def _type(self) -> bool:
        #=======================================================================
        # <type> ::= <type'>
        #         |  <templated type> <dimensions>
        #=======================================================================
        if self._type1():
            return True
        elif self._templated_type():
            self._dimensions() ## (notice: always returns True)
            return True
        else:
            return False            

    #-------------------------------------------------------------------------
    def _type1(self) -> bool:
        #=======================================================================
        # <type> ::= <auto type>
        #         |  (' <types list> ')'
        #         |  <container type>
        #         |  <file type>
        #         |  <NONE>
        #         |  <scalar type> <dimensions>
        #=======================================================================
        if self._current.is_PAROP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._types_list():
                self._append_error( FESyntaxErrors.TYPES_LIST )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.TYPES_LIST_END )
            return True
        elif self._current.is_SCALAR_TYPE():
            self._append_syntaxic_node()
            self._next_token_node()
            self._dimensions() ## (notice: always returns True)
            return True
        elif self._file_type() or self._none():
            return True
        elif self._auto_type():
            return True
        elif self._container_type():
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _type_alias(self) -> bool:
        #=======================================================================
        # <type alias> ::= 'type' <type alias"> <type alias'>
        #=======================================================================
        if self._current.is_TYPE_ALIAS():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._type_alias2():
                self._append_error( FESyntaxErrors.TYPE_ALIAS )
            return self._type_alias1() ## (notice: always returns True)
        else:
            return False

    #-------------------------------------------------------------------------
    def _type_alias1(self) -> bool:
        #=======================================================================
        # <type alias'> ::= ',' <type alias"> <type alias'>
        #                |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._type_alias2():
                self._append_error( FESyntaxErrors.TYPE_ALIAS )
        return True

    #-------------------------------------------------------------------------
    def _type_alias2(self) -> bool:
        #=======================================================================
        # <type alias"> ::= <TYPE> 'as' <identifier>
        #=======================================================================
        if  self._TYPE():
            if self._current.is_AS():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.TYPE_AS )
            if not self._identifier():
                self._append_error( FESyntaxErrors.TYPE_AS_IDENT )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _typed_target(self) -> bool:
        #=======================================================================
        # <typed target> ::= <type'> <target>
        #                 |  <dotted name> <typed target'>
        #=======================================================================
        if self._type1():
            if not self._target():
                self._append_error( FESyntaxErrors.TYPED_TARGET_IDENT )
            return True
        elif self._dotted_name():
            return self._typed_target1() ## (notice: always returns True)
        else:
            return False

    #-------------------------------------------------------------------------
    def _typed_target1(self) -> bool:
        #=======================================================================
        # <typed target'> ::= <dotted name> <target'>
        #                  |  <target'>
        #                  |  <templated type'> <target'>
        #=======================================================================
        if self._dotted_name() or self._templated_type1():
            pass
        return self._target1() ## (notice: always returns True)

    #-------------------------------------------------------------------------
    def _types_and_exprs_list(self) -> bool:
        #=======================================================================
        # <types and exprs list> ::= <expression> <types and exprs list'>
        #                         |  <templated type> <types and exprs list'>
        #=======================================================================
        if self._expression() or self._templated_type():
            self._types_and_exprs_list1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _types_and_exprs_list1(self) -> bool:
        #=======================================================================
        # <types and exprs list'> ::= ',' <types and exprs list"> <types and exprs list'>
        #                          |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._types_and_exprs_list2():
                self._append_error( FESyntaxErrors.TEMPLATE_TYPES_LIST )
        return True

    #-------------------------------------------------------------------------
    def _types_and_exprs_list2(self) -> bool:
        #=======================================================================
        # <types and exprs list"> ::= <expression>
        #                          | <templated type>
        #=======================================================================
        return self._expression() or self._templated_type()

    #-------------------------------------------------------------------------
    def _typed_args_list(self) -> bool:
        #=======================================================================
        # <typed args list> ::= <TYPE> <identifier> <typed args list'>
        #                    |  EPS
        #=======================================================================
        if self._TYPE():
            if not self._identifier():
                self._append_error( FESyntaxErrors.TYPE_LIST_IDENT )
            self.typed_args_list1()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _typed_args_list1(self) -> bool:
        #=======================================================================
        # <typed args list'> ::= ',' <TYPE> <identifier> <typed args list'>
        #                     |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._TYPE():
                self._append_error( FESyntaxErrors.TYPES_LIST_TYPE )
            if not self._identifier():
                self._append_error( FESyntaxErrors.TYPE_LIST_IDENT )
        return True

    #-------------------------------------------------------------------------
    def _type_casting(self) -> bool:
        #=======================================================================
        # <scalar type casting> ::= '(' <expression> ')'
        #=======================================================================
        if self._current.is_PAROP():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.CASTING_EXPR )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.CASTING_PARCL )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _types_list(self) -> bool:
        #=======================================================================
        # <types list> ::= <TYPE> <types list'>
        #=======================================================================
        if self._TYPE():
            self._types_list1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _types_list1(self) -> bool:
        #=======================================================================
        # <types list'> ::= ',' <TYPE> <types list'>
        #                |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._TYPE():
                self._append_error( FESyntaxErrors.TYPES_LIST_TYPE )
        return True

    #-------------------------------------------------------------------------
    def _unary_expr(self) -> bool:
        #=======================================================================
        # <unary expr> ::= <factor>
        #               |  '+' <factor>
        #               |  '-' <factor>
        #               |  '~' <factor>
        #               |  '#' <factor>
        #=======================================================================
        if self._current.is_PLUS() or \
                self._current.is_MINUS() or \
                self._current.is_TILD() or \
                self._current.is_HASH():
            self._append_syntaxic_node()
            self._next_token_node()
        return self._factor()

    #-------------------------------------------------------------------------
    def _unnamed(self) -> bool:
        #=======================================================================
        # <unnamed> ::= 'unnamed'
        #            |  'lambda'
        #=======================================================================
        if self._current.is_UNNAMED():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _unnamed_func(self) -> bool:
        #=======================================================================
        # <unnamed func> ::= <unnamed> <returned type> <function args declaration> <statements block>
        #=======================================================================
        if self._unnamed():
            if not self._returned_type():                         ## (notice: always returns True)
                self._append_error( FESyntaxErrors.UNNAMED_TYPE ) ## (notice: never reached statement)
            if not self._function_args_declaration():
                self._append_error( FESyntaxErrors.UNNAMED_ARGS )
            if not self._statements_block():
                self._append_error( FESyntaxErrors.UNNAMED_BODY )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _var_declaration_or_assignment(self) -> bool:
        #=======================================================================
        # <var declaration or assignment> ::= '=' <expression> <var declaration or assignment'>
        #                                  |  ',' <identifier> <var declaration or assignment>
        #                                  |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.DECL_COMMA_IDENT )
        if self._current.is_ASSIGN():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._expression():
                self._append_error( FESyntaxErrors.ASSIGN_EXPR )
            self._var_declaration_or_assignment1() ## (notice: always returns True)
        return True

    #-------------------------------------------------------------------------
    def _var_declaration_or_assignment1(self) -> bool:
        #=======================================================================
        # <var declaration or assignment'> ::= ',' <identifier> <var declaration or assignment>
        #                                   |    EPS
        #=======================================================================
        if self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._identifier():
                self._append_error( FESyntaxErrors.DECL_COMMA_IDENT )
            self._var_declaration_or_assignment()
        return True

    #-------------------------------------------------------------------------
    def _volatile_qualifier(self) -> bool:
        #=======================================================================
        # <volatile qualifier> ::= 'volatile'
        #=======================================================================
        if self._current.is_VOLATILE():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _while_statement(self) -> bool:
        #=======================================================================
        # <while statement> ::= 'while' '(' <expression> ')' <statements block> <while statement'>
        #=======================================================================
        if self._current.is_WHILE():
            self._append_syntaxic_node()
            self._next_token_node()
            if self._current.is_PAROP():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.WHILE_COND_BEGIN )
            if not self._expression():
                self._append_error( FESyntaxErrors.WHILE_COND )
            if self._current.is_PARCL():
                self._append_syntaxic_node()
                self._next_token_node()
            else:
                self._append_error( FESyntaxErrors.WHILE_COND_END )
            if not self._statements_block():
                self._append_error( FESyntaxErrors.WHILE_BODY )
            self._while_statement1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _while_statement1(self) -> bool:
        #=======================================================================
        # <while statement'> ::= 'otherwise' <statements block>
        #                     |  EPS
        #=======================================================================
        if self._current.is_OTHERWISE():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._statements_block():
                self._append_error( FESyntaxErrors.WHILE_OTHERWISE_BODY )
        return True

    #-------------------------------------------------------------------------
    def _with_item(self) -> bool:
        #=======================================================================
        # <with item> ::= <expression> <with item'>
        #=======================================================================
        if self._expression():
            self._with_item1() ## (notice: always returns True)
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _with_item1(self) -> bool:
        #=======================================================================
        # <with item'> ::= 'as' <with item">
        #               |  EPS
        #=======================================================================
        if self._current.is_AS():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._with_item2():
                self._append_error( FESyntaxErrors.WITH_AS_IDENT )
        return True

    #-------------------------------------------------------------------------
    def _with_item2(self) -> bool:
        #=======================================================================
        # <with item"> ::= <target>
        #               |  <type'> <target>
        #=======================================================================
        if self._target():
            return True
        elif self._type1():
            if not self._target():
                self._append_error( FESyntaxErrors.WITH_AS_TYPED_IDENT )
            return True
        else:
            return False

    #-------------------------------------------------------------------------
    def _with_items_list(self) -> bool:
        #=======================================================================
        # <with items list> ::= <with item> <with items list'>
        #=======================================================================
        if not self._with_item():
            self._append_error( FESyntaxErrors.WITH_EXPR )
        self._with_items_list1() ## (notice: always returns True)
        return True

    #-------------------------------------------------------------------------
    def _with_items_list1(self) -> bool:
        #=======================================================================
        # <with items list'> ::= ',' <with item> <with items list'>
        #                     |  EPS
        #=======================================================================
        while self._current.is_COMMA():
            self._append_syntaxic_node()
            self._next_token_node()
            if not self._with_item():
                self._append_error( FESyntaxErrors.WITH_LIST_COMMA )
        return True

    #-------------------------------------------------------------------------
    def _with_statement(self) -> bool:
        #=======================================================================
        # <with statement> ::= 'with' <with items list> <statements block>
        #=======================================================================
        if self._current.is_WITH():
            self._append_syntaxic_node()
            self._next_token_node()
            self._with_items_list() ## (notice: always returns True)
            if not self._statements_block():
                self._append_error( FESyntaxErrors.WITH_BODY )
            return True
        else:
            return False
    

    #=========================================================================
    #-------------------------------------------------------------------------
    def _append_error(self, err_data=None) -> None:
        self._errors_count += 1
        err_node = ICTokenNode_UNEXPECTED( data=err_data or self._current.tk_data )
        err_node.num_line = self._current.num_line
        err_node.num_coln = self._current.num_coln
        self._append_syntaxic_node( err_node )
    #-------------------------------------------------------------------------
    def _append_new_block(self) -> None:
        self._out_syntax_ic += FEICBlock()
        self._append_syntaxic_node()
    #-------------------------------------------------------------------------
    def _append_syntaxic_node(self, s_node: FEICodeTokenNode = None) -> bool:
        self._out_syntax_ic += FEICLeaf( self._current if s_node is None else s_node )
        return True
    #-------------------------------------------------------------------------
    def _eof(self) -> bool:
        if self._current.is_EOF():
            self._append_syntaxic_node()
            self._next_token_node()
            return True
        else:
            return False
    #-------------------------------------------------------------------------
    def _next_token_node(self) -> FEICodeTokenNode:
        try:
            self._current = next( self._tokenizedIC )
            while self._current.is_UNEXPECTED():
                self._append_syntaxic_node()
                self._current = next( self._tokenizedIC )
        except:
            self._current = ICTokenNode_EOF()
        return  self._current
    
    #-------------------------------------------------------------------------
    def __up_to_parent_block(self) -> None:
        self._out_syntax_ic.up_level()

#=====   end of   FrontEnd.Parser.parser   =====#
