comparison ide/compiler/parser.py @ 5:818f80afa78b

Added handy highlighting to IDE
author windel-eee
date Thu, 22 Sep 2011 17:44:31 +0200
parents 0d5ef85b8698
children 1784af239df4
comparison
equal deleted inserted replaced
4:0d5ef85b8698 5:818f80afa78b
1 """ 1 """
2 This module parses source code into an abstract syntax tree (AST) 2 This module parses source code into an abstract syntax tree (AST)
3 """ 3 """
4 4
5 import shelve
6 from .symboltable import SymbolTable 5 from .symboltable import SymbolTable
7 from .nodes import * 6 from .nodes import *
8 from .errors import CompilerException, Error 7 from .errors import CompilerException, Error
9 from .modules import loadModule 8 from .modules import loadModule
10 from .display import printNode 9 from .display import printNode
14 class Parser: 13 class Parser:
15 def __init__(self, tokens): 14 def __init__(self, tokens):
16 """ provide the parser with the tokens iterator from the lexer. """ 15 """ provide the parser with the tokens iterator from the lexer. """
17 self.tokens = tokens 16 self.tokens = tokens
18 self.NextToken() 17 self.NextToken()
18 self.errorlist = []
19 19
20 def Error(self, msg): 20 def Error(self, msg):
21 raise CompilerException(msg, self.token.row, self.token.col) 21 raise CompilerException(msg, self.token.row, self.token.col)
22 22
23 # Lexer helpers: 23 # Lexer helpers:
568 #print('opcode', opcode, operands) 568 #print('opcode', opcode, operands)
569 self.Consume('end') 569 self.Consume('end')
570 return AsmCode(asmcode) 570 return AsmCode(asmcode)
571 571
572 def parseStatement(self): 572 def parseStatement(self):
573 # Determine statement type based on the pending token: 573 try:
574 if self.token.typ == 'if': 574 # Determine statement type based on the pending token:
575 return self.parseIfStatement() 575 if self.token.typ == 'if':
576 elif self.token.typ == 'case': 576 return self.parseIfStatement()
577 return self.parseCaseStatement() 577 elif self.token.typ == 'case':
578 elif self.token.typ == 'while': 578 return self.parseCaseStatement()
579 return self.parseWhileStatement() 579 elif self.token.typ == 'while':
580 elif self.token.typ == 'repeat': 580 return self.parseWhileStatement()
581 return self.parseRepeatStatement() 581 elif self.token.typ == 'repeat':
582 elif self.token.typ == 'for': 582 return self.parseRepeatStatement()
583 return self.parseForStatement() 583 elif self.token.typ == 'for':
584 elif self.token.typ == 'asm': 584 return self.parseForStatement()
585 return self.parseAsmcode() 585 elif self.token.typ == 'asm':
586 elif self.token.typ == 'ID': 586 return self.parseAsmcode()
587 # Assignment or procedure call 587 elif self.token.typ == 'ID':
588 designator = self.parseDesignator() 588 # Assignment or procedure call
589 if self.token.typ == '(' and type(designator.typ) is ProcedureType: 589 designator = self.parseDesignator()
590 return self.parseProcedureCall(designator) 590 if self.token.typ == '(' and type(designator.typ) is ProcedureType:
591 elif self.token.typ == ':=': 591 return self.parseProcedureCall(designator)
592 return self.parseAssignment(designator) 592 elif self.token.typ == ':=':
593 return self.parseAssignment(designator)
594 else:
595 self.Error('Unknown statement following designator: {0}'.format(self.token))
593 else: 596 else:
594 self.Error('Unknown statement following designator: {0}'.format(self.token)) 597 # TODO: return empty statement??:
595 else: 598 return EmptyStatement()
596 # TODO: return empty statement??: 599 self.Error('Unknown statement {0}'.format(self.token))
597 return EmptyStatement() 600 except CompilerException as e:
598 self.Error('Unknown statement {0}'.format(self.token)) 601 print(e)
602 self.errorlist.append( (e.row, e.col, e.msg))
603 return EmptyStatement()
599 604
600 def parseStatementSequence(self): 605 def parseStatementSequence(self):
601 """ Sequence of statements seperated by ';' """ 606 """ Sequence of statements seperated by ';' """
602 statements = [ self.parseStatement() ] 607 statements = [ self.parseStatement() ]
603 while self.hasConsumed(';'): 608 while self.hasConsumed(';'):