Example #1
0
class Parser:

    TYPE = ['CLUSTER','COMPUTER', 'NETWORK', 'SERVICE']
    STATEMENT_STARTERS = ['SEMICOLON','LBRACE', 'IDENTIFIER', 'IF', 'WHILE','SELECTED_NAME']
    REL_OP = ['LT', 'LTE', 'GT', 'GTE']
    MUL_OP = ['MUL', 'DIV']
    ADD_OP=['ADD','SUB']
    LITERAL = ['INTEGER_LIT', 'FLOAT_LIT', 'CHAR_LIT','STRING_LIT']
    
    PRIMARY=LITERAL+['IDENTIFIER']


    def __init__(self, verbose=False):
        self.indentator = Indent(verbose)
        self.tokens = []
        self.errors = 0

    def show_next(self, n=1):
        try:
            return self.tokens[n - 1]
        except IndexError:
            print('ERROR: no more tokens left!')
            sys.exit(1)

    def expect(self, kind):
        actualToken = self.show_next()
        actualKind = actualToken.kind
        actualPosition = actualToken.position
        if actualKind == kind:
            return self.accept_it()
        else:
            print('Error at {}: expected {}, got {} instead'.format(str(actualPosition), kind, actualKind))
            sys.exit(1)

    # same as expect() but no error if not correct kind
    def maybe(self, kind):
        if self.show_next().kind == kind:
            return self.accept_it()

    def accept_it(self):
        token = self.show_next()
        output = str(token.kind) + ' ' + token.value
        self.indentator.say(output)
        return self.tokens.pop(0)

    def remove_comments(self):
        result = []
        in_comment = False
        for token in self.tokens:
            if token.kind == 'COMMENT':
                pass
            elif token.kind == 'LCOMMENT':
                in_comment = True
            elif token.kind == 'RCOMMENT':
                in_comment = False
            else:
                if not in_comment:
                    result.append(token)
        return result

    def parse(self,FileName):
        
        try:
            with open(FileName, 'r') as testFile:
                FileData = testFile.readlines()
        except FileNotFoundError:
            print('Error: test file {} does not exist'.format(FileName))
            sys.exit()
    
        lexer = Lexer()
        tokens = lexer.lex(FileData)               
        self.tokens = tokens
        self.tokens = self.remove_comments()   
        ast= Root()
        
        self.indentator.indent('Parsing Program')

# parse Hardware  
        
        hardware=self.parse_hardware()        
        ast.hardware=hardware
        
#parse network

        network=self.parse_network()
        ast.network=network
        
# service service 
        
        service=self.parse_service()        
        ast.service=service    
        
  
# parse configuration 
        

        configuration= self.parse_configuration()         
        ast.configuration=configuration
   
# parse Procssing

        self.parse_processing()                   
        self.indentator.dedent()
        if (self.errors == 1):
            print('WARNING: 1 error found!')
        elif (self.errors > 1):
            print('WARNING: ' + str(self.errors) + ' errors found!')
        else:
            print('parser: syntax analysis successful!')
            
            return ast
                        
 


    def parse_hardware(self):
        
        
        
        self.indentator.indent('Parsing Hardware')        
        
        hardware= Hardware()
        
        self.expect('HARDWARE_DECLARATION')
        
        self.expect('LBRACE')
        
        declarations=self.parse_declarations()
        
        self.expect('RBRACE') 
        
        hardware.declarations.extend(declarations)
        
        self.indentator.dedent()

        
        return hardware


    def parse_network(self):
        
        self.indentator.indent('Parsing Network')                
        
        
        network= Network()
        
        self.expect('NETWORK_DECLARATION')
        
        self.expect('LBRACE')
        
        declarations=self.parse_declarations()
        
        self.expect('RBRACE')
        
        network.declarations.extend(declarations)
        
        self.indentator.dedent()        
        
        return network
        
                
    def parse_service(self):


        self.indentator.indent('Parsing Service')                
           
        service=Service()
        
        self.expect('SERVICE_DECLARATION')
        
        self.expect('LBRACE')
        
        declarations=self.parse_declarations()
        self.expect('RBRACE')
        
        service.declarations.extend(declarations)
        
        self.indentator.dedent()
             
        return service


    def parse_configuration(self):

        self.indentator.indent('Parsing Configuration')    
        
        
        configuration=Configuration()
        
        print('ok config')
        
        self.expect('CONFIG_DECLARATION')

        self.expect('LBRACE')
        
        statements=self.parse_statements()
        
        configuration.statements.extend(statements)
        
        self.expect('RBRACE')

        self.indentator.dedent()
        
        return configuration
        
    def parse_processing(self):
        
        

        self.indentator.indent('Parsing Processing')      
        self.expect('PROCESSING_DECLARATION')
        self.expect('LBRACE')
        self.parse_statements()
        self.expect('RBRACE')        
        self.indentator.dedent()             
        

    def parse_declaration(self):

        self.indentator.indent('Parsing Declaration')    
        
        declaration=Declaration()
        
        self.accept_it()
        
        declaration.identifier =Identifier(self.expect('IDENTIFIER').value)
        
        
        self.expect('ASSIGN') 
        
        if self.show_next().kind in self.TYPE:
            
            declaration.type_=Type( self.accept_it().value)
            
            self.expect('LPAREN')  
            
            if  self.show_next().kind in self.PRIMARY:
                
                    
                  token=  self.accept_it()
                  
                  primary= Primary(token.kind,token.value)
                  
                  declaration.primaries.append(primary)
                  
            
                  while self.show_next().kind=='COMMA':
                        
                        
                        self.accept_it()
                        
        
                        if  self.show_next().kind in self.PRIMARY:
                                                                    
                             
                              token=self.accept_it()
                              
                              primary= Primary(token.kind,token.value)
                              
                              declaration.primaries.append(primary)
                              
                                 
            self.expect('RPAREN')

            
        else :
                
                self.errors+=1
                print("Error  excepts Constructor"+str(self.show_next().position))
                

            
        self.expect('SEMICOLON') 
        
        self.indentator.dedent()            

        return declaration
        
        
    def parse_declarations(self):
        
        declarations=[]
        self.indentator.indent('Parsing Declarations')

        while self.show_next().kind in self.TYPE :
            
            
            declaration=self.parse_declaration()
            declarations.append(declaration)
                        
 
            
        self.indentator.dedent() 
        
        return declarations
        

  

    def parse_statements(self):
        
        
        self.indentator.indent('Parsing Declaration')    
        
        
        self.indentator.indent('Parsing Statements')
        # TODO
        
        statements=[]
        
        while self.show_next().kind in self.STATEMENT_STARTERS:
            
            
            statements.append(self.parse_statement())
            
            
            
                       
        
        self.indentator.dedent()
        
        self.indentator.dedent() 
        
        return statements



    def parse_statement(self):
        
        self.indentator.indent('Parsing Statement ')            
        
        statement=Statement()
        

        
        
        self.indentator.indent('Parsing Statement ici')


        if self.show_next().kind=='LBRACE':
                

                self.parse_block()
                     

                
        elif self.show_next().kind=='SELECTED_NAME':
                
                
               statement.selectedobject_call_method=self.accept_it().value
               
                
               primaries=self.parse_call()
                
               statement.primaries.extend(primaries)

                
                
        else :
         raise NameError('expecting one of #{[:ident,:lparen,:literal]}. Got #{showNext.kind}')
    
        self.indentator.dedent()
        
        
        self.indentator.dedent()         
        
        return statement
  

                    
        
    def parse_call(self):
        

          self.indentator.indent('Parsing call ')               
          primaries=[]
          
          self.indentator.indent('Parsing call')
          self.expect('LPAREN')
          
          
          
            
          if  self.show_next().kind in self.PRIMARY :
                    
                    token=self.accept_it()
                    
                    primary=Primary(token.kind,token.value)
                    
                    primaries.append(primary)
                    

            
                    while self.show_next().kind=='COMMA':
                        
                        
                        self.accept_it()
                        
        
                        if  self.show_next().kind in self.PRIMARY:
                            
                             
                                token=self.accept_it()
                                
                                primary=Primary(token.kind,token.value)
                                
                                primaries.append(primary)                             
                             
                             
                     
                    self.expect('RPAREN')
        
            
          else :
                
                self.errors+=1
                print("Error  excepts Constructor"+str(self.show_next().position))
                
        
            
          self.expect('SEMICOLON') 

                  
        
        
          self.indentator.dedent()
          
          return primaries 
