Example #1
0
    def skip_nest(self, pos):
        """Skips anything between two brackets, parentheses or braces starting
        at 'pos', if the brackets, parentheses or braces are not closed or
        are closed in the wrong order an error shall be raised
        """
        lbrackets = ["LBRACKET", "LBRACE", "LPARENTHESIS"]
        rbrackets = ["RBRACKET", "RBRACE", "RPARENTHESIS"]
        try:
            c = self.peek_token(pos).type
        except:
            raise CParsingError(f"Unexpected EOF line {pos}")
        if c not in lbrackets:
            return pos
        c = rbrackets[lbrackets.index(c)]
        i = pos + 1
        while self.peek_token(i) is not None:
            if self.check_token(i, lbrackets) is True:
                i = self.skip_nest(i)
                if i == -1:
                    return -1
            elif self.check_token(i, rbrackets) is True:
                if c == self.peek_token(i).type:
                    return i
            i += 1
        raise CParsingError("Nested parentheses, braces or brackets\
 are not correctly closed")

        return -1
 def check_reserved_keywords(self, context, pos):
     if context.check_token(pos, keywords) is False:
         return False, pos
     if context.check_token(pos, "RETURN"):
         i = pos + 1
         while context.check_token(i, "SEMI_COLON") is False:
             i += 1
         i += 1
         return True, i
     elif context.check_token(pos, "GOTO"):
         i = pos + 1
         i = context.skip_ws(i)
         while context.check_token(
                 i, ["MULT", "BWISE_AND"
                     ]) is True and context.is_operator(i) is False:
             i += 1
         if context.check_token(i, "IDENTIFIER") is False:
             if context.check_token(i, "LPARENTHESIS") is True:
                 # parse label value here
                 i = context.skip_nest(i)
             elif context.debug == 0:
                 raise CParsingError(
                     "Goto statement should be followed by a label")
         i += 1
         i = context.skip_ws(i)
         i += 1
         return True, i
     else:
         i = pos + 1
         i = context.skip_ws(i)
         i += 1
         return True, i
Example #3
0
 def run(self, context):
     """
     Declared variables must be aligned using tabs with other variables on the same scope
     """
     i = 0
     expected = context.scope.indent
     if context.history[-1] == "IsAssignation":
         nest = expected + 1
     elif context.history[-1] == "IsFuncPrototype":
         nest = context.func_alignment
     else:
         nest = expected
     while context.check_token(i, ["SEMI_COLON"]) is False:
         if context.check_token(i, "NEWLINE") is True:
             if context.check_token(i - 1, operators) is True:
                 context.new_error("EOL_OPERATOR", context.peek_token(i))
             tmp = context.skip_ws(i + 1)
             if context.check_token(tmp, "COMMA"):
                 context.new_error("COMMA_START_LINE",
                                   context.peek_token(i))
             got = 0
             i += 1
             while context.check_token(i + got, "TAB") is True:
                 got += 1
             if context.peek_token(i + got) is None:
                 raise CParsingError(
                     f"Error: Unexpected EOF l.{context.peek_token(i - 1).pos[0]}"
                 )
             if context.check_token(
                     i + got, ["LBRACKET", "RBRACKET", "LBRACE", "RBRACE"]):
                 nest -= 1
             if got > nest:
                 context.new_error("TOO_MANY_TAB", context.peek_token(i))
                 return True, i
             elif got < nest:
                 context.new_error("TOO_FEW_TAB", context.peek_token(i))
                 return True, i
             if context.check_token(
                     i + got, ["LBRACKET", "RBRACKET", "LBRACE", "RBRACE"]):
                 nest += 1
         if context.check_token(i, "LPARENTHESIS") is True:
             nest += 1
         if context.check_token(i, "RPARENTHESIS") is True:
             nest -= 1
         i += 1
     return False, 0
