diff --git a/src/FrontEnd/Errors/fe_syntax_errors.py b/src/FrontEnd/Errors/fe_syntax_errors.py index a7d9a81..7c925c9 100644 --- a/src/FrontEnd/Errors/fe_syntax_errors.py +++ b/src/FrontEnd/Errors/fe_syntax_errors.py @@ -164,6 +164,9 @@ class FESyntaxErrors: IF_CONDITION_END = 'missing ) after condition in if clause, leads to unpaired (', IF_ELSE = 'missing keyword "else" in inlined if clause', IF_ELSE_EXPR = 'missing expression after keyword "else" in inlined if clause', + IF_OTHERWISE_EXPR = 'missing expression after keyword "otherwise" in inlined if clause', + IMPORT_BUT_COMMA_IDENT = 'missing or badly formed identifier after , in list of identifiers in import-but clause', + IMPORT_BUT_IDENT = 'missing or badly formed identifier in import-but clause', IMPORT_IDENT = 'missing or badly formed identifier after , in list of identifiers in import-as instruction', IMPORT_MODULE = 'missing or badly formed module identifier in import instruction', INCR_IDENT = 'missing variable name after operator "++"', @@ -191,6 +194,7 @@ class FESyntaxErrors: OPERATOR_OP = 'missing or badly formed operator identifier in operator definition', OR_EXPR = 'missing or badly formed numerical expression after bitwise operator |', OR_TEST = 'missing or badly formed comparison expression after keyword "or"', + OTHERWISE_BODY = 'missing instruction or block of instructions after keyword "otherwise"', PARENTH_EXPR = 'missing or badly formed expression in parenthesis-form clause', POWER_EXPR = 'missing or badly formed expression after power operator', @@ -215,10 +219,11 @@ class FESyntaxErrors: SUBCSR_SLICE_END = 'missing ] at end of subscription or slicing specification, leads to unpaired [', SWITCH_BODY_BEGIN = 'missing { after switch clause and before block of case clauses in switch instruction', SWITCH_BODY_END = 'missing } at end of case clauses in switch instruction, leads to unpaired {', - SWITCH_ELSE_BODY = 'missing instruction or instructions block after keyword "otherwise" of switch statement', + SWITCH_OTHERWISE_BODY = 'missing instruction or instructions block after keyword "otherwise" of switch statement', SWITCH_EXPR = 'missing or badly formed expression after ( in switch instruction', SWITCH_EXPR_BEGIN = 'missing ( after keyword "switch" in switch instruction', SWITCH_EXPR_END = 'missing ) at end of switch clause in switch instruction, leads to unpaired (', + SWITCH_OTHERWISE_BODY = 'missing instruction or instructions block after keyword "otherwise" of switch statement', TARGET_IDENT = 'missing or badly formed identifier', TARGET_TYPE = 'missing or badly formed typed identifier after "," in list of types identifiers', @@ -273,11 +278,12 @@ class FESyntaxErrors: WHILE_COND = 'missing or badly formed conditional expression after ( in while clause', WHILE_COND_BEGIN = 'missing ( after keyword "while"', WHILE_COND_END = 'missing ) at end of conditional expression in while clause, leads to unpaired (', - WHILE_ELSE_BODY = 'missing instruction or instructions block after keyword "otherwise" in while instruction', + WHILE_OTHERWISE_BODY = 'missing instruction or instructions block after keyword "otherwise" in while instruction', WITH_AS_IDENT = 'missing or badly formed identifier after keyword "as" in with clause', WITH_BODY = 'missing instruction or instructions block after with clause in with instruction', WITH_EXPR = 'missing or badly formed expression after keyword "with"', WITH_LIST_COMMA = 'missing or badly formed with-as clause in list of with-as clauses' ## notice: we already know that this kind of error will never be detected as such + WHILE_OTHERWISE_BODY = 'missing instruction or instructions block after keyword "otherwise" in while instruction', #===== end of FrontEnd.Errors.fe_syntax_errors =====# \ No newline at end of file diff --git a/src/FrontEnd/IntermediateCode/fe_icode_token_node.py b/src/FrontEnd/IntermediateCode/fe_icode_token_node.py index 25b8368..a8d27d7 100644 --- a/src/FrontEnd/IntermediateCode/fe_icode_token_node.py +++ b/src/FrontEnd/IntermediateCode/fe_icode_token_node.py @@ -25,6 +25,7 @@ #============================================================================= ## THIS FILE HAS BEEN AUTOMATICALLY GENERATED BY Typee FRAMEWORK. ## DO NOT MODIFY IT: ANY MODIFICATION WOULD BE LOST ON NEXT SCRIPTED GENERATION. +## Last modification version: 201906-061508-11324Y #============================================================================= @@ -165,6 +166,9 @@ def is_BRACKETOP(self) -> bool: def is_BREAK(self) -> bool: return self.tk_ident == FEICodeTokens.TK_BREAK @property + def is_BUT(self) -> bool: + return self.tk_ident == FEICodeTokens.TK_BUT + @property def is_CASE(self) -> bool: return self.tk_ident == FEICodeTokens.TK_CASE @property @@ -637,6 +641,10 @@ class ICTokenNode_BREAK( FEICodeTokenNode ): def __init__(self, scanner=None, data='break'): super().__init__( scanner, FEICodeTokens.TK_BREAK, data ) +class ICTokenNode_BUT( FEICodeTokenNode ): + def __init__(self, scanner=None, data='but'): + super().__init__( scanner, FEICodeTokens.TK_BUT, data ) + class ICTokenNode_CASE( FEICodeTokenNode ): def __init__(self, scanner=None, data='case'): super().__init__( scanner, FEICodeTokens.TK_CASE, data ) diff --git a/src/FrontEnd/IntermediateCode/fe_icode_tokens.py b/src/FrontEnd/IntermediateCode/fe_icode_tokens.py index 9fc8391..2883a8c 100644 --- a/src/FrontEnd/IntermediateCode/fe_icode_tokens.py +++ b/src/FrontEnd/IntermediateCode/fe_icode_tokens.py @@ -199,6 +199,7 @@ class FEICodeTokens: TK_FROM = 0 TK_ALL = 0 TK_AS = 0 + TK_BUT = 0 TK_EXCLUDE = 0 TK_EXIT = 0 @@ -398,6 +399,7 @@ class FEICodeTokensData: FEICodeTokens._TOKEN_NAMES[ FEICodeTokens.TK_FROM ] : 'from', FEICodeTokens._TOKEN_NAMES[ FEICodeTokens.TK_ALL ] : 'all', FEICodeTokens._TOKEN_NAMES[ FEICodeTokens.TK_AS ] : 'as', + FEICodeTokens._TOKEN_NAMES[ FEICodeTokens.TK_BUT ] : 'but', FEICodeTokens._TOKEN_NAMES[ FEICodeTokens.TK_EXCLUDE ] : 'exclude', FEICodeTokens._TOKEN_NAMES[ FEICodeTokens.TK_EXIT ] : 'exit', diff --git a/src/FrontEnd/Parser/fe_parser.py b/src/FrontEnd/Parser/fe_parser.py index e5a44da..b1f851c 100644 --- a/src/FrontEnd/Parser/fe_parser.py +++ b/src/FrontEnd/Parser/fe_parser.py @@ -694,9 +694,9 @@ def _comp_operator(self) -> bool: #------------------------------------------------------------------------- def _comp_operator1(self) -> bool: #======================================================================= - # ::= '<' | '>' + # ::= '<' | '>' | '<=>' #======================================================================= - if self._current.is_LT() or self._current.is_GT(): + 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 @@ -740,7 +740,7 @@ def _condition(self) -> bool: #------------------------------------------------------------------------- def _condition1(self) -> bool: #======================================================================= - # ::= 'if' 'else' + # ::= 'if' # | EPS #======================================================================= if self._current.is_IF(): @@ -748,18 +748,27 @@ def _condition1(self) -> bool: self._next_token_node() if not self._or_test(): self._append_error( FESyntaxErrors.IF_COND ) - 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 ) - return True - else: - self._append_error( FESyntaxErrors.IF_ELSE ) - return True + return self._condition2() else: return True + #------------------------------------------------------------------------- + def _condition2(self) -> bool: + #=========================================================================== + # ::= 'else' + # | 'otherwise' + #=========================================================================== + 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: #======================================================================= @@ -2018,11 +2027,12 @@ def _if_statement1(self) -> bool: self._append_error( FESyntaxErrors.ELIF_CONDITION_END ) if not self._statements_block(): self._append_error( FESyntaxErrors.ELIF_BODY ) - if self._current.is_ELSE(): + 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 ) + self._append_error( FESyntaxErrors.ELSE_BODY if self._current.is_ELSE() + else FESyntaxErrors.OTHERWISE_BODY ) return True #------------------------------------------------------------------------- @@ -2072,6 +2082,33 @@ def _import_as_names1(self) -> bool: self._append_error( FESyntaxErrors.IMPORT_IDENT ) return True + #------------------------------------------------------------------------- + def _import_but(self) -> bool: + #=============================================================================== + # ::= '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: + #=============================================================================== + # ::= ',' + # | 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: #======================================================================= @@ -2115,14 +2152,14 @@ def _import_from2(self) -> bool: #------------------------------------------------------------------------- def _import_from3(self) -> bool: #======================================================================= - # ::= 'all' + # ::= 'all' # | '(' ')' # | #======================================================================= if self._current.is_ALL(): self._append_syntaxic_node() self._next_token_node() - return True + return self._import_but() elif self._current.is_PAROP(): self._append_syntaxic_node() self._next_token_node() @@ -2575,11 +2612,12 @@ def _operator(self) -> bool: #------------------------------------------------------------------------- def _operator1(self) -> bool: #======================================================================= - # ::= '<' | '>' | '<<' | '<<<' | '>>' | '>>>' + # ::= '<' | '>' | '<<' | '<<<' | '>>' | '>>>' | '<=>' #======================================================================= if self._current.is_LT() or self._current.is_GT() or \ self._current.is_SHIFTL() or self._current.is_SHIFT0L() or \ - self._current.is_SHIFTR() or self._current.is_SHIFT0R(): + self._current.is_SHIFTR() or self._current.is_SHIFT0R() or \ + self._current.is_LEG(): self._append_syntaxic_node() self._next_token_node() return True @@ -3260,7 +3298,7 @@ def _switch_statement1(self) -> bool: self._append_syntaxic_node() self._next_token_node() if not self._statements_block(): - self._append_error( FESyntaxErrors.SWITCH_ELSE_BODY ) + self._append_error( FESyntaxErrors.SWITCH_OTHERWISE_BODY ) return True #------------------------------------------------------------------------- @@ -4069,7 +4107,7 @@ def _while_statement1(self) -> bool: self._append_syntaxic_node() self._next_token_node() if not self._statements_block(): - self._append_error( FESyntaxErrors.WHILE_ELSE_BODY ) + self._append_error( FESyntaxErrors.WHILE_OTHERWISE_BODY ) return True #-------------------------------------------------------------------------