Example #2
0
class Parser:

    TYPE = ['INT', 'FLOAT', 'CHAR']
    STATEMENT_STARTERS = ['SEMICOLON', 'LBRACE', 'IDENTIFIER', 'IF', 'WHILE']
    ASSIGN = ["ASSIGN"]
    REL_OP = ['LT', 'LTE', 'GT', 'GTE']
    MUL_OP = ['MUL', 'DIV']
    LITERAL = ['INTEGER_LIT', 'FLOAT_LIT', 'CHAR_LIT']
    EQU_OP = ['EQU', 'NEQ']
    ADD_OP = ['ADD', 'SUB']
    UNARY_OP = ['SUB']

    def __init__(self, verbose=False):
        self.indentator = Indent(verbose)
        self.tokens = []
        self.errors = 0

    def show_next(self, n=1):
        try:
            return self.tokens[n - 1]
        except IndexError:
            print('ERROR: no more tokens left!')
            sys.exit(1)

    def expect(self, kind):
        actualToken = self.show_next()
        actualKind = actualToken.kind
        actualPosition = actualToken.position
        if actualKind == kind:
            return self.accept_it()
        else:
            print('Error at {}: expected {}, got {} instead'.format(
                str(actualPosition), kind, actualKind))
            self.errors += 1
            sys.exit(1)

    # same as expect() but no error if not correct kind
    def maybe(self, kind):
        if self.show_next().kind == kind:
            return self.accept_it()

    def accept_it(self):
        token = self.show_next()
        output = str(token.kind) + ' ' + token.value
        self.indentator.say(output)
        return self.tokens.pop(0)

    def remove_comments(self):
        result = []
        in_comment = False
        for token in self.tokens:
            if token.kind == 'COMMENT':
                pass
            elif token.kind == 'LCOMMENT':
                in_comment = True
            elif token.kind == 'RCOMMENT':
                in_comment = False
            else:
                if not in_comment:
                    result.append(token)
        return result

    def parse(self, tokens):
        self.tokens = tokens
        self.tokens = self.remove_comments()
        self.parse_program()

    def parse_program(self):
        self.indentator.indent('Parsing Program')
        self.expect('INT')
        self.expect('IDENTIFIER')
        self.expect('LPAREN')
        self.expect('RPAREN')
        self.expect('LBRACE')

        self.parse_declarations()
        self.parse_statements()

        self.expect('RBRACE')
        self.indentator.dedent()
        if (self.errors == 1):
            print('WARNING: 1 error found!')
        elif (self.errors > 1):
            print('WARNING: ' + str(self.errors) + ' errors found!')
        else:
            print('parser: syntax analysis successful!')

    def parse_declarations(self):
        self.indentator.indent('Parsing Declarations')
        while (self.show_next().kind in self.TYPE):
            self.parse_declaration()

#        while(self.show_next().kind in self.STATEMENT_STARTERS):
#            self.parse_statement()

        self.indentator.dedent()

    def parse_declaration(self):
        self.indentator.indent('Parsing Declaration')
        if (self.show_next().kind in self.TYPE):
            self.accept_it()
        self.expect('IDENTIFIER')
        if (self.show_next().kind == 'LBRACKET'):
            self.accept_it()
            self.expect('INTEGER_LIT')
            self.expect('RBRACKET')

        while (self.show_next().kind == 'COMMA'):
            self.accept_it()
            self.expect('IDENTIFIER')
            if (self.show_next().kind == 'LBRACKET'):
                self.accept_it()
                self.expect('INTEGER_LIT')
                self.expect('RBRACKET')

        self.expect('SEMICOLON')

        self.indentator.dedent()

    def parse_statements(self):
        self.indentator.indent('Parsing Statements')
        while (self.show_next().kind in self.STATEMENT_STARTERS):
            print("KIND = ", self.show_next().kind)
            self.parse_statement()
        self.indentator.dedent()

    def parse_statement(self):
        self.indentator.indent('Parsing Statement')
        print(self.tokens[-1].value)
        print(self.tokens[-1].position)

        if (self.show_next().kind == 'IF'):
            self.parse_if

        if (self.show_next().kind == 'WHILE'):
            self.parse_while

        if (self.show_next().kind == 'SEMICOLON'):
            #            self.expect('SEMICOLON')
            self.accept_it()
#            self.indentator.dedent()

        if (self.show_next().kind == 'LBRACE'):
            self.parse_block

        if (self.show_next().kind == 'IDENTIFIER'):
            self.parse_assignement

        self.indentator.dedent()

    def parse_block(self):
        self.indentator.indent('Parsing Block')
        self.expect('LBRACE')
        #        self.accept_it()
        self.parse_statements()
        self.expect('RBRACE')
        self.indentator.dedent()

    def parse_assignement(self):
        self.indentator.indent('Parsing Assignement')
        self.expect('IDENTIFIER')
        #        self.accept_it()
        if (self.show_next().kind == 'LBRACKET'):
            self.accept_it()
            self.parse_expression()
            self.expect('RBRACKET')
        self.expect('ASSIGN')
        self.parse_expression()
        self.expect("SEMICOLON")
        print("!!!!!! here !!!!!!")
        s
        self.indentator.dedent()

    def parse_if(self):
        self.indentator.indent('Parsing If')
        self.expect('IF')
        self.accept_it()
        self.expect('LPAREN')
        self.parse_expression()
        self.expect('RPAREN')
        self.parse_statement()
        if (self.show_next().kind == 'ELSE'):
            self.accept_it()
            self.parse_statement()
        self.indentator.dedent()

    def parse_while(self):
        self.indentator.indent('Parsing While')
        self.expect('WHILE')
        #        self.accept_it()
        self.expect('LPAREN')
        self.parse_expression()
        self.expect('RPAREN')
        self.parse_statement()
        self.indentator.dedent()
#        self.indentator.dedent()

    def parse_expression(self):
        self.indentator.indent('Parsing Expression')
        self.parse_conjunction()
        while (self.show_next().kind == 'DBAR'):
            self.accept_it()
            self.parse_conjunction()
        self.indentator.dedent()

    def parse_conjunction(self):
        self.indentator.indent('Parsing Conjunction')
        self.parse_equality()
        while (self.show_next().kind == 'DAMPERSAND'):
            self.accept_it()
            self.parse_equality()
        self.indentator.dedent()

    def parse_equality(self):
        self.indentator.indent('Parsing Equality')
        self.parse_relation()
        if (self.show_next().kind in self.EQU_OP):
            self.accept_it()
            self.parse_relation()
        self.indentator.dedent()

    def parse_relation(self):
        self.indentator.indent('Parsing Relation')
        self.parse_addition()
        if (self.show_next().kind in self.REL_OP):
            self.accept_it()
            self.parse_addition()
        self.indentator.dedent()

    def parse_addition(self):
        self.indentator.indent('Parsing Addition')
        self.parse_terme()
        while (self.show_next().kind in self.ADD_OP):
            self.accept_it()
            self.parse_terme()
        self.indentator.dedent()

    def parse_terme(self):
        self.indentator.indent('Parsing Terme')
        self.parse_factor()
        while (self.show_next().kind in self.MUL_OP):
            self.accept_it()
            self.parse_factor()
        self.indentator.dedent()

    def parse_factor(self):
        self.indentator.indent()
        if (self.show_next().kind in self.UNARY_OP):
            self.accept_it()
            self.parse_primary()
        else:
            self.parse_primary()
        self.indentator.dedent()

    def parse_primary(self):
        self.indentator.indent()
        #        self.expect("IDENTIFIER")
        #        kind = self.show_next().kind
        #        if kind == "IDENTIFIER":
        #            self.accept_it()
        #            if self.show_next().kind == "LBRACKET":
        #                self.accept_it()
        #                self.parse_expre

        while (self.show_next().kind == "LBRACKET"):
            self.accept_it()
            if (self.show_next().kind == "LBRACKET"):
                self.accept_it()
                self.parse_expression()
                self.expect("RBRACKET")
        while (self.show_next().kind in self.LITERAL):
            self.accept_it()

        while (self.show_next().kind == "LPAREN"):
            self.accept_it()
            self.parse_expression
            self.expect("RPAREN")

        self.indentator.dedent()