Example #4
0
 def run(self, context, source):
     """
     Main function for each file.
     Primary rules are determined by the prefix "Is" and
     are run by order of priority as defined in each class
     Each secondary rule is then run in arbitrary order based on their
     dependencies
     """
     unrecognized_tkns = []
     while context.tokens != []:
         context.tkn_scope = len(context.tokens)
         for rule in self.primary_rules:
             if type(context.scope) not in rule.scope and rule.scope != []:
                 continue
             ret, jump = self.run_rules(context, rule)
             if ret is True:
                 if unrecognized_tkns != []:
                     if context.debug == 0:
                         raise CParsingError(
                             f"Unrecognized line {unrecognized_tkns[0].pos} while parsing line {unrecognized_tkns}"
                         )
                     print("uncaught -> ", context.filename)
                     print("uncaught -> ", unrecognized_tkns)
                     unrecognized_tkns = []
                 context.dprint(rule.name, jump)
                 context.update()
                 context.pop_tokens(jump)
                 break
         # #############################################################
         else:  # Remove these one ALL  primary rules are done
             # print("#, ", context.tokens[0])
             unrecognized_tkns.append(context.tokens[0])
             context.pop_tokens(1)  # ##################################
         # #############################################################
     if unrecognized_tkns != []:
         print(context.debug)
         if context.debug > 0:
             print("uncaught ->", unrecognized_tkns)
     if context.errors == []:
         print(context.filename + ": OK!")
     else:
         print(context.filename + ": KO!")
         context.errors = sorted(context.errors, key=cmp_to_key(sort_errs))
         for err in context.errors:
             print(err)
 def run(self, context):
     """
     User defined types must respect the following rules:
         - Struct names start with s_
         - Enum names start with e_
         - Union names start with u_
         - Typedef names start with t_
     """
     i = 0
     i = context.skip_ws(i)
     tkns = context.tokens
     is_td = False
     on_newline = False
     utype = None
     contain_full_def = False
     ids = []
     while context.check_token(i, ["SEMI_COLON"]) is False and i < len(
             context.tokens):
         if context.check_token(i, ["SPACE", "TAB"]):
             pass
         if context.check_token(i, ["LPARENTHESIS"]) is True:
             val, tmp = context.parenthesis_contain(i)
             if val == None or val == "cast":
                 i = tmp
         if context.check_token(i, utypes) is True:
             utype = context.peek_token(i)
         if context.check_token(i, "TYPEDEF") is True:
             is_td = True
         if context.check_token(i, "LBRACKET") is True:
             i = context.skip_nest(i)
         if context.check_token(i, "IDENTIFIER") is True:
             if context.peek_token(i).value == "__attribute__":
                 i += 1
                 i = context.skip_ws(i)
                 i = context.skip_nest(i)
                 continue
             if context.check_token(i - 1, ["MULT", "BWISE_AND"]) is True:
                 tmp = i - 1
                 while context.check_token(tmp, [
                         "MULT", "BWISE_AND"
                 ]) is True and context.is_operator(tmp) == False:
                     tmp -= 1
                 ids.append((context.peek_token(i), tmp))
             else:
                 ids.append((context.peek_token(i), i))
         if context.check_token(i, "LBRACE") is True:
             contain_full_def = True
             i = context.skip_nest(i)
         i += 1
     check = -1
     #print (ids, utype, contain_full_def)
     if is_td == True and len(ids) < 2 and utype != None:
         context.new_error("MISSING_TYPEDEF_ID", context.peek_token(0))
         return False, 0
     if contain_full_def == False and is_td == False and len(ids) > 1:
         check = -2
     else:
         check = -1
     if len(ids) == 0:
         return False, 0
     name = ids[0][0]
     loc = ids[check][1]
     if is_td == True:
         if ids[check][0].value.startswith("t_") is False:
             context.new_error("USER_DEFINED_TYPEDEF",
                               context.peek_token(loc))
         if utype is not None:
             if len(ids) > 1:
                 name = ids[0][0]
             else:
                 if context.debug >= 1:
                     pass
                 elif context.debug == 0:
                     raise CParsingError(
                         f"Error: {context.filename}: Could not parse structure line {context.peek_token(0).pos[0]}"
                     )
         loc = ids[0][1]
     else:
         loc = ids[0][1]
     if is_td == False:
         if utype is not None and utype.type == "STRUCT" and name.value.startswith(
                 "s_") is False:
             context.new_error("STRUCT_TYPE_NAMING",
                               context.peek_token(loc))
         if utype is not None and utype.type == "UNION" and name.value.startswith(
                 "u_") is False:
             context.new_error("UNION_TYPE_NAMING", context.peek_token(loc))
         if utype is not None and utype.type == "ENUM" and name.value.startswith(
                 "e_") is False:
             context.new_error("ENUM_TYPE_NAMING", context.peek_token(loc))
     if is_td or (is_td == False and contain_full_def == False):
         tmp = ids[-1][1] - 1
         tabs = 0
         while (context.check_token(tmp, "TAB")) is True and tmp > 0:
             tabs += 1
             tmp -= 1
         #if tabs > 1:
         #context.new_error("TOO_MANY_TABS_TD", context.peek_token(tmp))
         if context.check_token(tmp, "SPACE") is True:
             context.new_error("SPACE_REPLACE_TAB", context.peek_token(tmp))
         tab_error = False
         while tmp > 0:
             if context.check_token(tmp, "RBRACE") is True:
                 tmp = context.skip_nest_reverse(tmp)
             if context.check_token(tmp,
                                    "TAB") is True and on_newline == False:
                 tab_error = True
             tmp -= 1
         if tab_error:
             context.new_error("TAB_REPLACE_SPACE", context.peek_token(tmp))
     if contain_full_def == False:
         i = 0
         identifier = ids[-1][0]
         i = ids[-1][1]
         if context.check_token(
                 i - 1, ["MULT", "BWISE_AND", "LPARENTHESIS"]) is True:
             i -= 1
             while (context.check_token(
                     i, ["MULT", "BWISE_AND", "LPARENTHESIS"]) is True
                    and context.is_operator(i) is False):
                 i -= 1
         current_indent = context.peek_token(i).pos[1]
         if context.scope.vars_alignment == 0:
             context.scope.vars_alignment = current_indent
         elif context.scope.vars_alignment != current_indent:
             context.new_error("MISALIGNED_VAR_DECL", context.peek_token(0))
             return True, i
         return False, 0