Example #3
0
 def __init__(self, verbose=False):
     self.indentator = Indent(verbose)
     self.tokens = []
     self.errors = 0
Example #4
0
class Parser:
    def __init__(self, verbose=False):
        self.indentator = Indent(verbose)
        self.tokens = []
        self.errors = 0

    def show_next(self, n=1):
        try:
            return self.tokens[n - 1]
        except IndexError:
            print('ERROR: no more tokens left!')
            sys.exit(1)

    def generate_error(self):
        chaine_ret = "Erreur :"
        for i in range(0, 85):
            chaine_ret += chr(randint(33, 126))
        print(chaine_ret)
        sys.exit(1)

    def expect(self, kind):
        if type(kind) == list:
            actualToken = self.show_next()
            actualKind = actualToken.kind
            if actualKind in kind:
                return self.accept_it()
            else:
                self.generate_error()
        else:
            actualToken = self.show_next()
            actualKind = actualToken.kind
            if actualKind == kind:
                return self.accept_it()
            else:
                self.generate_error()

    # same as expect() but no error if not correct kind
    def maybe(self, kind):
        if self.show_next().kind == kind:
            return self.accept_it()

    def accept_it(self):
        token = self.show_next()
        output = str(token.kind) + ' ' + token.value
        self.indentator.say(output)
        return self.tokens.pop(0)

    def remove_comments(self):
        result = []
        in_comment = False
        for token in self.tokens:
            if token.kind == 'COMMENT':
                pass
            elif token.kind == 'LCOMMENT':
                in_comment = True
            elif token.kind == 'RCOMMENT':
                in_comment = False
            else:
                if not in_comment:
                    result.append(token)
        return result

    #PARSE GLOBAL
    def parse(self, tokens):
        self.tokens = tokens
        self.tokens = self.remove_comments()
        self.calcul_politesse(tokens)
        self.parse_program()

    def calcul_politesse(self, tokens):
        nombrePlease = 0
        for i in tokens:
            if (i == "please"):
                nombrePlease += 1
        ratio = nombrePlease / len(tokens)
        if (ratio < 0.05 or ratio > 0.2):
            #self.generate_error()
            pass

    #PARSE DU PROGRAMME
    def parse_program(self):
        self.indentator.indent('Parsing Program')

        self.parse_typedefs()
        self.parse_structures()
        self.parse_functions()
        ###

        #réservé au main
        self.expect('ENTIER')
        self.expect('IDENTIFIER')
        self.expect('LPAREN')
        self.expect('RPAREN')
        self.expect('LPAREN')
        #print(self.show_next())
        if (self.show_next().kind == 'VIRGULE'):
            self.accept_it()
            self.expect('PLEASE')
        self.expect('POINT')
        #print(self.show_next())

        self.parse_declarations()

        self.parse_statements()

        self.expect('RPAREN')
        self.expect('POINT')
        self.indentator.dedent()
        if (self.errors == 1):
            print('WARNING: 1 error found!')
        elif (self.errors > 1):
            print('WARNING: ' + str(self.errors) + ' errors found!')
        else:
            print('parser: syntax analysis successful!')

    #PARSE ENSEMBLE DE DECLARATIONS
    def parse_declarations(self):
        self.indentator.indent('Parsing Declarations')
        while (self.show_next().kind in TYPE):
            self.parse_declaration()
            #self.expect('POINT')
        self.indentator.dedent()

    #PARSE UNE DECLARATION
    def parse_declaration(self):
        self.indentator.indent('Parsing Declaration')
        self.expect(TYPE)
        self.expect('IDENTIFIER')
        if self.show_next().kind == 'LPAREN':
            self.accept_it()
            self.expect('ENTIER_LIT')
            self.expect('RPAREN')
        while self.show_next().kind == 'POINTVIRGULE':
            self.accept_it()
            self.expect('IDENTIFIER')
            if self.show_next().kind == 'LPAREN':
                self.accept_it()
                self.expect('ENTIER_LIT')
                self.expect('RPAREN')
        self.expect('POINT')
        self.indentator.dedent()

    #PARSE UN ENSEMBLE DE STATEMENTS
    def parse_statements(self):
        while (self.show_next().kind in STATEMENT_STARTERS
               or self.show_next().kind in BREAKER
               or self.show_next().kind == 'VIRGULE'):
            self.indentator.indent('Parsing statements')
            self.parse_statement()
            self.indentator.dedent()
            #print("==>", self.show_next().kind)

    #PARSE UN STATEMENT
    def parse_statement(self):
        self.indentator.indent('Parsing Statement')

        if (self.show_next().kind == 'POINT'):
            self.accept_it()
        if (self.show_next().kind == 'RPAREN'):
            self.accept_it()
            self.expect('POINT')
        if (self.show_next().kind == 'VIRGULE'):
            self.accept_it()
            self.expect('PLEASE')
            self.expect('POINT')
        elif (self.show_next().kind == 'LPAREN'):
            self.accept_it()
            self.parse_block()

        elif (self.show_next().kind == 'IDENTIFIER'):
            self.accept_it()
            self.parse_assignement()

        elif (self.show_next().kind in BREAKER):
            self.parse_breaker()

        elif (self.show_next().kind == 'SI'):
            self.parse_if()
            while (self.show_next().kind in STATEMENT_STARTERS
                   or self.show_next().kind in BREAKER
                   or self.show_next().kind == 'IDENTIFIER'
                   or self.show_next().kind == 'POINT'):
                self.parse_statement()
            self.expect('RPAREN')
            self.expect('POINT')
            if (self.show_next().kind == 'SINON'):
                self.accept_it()
                if (self.show_next().kind == 'LPAREN'):
                    self.accept_it()
                    while (self.show_next().kind in STATEMENT_STARTERS):
                        self.parse_statement()
                elif (self.show_next().kind == 'SI'):
                    self.parse_if()
                    while (self.show_next().kind in STATEMENT_STARTERS):
                        self.parse_statement()

        elif (self.show_next().kind == 'TANTQUE'):
            self.parse_while()
            while (self.show_next().kind in STATEMENT_STARTERS
                   or self.show_next().kind == 'IDENTIFIER'):
                self.parse_statement()
            #print('===|>', self.show_next())
            self.expect('RPAREN')
            self.expect('POINT')
            #print(self.show_next())

        else:
            print('Error parse statement')
            sys.exit(1)
        """
        print("---")
        print(self.show_next())
        print(self.show_next(2))
        print("---")
        """
        self.indentator.dedent()

    #PARSE UN BLOCK
    def parse_block(self):
        self.indentator.indent('Parsing block')
        self.expect('LPAREN')
        self.parse_statements()
        self.expect('RPAREN')
        self.indentator.dedent()

    #PARSE CONDITION IF
    def parse_if(self):
        self.indentator.indent('Parsing if')
        self.accept_it()
        self.expect('LPAREN')
        self.parse_expressions()
        self.expect('RPAREN')
        self.expect('LPAREN')
        self.expect('POINT')
        self.indentator.dedent()

    #PARSE BOUCLE WHILE
    def parse_while(self):
        self.indentator.indent('Parsing while')
        self.accept_it()
        self.expect('LPAREN')
        self.parse_expressions()
        self.expect('RPAREN')
        self.expect('LPAREN')
        self.expect('POINT')
        self.indentator.dedent()

    def parse_expressions(self):
        self.indentator.indent('Parsing expressions')
        self.parse_expression()
        while (self.show_next().kind in MORE):
            self.accept_it()
            self.parse_expression()
        self.indentator.dedent()

    #PARSE UNE EXPRESSION DE CONDITION (ex : dans une condition de if)
    def parse_expression(self):
        self.indentator.indent('Parsing expression')
        if (self.show_next().kind in LITERAL):
            val = self.show_next().kind
            self.accept_it()
            if (self.show_next().kind in REL_OP
                    or self.show_next().kind in MUL_OP):
                self.accept_it()
                if (self.show_next().kind == val):
                    self.accept_it()
                elif (self.show_next().kind == 'IDENTIFIER'):
                    self.accept_it()
                else:
                    self.generate_error()
            else:
                self.generate_error()
        elif (self.show_next().kind == 'IDENTIFIER'):
            self.accept_it()
            if (self.show_next().kind in REL_OP):
                self.accept_it()
                if (self.show_next().kind in LITERAL):
                    self.accept_it()
                elif (self.show_next().kind == 'IDENTIFIER'):
                    self.accept_it()
                else:
                    self.generate_error()
        else:
            self.generate_error()
        self.indentator.dedent()

    #PARSE UNE ASSIGNATION (ex : a = a * 2)
    def parse_assignement(self):
        self.indentator.indent('Parsing assignement')
        cpt_parentheses = 0  #compteur qui va nous servir a detecter un "unbalanced parenthesis"
        while (self.show_next().kind in OP or self.show_next().kind in LITERAL
               or self.show_next().kind in PAREN
               or self.show_next().kind == 'IDENTIFIER'):
            if (self.show_next().kind == 'LPAREN'):
                cpt_parentheses += 1
            elif (self.show_next().kind == 'RPAREN'):
                cpt_parentheses -= 1
            self.accept_it()
        if self.show_next().kind == 'VIRGULE':
            self.accept_it()
            self.expect('PLEASE')
        self.expect('POINT')
        if (cpt_parentheses != 0):
            self.generate_error()
        self.indentator.dedent()

    def parse_structures(self):
        self.indentator.indent('Parsing structures')
        while (self.show_next().kind == 'STRUCTURE'):
            self.expect('STRUCTURE')
            self.expect('IDENTIFIER')
            self.expect('LPAREN')
            self.parse_declarations()
            self.expect('RPAREN')
            self.expect('POINT')
        self.indentator.dedent()

    def parse_typedefs(self):
        self.indentator.indent('Parsing typedefs')
        while (self.show_next().kind == 'TYPEDEF'):
            self.expect('TYPEDEF')
            for i in range(2):
                if self.show_next().kind in TYPE or self.show_next(
                ).kind == 'IDENTIFIER' or self.show_next().kind == 'UNSIGNED':
                    if self.show_next().kind == 'UNSIGNED':
                        self.accept_it()
                        if self.show_next().kind in TYPE or self.show_next(
                        ).kind == 'IDENTIFIER':
                            self.accept_it()
                        else:
                            self.generate_error()
                    else:
                        self.accept_it()
            self.expect('SEMICOLON')
        self.indentator.dedent()

    def parse_breaker(self):
        self.indentator.indent('Parsing breaker')
        self.accept_it()
        self.expect('SEMICOLON')
        self.indentator.dedent()

    def parse_functions(self):
        while self.show_next(2).value != 'main' and self.show_next(
                2).kind == 'IDENTIFIER' and self.show_next(3).kind == 'LPAREN':
            if self.show_next().kind in TYPE: self.accept_it()
            self.expect('IDENTIFIER')
            self.expect('LPAREN')
            if self.show_next().kind in TYPE:
                self.accept_it()
                self.expect('IDENTIFIER')
            while self.show_next().kind == 'COMMA':
                self.accept_it()
                #if self.show_next().kind in TYPE: self.accept_it()
                self.expect(TYPE)
                self.expect('IDENTIFIER')
            self.expect('RPAREN')
            self.expect('LBRACE')

            self.parse_declarations()
            self.parse_statements()

            self.expect('RBRACE')
Example #5
0
class Parser:

    OP = ['ADD', 'SUB', 'MUL', 'DIV']
    EXPR = ['INTEGER_LIT', 'IDENTIFIER']

    def __init__(self, verbose=False):
        self.AST = None
        self.indentator = Indent(verbose)
        self.tokens = []
        self.errors = 0

    def show_next(self, n=1):
        try:
            return self.tokens[n - 1]
        except IndexError:
            print('ERROR: no more tokens left!')
            sys.exit(1)

    def expect(self, kind):
        actualToken = self.show_next()
        actualKind = actualToken.kind
        actualPosition = actualToken.position
        if actualKind == kind:
            return self.accept_it()
        else:
            print('Error at {}: expected {}, got {} instead'.format(
                str(actualPosition), kind, actualKind))
            sys.exit(1)

    # same as expect() but no error if not correct kind
    def maybe(self, kind):
        if self.show_next().kind == kind:
            return self.accept_it()

    def accept_it(self):
        token = self.show_next()
        output = str(token.kind) + ' ' + token.value
        self.indentator.say(output)
        return self.tokens.pop(0)

    def parse(self, tokens):
        self.tokens = tokens
        self.parse_program()

    def parse_program(self):
        self.indentator.indent('Parsing Program')

        self.expect('SYSTEME')
        self.AST = Systeme()
        self.expect('LBRACE')
        self.parse_declarations()
        self.expect('RBRACE')
        self.indentator.dedent()
        if (self.errors == 1):
            print('WARNING: 1 error found!')
        elif (self.errors > 1):
            print('WARNING: ' + str(self.errors) + ' errors found!')
        else:
            print('parser: syntax analysis successful!')

    def parse_declarations(self):
        self.indentator.indent('Parsing Declarations')
        actualToken = self.show_next()
        actualKind = actualToken.kind
        while actualKind != 'RBRACE':
            self.AST.equations.append(Equation())  #Ajout D'une Equation
            self.parse_declaration()
            actualToken = self.show_next()
            actualKind = actualToken.kind
        self.indentator.dedent()

    def parse_declaration(self):
        if self.show_next().kind == 'RBRACE':
            return ()
        self.parse_membreGauche()
        self.expect('ASSIGN')
        self.parse_assignment()

    def parse_membreGauche(self):
        self.AST.equations[-1].left = Relation()  #Ajout d'un relation
        actualToken = self.show_next()
        actualKind = actualToken.kind
        if actualKind == 'SUB':
            self.accept_it()
            for kind in Parser.EXPR:
                if self.show_next().kind == kind:

                    if kind == 'INTEGER_LIT':
                        self.AST.equations[-1].left.list_expr.append(
                            Int(-int(self.show_next().value)))
                    if kind == 'IDENTIFIER':
                        self.AST.equations[-1].left.list_expr.append(
                            Identifier(self.show_next().value, True))
                    self.expect(kind)

        while self.show_next().kind != 'ASSIGN':
            self.parse_expression(self.AST.equations[-1].left)

    def parse_assignment(self):
        actualToken = self.show_next()
        actualKind = actualToken.kind
        self.AST.equations[-1].right = Relation()
        if actualKind == 'SUB':
            self.accept_it()
            for kind in Parser.EXPR:
                if self.show_next().kind == kind:
                    if kind == 'INTEGER_LIT':
                        self.AST.equations[-1].right.list_expr.append(
                            Int(-int(self.show_next().value)))
                    if kind == 'IDENTIFIER':
                        self.AST.equations[-1].right.list_expr.append(
                            Identifier(self.show_next().value, True))
                    self.expect(kind)

        while self.show_next().kind != 'SEMICOLON':
            self.parse_expression(self.AST.equations[-1].right)
        self.expect('SEMICOLON')

    def parse_expression(self, relation):
        if self.show_next().kind == 'LPAREN':
            relation.list_expr.append(
                Relation()
            )  #ouverture d'une nouvelle relation dans la relation superieure car parentheses
            self.expect('LPAREN')
            if self.show_next().kind == 'MUL' or self.show_next(
            ).kind == 'DIV':
                actualToken = self.show_next()
                actualKind = actualToken.kind
                actualPosition = actualToken.position
                print('Error at {}: No expected {} after LPAREN'.format(
                    str(actualPosition), actualKind))
                sys.exit(1)
            while self.show_next().kind != 'RPAREN':
                self.parse_expression(relation.list_expr[-1])
            self.expect('RPAREN')

        expectEXPR = False
        for kind in Parser.OP:
            if self.show_next().kind == kind:
                if relation.list_operateur == None:
                    relation.list_operateur = []
                relation.list_operateur.append(kind)
                self.expect(kind)
                expectEXPR = True

        for kind in Parser.EXPR:
            if self.show_next().kind == kind:
                if kind == 'INTEGER_LIT':
                    relation.list_expr.append(Int(int(self.show_next().value)))
                if kind == 'IDENTIFIER':
                    relation.list_expr.append(
                        Identifier(self.show_next().value))
                self.expect(kind)
                expectEXPR = False
        if expectEXPR:
            actualToken = self.show_next()
            actualPosition = actualToken.position
            print('Error at {}: expected IDENTIFIER or INTEGER_LIT after OP '.
                  format(str(actualPosition)))
            sys.exit(1)

    def check_linear(self):
        for i in range(len(self.AST.equations)):
            equation_i = self.AST.equations[i]
            a = self.cherche(equation_i.left)
            b = self.cherche(equation_i.right)
            if a >= 2 or b >= 2:
                return (False)
        return (True)

    def cherche(self, relation):
        type_relation = type(Relation())
        type_identifier = type(Identifier("e"))
        if len(relation.list_operateur) == 0:
            return (0)
        for j in range(len(relation.list_operateur)):
            if relation.list_operateur[j] == 'MUL' or relation.list_operateur[
                    j] == 'DIV':
                g = relation.list_expr[j]
                d = relation.list_expr[j + 1]
                if type(g) != type_relation and type(d) != type_relation:
                    if type(g) == type_identifier and type(
                            d) == type_identifier:
                        return (2)
                elif type(g) != type_relation:
                    if type(g) == type_identifier:
                        return (1 + self.cherche(d))
                    else:
                        return (self.cherche(d))
                elif type(d) != type_relation:
                    if type(d) == type_identifier:
                        return (1 + self.cherche(g))
                    else:
                        return (self.cherche(g))
                else:
                    return (self.cherche(g) + self.cherche(d))
            else:
                for x in relation.list_expr:
                    if type(x) == type_identifier:
                        return (1)
                return (0)
Example #6
0
class Parser:

    TYPE = ['WIND', 'RAINFALL', 'SUN', 'CLOUD']
    STATEMENT_STARTERS = ['SEMICOLON', 'IDENTIFIER', 'IN', 'AT', 'MAP']
    DIR = ['NORTH', 'SOUTH', 'EAST', 'WEST']
    TYPE_CLOUD = ['CIRRUS', 'CUMULUS', 'CUMULONIMBUS']
    TYPE_RAINFALL = ['PLUIE', 'NEIGE']
    TYPE_INTENS = ['FORTE', 'FAIBLE', 'NORMALE']

    ALL_VAR = [
        'TYPE_CLOUD', 'POSITION', 'DUREE', 'INTENSITE', 'UV', 'TYPE_RAIN',
        'VITESSE', 'DIRECTION'
    ]
    CLOUD = ['TYPE_CLOUD', 'POSITION', 'DUREE']
    SUN = ['UV', 'POSITION', 'DUREE']
    WIND = ['VITESSE', 'DIRECTION', 'POSITION', 'DUREE']
    RAINFALL = ['TYPE_RAIN', 'POSITION', 'DUREE', 'INTENSITE']

    REL_OP = ['DOT', 'MOVE', 'ASSIGN', 'COLON', 'DEL']

    def __init__(self, verbose=False):
        self.indentator = Indent(verbose)
        self.tokens = []
        self.errors = 0

    def show_next(self, n=1):
        try:
            return self.tokens[n - 1]
        except IndexError:
            print('ERROR: no more tokens left!')
            sys.exit(1)

    def expect(self, kind):
        actualToken = self.show_next()
        actualKind = actualToken.kind
        actualPosition = actualToken.position
        if actualKind == kind:
            return self.accept_it()
        else:
            print('Error at {}: expected {}, got {} instead'.format(
                str(actualPosition), kind, actualKind))
            sys.exit(1)

    # same as expect() but no error if not correct kind
    def maybe(self, kind):
        if self.show_next().kind == kind:
            return self.accept_it()

    def accept_it(self):
        token = self.show_next()
        output = str(token.kind) + ' ' + token.value
        self.indentator.say(output)
        return self.tokens.pop(0)

    def remove_comments(self):
        result = []
        in_comment = False
        for token in self.tokens:
            if token.kind == 'LCOMMENT':
                in_comment = True
            elif token.kind == 'RCOMMENT':
                in_comment = False
            else:
                if not in_comment:
                    result.append(token)
        return result

    def parse(self, tokens):
        self.tokens = tokens
        self.tokens = self.remove_comments()
        return self.parse_program()

    def parse_program(self):
        self.indentator.indent('Parsing Program')
        declarations = self.parse_declarations()

        self.expect('MAIN')
        stats = self.parse_statements()
        self.indentator.dedent()

        AST_Root = ast.Program(declarations, stats)

        if (self.errors == 1):
            print('WARNING: 1 error found!')
        elif (self.errors > 1):
            print('WARNING: ' + str(self.errors) + ' errors found!')
        else:
            print('parser: syntax analysis successful!')

        return AST_Root

    def parse_declarations(self):
        declarations = []
        self.indentator.indent('Parsing Declarations')
        while self.show_next().kind == 'IDENTIFIER':
            varName = self.show_next().value
            self.accept_it()
            aDecl = self.parse_declaration(varName)
            declarations.append(aDecl)
        self.indentator.dedent()

        return declarations

    def parse_declaration(self, varName):
        self.indentator.indent('Parsing Declaration of {}'.format(varName))
        self.expect('ASSIGN')
        if self.show_next().kind == 'WIND':
            self.accept_it()
            aDecl = self.parse_wind(varName)
        elif self.show_next().kind == 'SUN':
            self.accept_it()
            aDecl = self.parse_sun(varName)
        elif self.show_next().kind == 'CLOUD':
            self.accept_it()
            aDecl = self.parse_cloud(varName)
        elif self.show_next().kind == 'RAINFALL':
            self.accept_it()
            aDecl = self.parse_rainfall(varName)
        self.indentator.dedent()

        return aDecl

    def parse_wind(self, varName):
        self.indentator.indent('Parsing Wind')
        self.expect('LBRACE')
        params = self.parse_vars_wind()
        self.expect('RBRACE')
        windDecl = ast.windDecl(varName, params)
        self.indentator.dedent()

        return windDecl

    def parse_vars_wind(self):
        params = []
        self.indentator.indent('Parsing Vars_wind')
        if self.show_next().kind in self.WIND:
            param = self.parse_var_wind()
            params.append(param)
        while self.show_next().kind == 'SEMICOLON':
            self.accept_it()
            param = self.parse_var_wind()
            params.append(param)
        self.indentator.dedent()

        return params

    def parse_var_wind(self):
        self.indentator.indent('Parsing Var_wind')
        if self.show_next().kind == 'POSITION':
            param = self.parse_position()
        elif self.show_next().kind == 'VITESSE':
            param = self.parse_vitesse()
        elif self.show_next().kind == 'DUREE':
            param = self.parse_duree()
        elif self.show_next().kind == 'DIRECTION':
            param = self.parse_direction()
        self.indentator.dedent()

        return param

    def parse_sun(self, varName):
        self.indentator.indent('Parsing Sun')
        self.expect('LBRACE')
        params = self.parse_vars_sun()
        self.expect('RBRACE')
        sunDecl = ast.sunDecl(varName, params)
        self.indentator.dedent()

        return sunDecl

    def parse_vars_sun(self):
        params = []
        self.indentator.indent('Parsing Vars_sun')
        if self.show_next().kind in self.SUN:
            param = self.parse_var_sun()
            params.append(param)
        while self.show_next().kind == 'SEMICOLON':
            self.accept_it()
            param = self.parse_var_sun()
            params.append(param)
        self.indentator.dedent()

        return params

    def parse_var_sun(self):
        self.indentator.indent('Parsing Var_sun')
        if self.show_next().kind == 'POSITION':
            param = self.parse_position()
        elif self.show_next().kind == 'UV':
            param = self.parse_uv()
        elif self.show_next().kind == 'DUREE':
            param = self.parse_duree()
        self.indentator.dedent()

        return param

    def parse_cloud(self, varName):
        self.indentator.indent('Parsing Cloud')
        self.expect('LBRACE')
        params = self.parse_vars_cloud()
        self.expect('RBRACE')
        cloudDecl = ast.cloudDecl(varName, params)
        self.indentator.dedent()

        return cloudDecl

    def parse_vars_cloud(self):
        params = []
        self.indentator.indent('Parsing Vars_cloud')
        if self.show_next().kind in self.CLOUD:
            param = self.parse_var_cloud()
            params.append(param)
        while self.show_next().kind == 'SEMICOLON':
            self.accept_it()
            param = self.parse_var_cloud()
            params.append(param)
        self.indentator.dedent()

        return params

    def parse_var_cloud(self):
        self.indentator.indent('Parsing Var_cloud')
        if self.show_next().kind == 'POSITION':
            param = self.parse_position()
        elif self.show_next().kind == 'TYPE_CLOUD':
            param = self.parse_type_cloud()
        elif self.show_next().kind == 'DUREE':
            param = self.parse_duree()
        self.indentator.dedent()

        return param

    def parse_rainfall(self, varName):
        self.indentator.indent('Parsing Rainfall')
        self.expect('LBRACE')
        params = self.parse_vars_rainfall()
        self.expect('RBRACE')
        RFDecl = ast.RFDecl(varName, params)
        self.indentator.dedent()

        return RFDecl

    def parse_vars_rainfall(self):
        params = []
        self.indentator.indent('Parsing Vars_rainfall')
        if self.show_next().kind in self.RAINFALL:
            param = self.parse_var_rainfall()
            params.append(param)
        while self.show_next().kind == 'SEMICOLON':
            self.accept_it()
            param = self.parse_var_rainfall()
            params.append(param)
        self.indentator.dedent()

        return params

    def parse_var_rainfall(self):
        self.indentator.indent('Parsing Var_rainfall')
        if self.show_next().kind == 'POSITION':
            param = self.parse_position()
        elif self.show_next().kind == 'INTENSITE':
            param = self.parse_intensite()
        elif self.show_next().kind == 'DUREE':
            param = self.parse_duree()
        elif self.show_next().kind == 'TYPE_RAIN':
            param = self.parse_type_rainfall()
        self.indentator.dedent()

        return param

    def parse_direction(self):
        self.indentator.indent('Parsing Direction')
        self.expect('DIRECTION')
        self.expect('COLON')
        if self.show_next().kind in self.DIR:
            value = self.show_next().value
            self.accept_it()
            param = ast.Parameter("direction", value)
        self.indentator.dedent()

        return param

    def parse_duree(self):
        self.indentator.indent('Parsing Duree')
        self.expect('DUREE')
        self.expect('COLON')
        value = self.show_next().value
        self.expect('INT')
        param = ast.Parameter("duree", value)
        self.indentator.dedent()

        return param

    def parse_position(self):
        self.indentator.indent('Parsing Position')
        self.expect('POSITION')
        self.expect('COLON')
        value = self.parse_coord()
        param = ast.Parameter("position", value)
        self.indentator.dedent()

        return param

    def parse_coord(self):
        self.indentator.indent('Parsing Coordinates')
        self.expect('LPAREN')
        valueX = self.show_next().value
        self.expect('INT')
        self.expect('COMMA')
        valueY = self.show_next().value
        self.expect('INT')
        self.expect('RPAREN')
        self.indentator.dedent()

        return (valueX, valueY)

    def parse_vitesse(self):
        self.indentator.indent('Parsing Vitesse')
        self.expect('VITESSE')
        self.expect('COLON')
        value = self.show_next().value
        self.expect('INT')
        param = ast.Parameter("vitesse", value)
        self.indentator.dedent()

        return param

    def parse_type_cloud(self):
        self.indentator.indent('Parsing Type_could')
        self.expect('TYPE_CLOUD')
        self.expect('COLON')
        if self.show_next().kind in self.TYPE_CLOUD:
            value = self.show_next().value
            self.accept_it()
            param = ast.Parameter("typeCloud", value)
        self.indentator.dedent()

        return param

    def parse_type_rainfall(self):
        self.indentator.indent('Parsing Type_rainfall')
        self.expect('TYPE_RAIN')
        self.expect('COLON')
        if self.show_next().kind in self.TYPE_RAINFALL:
            value = self.show_next().value
            self.accept_it()
            param = ast.Parameter("typeRain", value)
        self.indentator.dedent()

        return param

    def parse_uv(self):
        self.indentator.indent('Parsing Uv')
        self.expect('UV')
        self.expect('COLON')
        value = self.show_next().value
        self.expect('INT')
        param = ast.Parameter("uv", value)
        self.indentator.dedent()

        return param

    def parse_intensite(self):
        self.indentator.indent('Parsing Intensite')
        self.expect('INTENSITE')
        self.expect('COLON')
        if self.show_next().kind in self.TYPE_INTENS:
            value = self.show_next().value
            self.accept_it()
            param = ast.Parameter("intensite", value)
        self.indentator.dedent()

        return param

    def parse_statements(self):
        statements = []
        self.indentator.indent('Parsing Statements')
        while self.show_next().kind in self.STATEMENT_STARTERS:
            statement = self.parse_statement()
            statements.append(statement)
        self.expect('ENDMAIN')
        self.indentator.dedent()

        return statements

    def parse_statement(self):

        self.indentator.indent('Parsing Statement')
        if self.show_next().kind == 'SEMICOLON':
            self.accept_it()
        elif self.show_next().kind == 'IDENTIFIER':
            statement = self.parse_expression()
        elif self.show_next().kind == 'AT':
            statement = self.parse_atstatement()
        elif self.show_next().kind == 'IN':
            statement = self.parse_instatement()
        elif self.show_next().kind == 'MAP':
            statement = self.parse_map()
        self.indentator.dedent()

        return statement

        #####

    def parse_atstatement(self):
        self.indentator.indent('Parsing AtStatement')
        self.expect('AT')
        self.expect('BAR')
        time = self.show_next().value
        self.expect('INT')
        self.expect('LBRACKET')
        expressions = []
        exp = self.parse_expression()
        expressions.append(exp)
        while self.show_next().kind == 'SEMICOLON':
            self.accept_it()
            exp = self.parse_expression()
            expressions.append(exp)
        atStat = ast.atStatement(time, expressions)
        self.expect('RBRACKET')
        self.indentator.dedent()

        return atStat

    def parse_instatement(self):
        self.indentator.indent('Parsing InStatement')
        self.expect('IN')
        self.expect('BAR')
        start = self.show_next().value
        self.expect('INT')
        self.expect('SUB')
        finish = self.show_next().value
        self.expect('INT')
        self.expect('LBRACKET')
        expressions = []
        exp = self.parse_expression()
        expressions.append(exp)
        while self.show_next().kind == 'SEMICOLON':
            self.accept_it()
            exp = self.parse_expression()
            expressions.append(exp)
        inStat = ast.inStatement(start, finish, expressions)
        self.expect('RBRACKET')
        self.indentator.dedent()

        return inStat

    def parse_map(self):
        self.indentator.indent('Parsing Map')
        self.expect('MAP')
        self.expect('LBRACKET')
        displayed = []
        while (self.show_next().kind == 'IDENTIFIER'):
            displayed.append(self.show_next().value)
            self.accept_it()
            if self.show_next().kind == 'SEMICOLON':
                self.accept_it()
        self.expect('DBAR')
        longit = self.show_next().value
        self.expect('LATLONG')
        if self.show_next().kind == 'SEMICOLON':
            self.accept_it()
        latit = self.show_next().value
        self.expect('LATLONG')
        longlat = (longit, latit)
        self.expect('DBAR')
        dimX = self.show_next().value
        self.expect('INT')
        if self.show_next().kind == 'SEMICOLON':
            self.accept_it()
        dimY = self.show_next().value
        self.expect('INT')
        dims = (dimX, dimY)
        self.expect('RBRACKET')
        self.indentator.dedent()

        return ast.mapStatement(displayed, longlat, dims)

    def parse_expression(self):
        self.indentator.indent('Parsing Expression')
        ident = self.show_next().value
        self.expect('IDENTIFIER')
        ope = self.parse_term(ident)
        self.indentator.dedent()

        return ast.Expression(ident, ope)

    def parse_term(self, ident):
        self.indentator.indent('Parsing Term')
        if self.show_next().kind == 'DOT':
            ope = self.parse_dot()
        elif self.show_next().kind == 'ASSIGN':
            ope = ast.assignOperation(self.parse_declaration(ident))
        elif self.show_next().kind == 'DEL':
            ope = ast.delOperation()
            self.accept_it()
        elif self.show_next().kind == 'MOVE':
            ope = self.parse_move()
        self.indentator.dedent()

        return ope

    def parse_dot(self):
        self.indentator.indent('Parsing dot')
        self.expect('DOT')
        if self.show_next().kind == 'POSITION':
            param = self.parse_position()
        elif self.show_next().kind == 'INTENSITE':
            param = self.parse_intensite()
        elif self.show_next().kind == 'DUREE':
            param = self.parse_duree()
        elif self.show_next().kind == 'TYPE_RAINFALL':
            param = self.parse_type_rainfall()
        elif self.show_next().kind == 'TYPE_CLOUD':
            param = self.parse_type_cloud()
        elif self.show_next().kind == 'DIRECTION':
            param = self.parse_direction()
        elif self.show_next().kind == 'VITESSE':
            param = self.parse_vitesse()
        self.indentator.dedent()

        return ast.dotOperation(param)

    def parse_move(self):
        self.indentator.indent('Parsing move')
        self.expect('MOVE')
        coords = self.parse_coord()
        param = ast.Parameter("position", coords)
        self.indentator.dedent()

        return ast.moveOperation(param)
Example #7
0
class Parser:

    TYPE = ['INT', 'FLOAT', 'CHAR']
    STATEMENT_STARTERS = ['SEMICOLON', 'LBRACE', 'IDENTIFIER', 'IF', 'WHILE']
    REL_OP = ['LT', 'LTE', 'GT', 'GTE','EQ']
    MUL_OP = ['MUL', 'DIV']
    ASSIGN_OP = ['ASSIGN']
    LITERAL = ['INTEGER_LIT', 'FLOAT_LIT', 'CHAR_LIT']

    def __init__(self, verbose=False):
        self.indentator = Indent(verbose)
        self.tokens = []
        self.errors = 0

    def show_next(self, n=1):
        try:
            return self.tokens[n - 1]
        except IndexError:
            print('ERROR: no more tokens left!')
            sys.exit(1)

    def expect(self, kind):
        actualToken = self.show_next()
        actualKind = actualToken.kind
        actualPosition = actualToken.position
        if actualKind == kind:
            return self.accept_it()
        else:
            print('Error at {}: expected {}, got {} instead'.format(str(actualPosition), kind, actualKind))
            sys.exit(1)

    # same as expect() but no error if not correct kind
    def maybe(self, kind):
        if self.show_next().kind == kind:
            return self.accept_it()

    def accept_it(self):
        token = self.show_next()
        output = str(token.kind) + ' ' + token.value
        self.indentator.say(output)
        return self.tokens.pop(0)

    def remove_comments(self):
        result = []
        in_comment = False
        for token in self.tokens:
            if token.kind == 'COMMENT':
                pass
            elif token.kind == 'LCOMMENT':
                in_comment = True
            elif token.kind == 'RCOMMENT':
                in_comment = False
            else:
                if not in_comment:
                    result.append(token)
        return result

    def parse(self, tokens):
        self.tokens = tokens
        self.tokens = self.remove_comments()
        self.parse_program()

    def parse_program(self):
        #print(self.tokens)
        self.indentator.indent('Parsing Program')
        self.expect('INT')
        self.expect('IDENTIFIER')
        self.expect('LPAREN')
        self.expect('RPAREN')
        self.expect('LBRACE')

        self.parse_declarations()
        self.parse_statements()

        self.expect('RBRACE')
        self.indentator.dedent()
        if (self.errors == 1):
            print('WARNING: 1 error found!')
        elif (self.errors > 1):
            print('WARNING: ' + str(self.errors) + ' errors found!')
        else:
            print('parser: syntax analysis successful!')

    def parse_declarations(self):
        self.indentator.indent('Parsing Declarations')
        
        while self.show_next().kind in self.TYPE :

            self.parse_declaration()

        
        self.indentator.dedent()


    def parse_declaration(self):
        self.indentator.indent('Parsing Declaration')

        if self.show_next().kind in self.TYPE :

            self.accept_it()
            dec = Declaration()
            
        self.expect('IDENTIFIER')
        
        if self.show_next().kind == 'LBRACKET' :

            self.expect('LBRACKET')
            self.expect('INTEGER_LIT')
            self.expect('RBRACKET')

        while self.show_next().kind == 'COMMA':
            
            self.expect('COMMA')
            self.expect('IDENTIFIER')
            
            if self.show_next().kind == 'LBRACKET' :
                
                self.expect('LBRACKET')
                self.expect('INTEGER_LIT')
                self.expect('RBRACKET')

        self.expect('SEMICOLON')
        
        self.indentator.dedent()

        return()

        
    def parse_statements(self):
        self.indentator.indent('Parsing Statements')
        
        while self.show_next().kind in self.STATEMENT_STARTERS :
           
            self.parse_statement()

        self.indentator.dedent()

    def parse_statement(self):
        self.indentator.indent('Parsing Statements')
        
        if self.show_next().kind == 'IF':
            self.parse_if()
        if self.show_next().kind == 'WHILE':
            self.parse_statementwhile()
        if self.show_next().kind == 'LBRACE':
            self.parse_block()
        if self.show_next().kind == 'SEMICOLON':
            self.accept_it()
        if self.show_next().kind == 'IDENTIFIER'
            self.parse_assignement()

        self.indentator.dedent()

    def parse_if(self): #DONE

        self.indentator.indent('Parsing Declaration')
        self.expect('LPAREN')
        self.parse_expression()
        self.expect('RPAREN')
        self.parse_statement()

        if show_next().kind == 'ELSE':
            self.accept_it()
            self.parse_statement()

        self.indentator.dedent()

    def parse_expression(self):

        self.indentator.indent('Parsing Expression')

    def parse_assignement(self):

        self.indentator.indent('Parsing Assignement')
        self.expect('IDENTIFIER')

        self.expect('ASSIGN')

        self.parse_expression()
        self.expect('SEMICOLON')



    def parse_block(self): #DONE
        self.indentator.indent('Parsing Block')
        self.expect('LBRACE')
        self.parse_statements()
        self.expect('RBRACE')

        self.indetator.dedent()
Example #8
0
class Parser:

    TYPE = ['INT', 'FLOAT', 'CHAR','BOOL']
    STATEMENT_STARTERS = ['SEMICOLON', 'LBRACE', 'IDENTIFIER', 'IF', 'WHILE']
    REL_OP = ['LT', 'LTE', 'GT', 'GTE']
    NUM_OP = ['ADD','SUB']
    MUL_OP = ['MUL', 'DIV']
    LITERAL = ['INTEGER_LIT', 'FLOAT_LIT', 'CHAR_LIT']
    declarations_count = 0
    def __init__(self, verbose=False):
        self.indentator = Indent(True)
        self.tokens = []
        self.errors = 0

    def show_next(self, n=1):
        try:
            return self.tokens[n - 1]
        except IndexError:
            print('ERROR: no more tokens left!')
            sys.exit(1)

    def expect(self, kind):
        actualToken = self.show_next()
        actualKind = actualToken.kind
        actualPosition = actualToken.position
        if actualKind == kind:
            return self.accept_it()
        else:
            print('Error at {}: expected {}, got {} instead'.format(str(actualPosition), kind, actualKind))
            sys.exit(1)

    # same as expect() but no error if not correct kind
    def maybe(self, kind):
        if self.show_next().kind == kind:
            return self.accept_it()

    def accept_it(self):
        token = self.show_next()
        output = str(token.kind) + ' ' + token.value
        self.indentator.say(output)
        return self.tokens.pop(0)

    def remove_comments(self):
        result = []
        in_comment = False
        for token in self.tokens:
            if token.kind == 'COMMENT':
                pass
            elif token.kind == 'LCOMMENT':
                in_comment = True
            elif token.kind == 'RCOMMENT':
                in_comment = False
            else:
                if not in_comment:
                    result.append(token)
        return result

    def parse(self, tokens):
        self.tokens = tokens
        self.tokens = self.remove_comments()
        self.parse_program()

    def parse_program(self):
        self.indentator.indent('Parsing Program')
        self.expect('INT')
        self.expect('IDENTIFIER')
        self.expect('LPAREN')
        self.expect('RPAREN')
        self.expect('LBRACE')
        self.parse_declarations()
        self.parse_statements()
        self.expect('RBRACE')
        self.indentator.dedent()
        if (self.errors == 1):
            print('WARNING: 1 error found!')
        elif (self.errors > 1):
            print('WARNING: ' + str(self.errors) + ' errors found!')
        else:
            print('parser: syntax analysis successful!')

    def parse_declaration(self): # done
        self.indentator.indent('Parsing Declaration')
        self.parse_type()
        self.expect('IDENTIFIER')
        if self.show_next().kind == 'LBRACK':
            self.accept_it()
            self.expect('INTEGER_LIT')
            self.expect('RBRACK')

        while self.show_next().kind == 'COMMA':
            self.accept_it()
            self.expect('IDENTIFIER')
            if self.show_next().kind == 'LBRACK':
                self.accept_it()
                self.expect('INTEGER_LIT')
                self.expect('RBRACK')
    
        self.expect('SEMICOLON')
        self.indentator.dedent()

    def parse_declarations(self): # done
        self.indentator.indent('Parsing Declarations')
        
        while self.show_next().kind in self.TYPE: 
             self.parse_declaration()
        self.indentator.dedent()
        

    def parse_type(self): # done
        # check what is the type of the identifier
        self.indentator.indent('Parsing Type')
        if self.show_next().kind in self.TYPE:
            self.accept_it()
        else:
            print("parsing error for type")
        self.indentator.dedent()
    
    def parse_statements(self): # done
        self.indentator.indent('Parsing Statements')

        # parse statement consist to check if there is a statement !
        while self.show_next().kind in self.STATEMENT_STARTERS:
            self.parse_statement()

        self.indentator.dedent()

    def parse_statement(self): # done
        self.indentator.indent('Parsing Statement')
        nextstatement = self.show_next().kind
        # parse statement consist to check if there is a statement !
        # ; | Block | Assignement | IfStatement | WhileStatement
        if nextstatement == 'SEMICOLON':
            self.expect('SEMICOLON')

        elif nextstatement == 'IDENTIFIER':
            self.parse_assignement_statement() 

        elif nextstatement == 'LBRACE':
            self.parse_block_statement()

        elif nextstatement == 'IF':
            self.parse_if_statement()

        elif nextstatement == 'WHILE':
            self.parse_while_statement()
        else:
            self.parse_expression()
        self.indentator.dedent() 

    def parse_assignement_statement(self): # done
        self.indentator.indent('Parsing Assignement Statement')
        self.expect('IDENTIFIER')
        if self.show_next().kind == 'LBRACK':
            self.accept_it()
            self.parse_expression()
            self.expect('RBRACK')
        
        # self.expect('ASSIGN')
        self.parse_expression()
        self.expect('SEMICOLON')
        self.indentator.dedent() 

    def parse_block_statement(self): #done
        self.indentator.indent('Block statement')
        self.expect('LBRACE')
        self.parse_statements()
        self.expect('RBRACE')
        self.indentator.dedent()
  
    def parse_if_statement(self): #done
        self.indentator.indent('Parsing if statement')
        self.expect('IF')
        self.expect('LPAREN')
        self.parse_expression()
        self.expect('RPAREN')
        self.parse_statement()
        if self.show_next().kind == 'ELSE':
            self.accept_it()
            self.parse_statement()
        self.indentator.dedent()

    def parse_while_statement(self): # done
        self.indentator.indent('Parsing While statement')
        self.expect('WHILE')
        self.expect('LPAREN')
        self.parse_expression()
        self.expect('RPAREN')
        self.parse_statement()
        self.indentator.dedent()

    def parse_expression(self): # done
        self.indentator.indent('parsing Expression')
        self.parse_conjunction()
        if (self.show_next().kind == 'DBAR'): 
            self.accept_it()
            self.parse_conjunction()
        self.indentator.dedent()

    def parse_conjunction(self): # done
        self.indentator.indent('parsing conjunction')
        self.parse_equality()
        if (self.show_next().kind == 'DAMPERSAND'):
            self.accept_it()
            self.parse_equality()
        self.indentator.dedent()

    def parse_equality(self): # done 1
        self.indentator.indent('parsing equality')
        EQOP = ['EQ', 'NEQ']
        print(str(self.show_next().kind))
        self.parse_relation()
        if self.show_next().kind in EQOP:
            self.accept_it()
            self.parse_relation()
        self.indentator.dedent()

    def parse_relation(self): # done 1
        self.indentator.indent('parsing relation')
        self.parse_addition()
        while self.show_next().kind in self.REL_OP:
            self.accept_it()
            self.parse_addition()
        self.indentator.dedent()
        '''
        def parse_equality(self): # done
            #self.indentator.indent('parsing equality')
            EQOP = ['EQ', 'NEQ']
            print(str(self.show_next().kind))
            lhs=self.parse_relation()
            if self.show_next().kind in EQOP:
                op=self.accept_it()
                rhs=self.parse_relation()
                return Binary(lhs,op,rhs)    
            return lhs

        def parse_relation(self): # done
            self.indentator.indent('parsing relation')
            e1=self.parse_addition()
            while self.show_next().kind in self.REL_OP:
                op=self.accept_it()
                e2=self.parse_addition()
                e1=Binary(e1,op,e2)
            return e1
        
        def parse_addition(self): # done
            self.indentator.indent('parsing addition')
            t1=self.parse_term()
            while self.show_next().kind in self.NUM_OP:
                op=self.accept_it()
                t2=self.parse_term()
                t1=lit(t1,op,t2)
            return e1
        def parse_term(self): # done
            self.indentator.indent('parsing term')
            e1=self.parse_factor()
            if self.show_next().kind in self.MUL_OP:
                term=self.accept_it()
                e2=self.parse_factor()
                e1=lit(e1,op,e2)
            return e1
        '''

    def parse_addition(self): # done 1
        self.indentator.indent('parsing addition')
        self.parse_term()
        if self.show_next().kind in self.NUM_OP:
            self.accept_it()
            self.parse_term()
        self.indentator.dedent()
        
    def parse_term(self): # done
        self.indentator.indent('parsing term')
        self.parse_factor()
        if self.show_next().kind in self.MUL_OP:
            self.accept_it()
            self.parse_factor()
        self.indentator.dedent()
        
    def parse_factor(self): # done
        self.indentator.indent('parsing factor')
        TAB = ['SUB', 'NOT']
        if self.show_next().kind in TAB:
            self.accept_it()
        self.parse_primary()

        self.indentator.dedent()
        
    def parse_primary(self): # done
        self.indentator.indent('parsing primary')
        # Identifier[[Expression]] | Literal | (Expression) | Type(Expression)
        if self.show_next().kind == 'IDENTIFIER':
            self.accept_it()
        elif self.show_next().kind == 'LBRACKET':
            self.accept_it()
            self.parse_expression()
            self.expect('RBRACKET')
        elif self.show_next().kind in self.LITERAL:
            self.accept_it()
        elif self.show_next().kind == "LPAREN":
            self.accept_it()
            self.parse_expression()
            self.expect('RPAREN')
        # else: 
            # sys.exit()
        self.indentator.dedent()
        
    '''