def _parse_base_list(self): """BaseList = (BASE)*""" tree = Tree('BaseList') while not self._scanner.is_end() and not self._scanner.is_next('}'): tree.append(self._parse_base()) return tree
def _parse_exp(self): """EXP = ITEM ([+-*/] ITEM)? """ tree = Tree('EXP') \ .append(self._parse_item()) if self._scanner.is_next('OP'): tree.append(self._scanner.get_next('OP')) \ .append(self._parse_item()) return tree
def _parse_stmt(self): """STMT = 'return' id | id '=' EXP | id ('++'|'--') """ tree = Tree('STMT') if self._scanner.is_next('return'): tree.append(self._scanner.get_next('return')) \ .append(self._parse_id()) else: tree.append(self._parse_id()) if self._scanner.is_next('ASSIGN'): tree.append(self._scanner.get_next('ASSIGN')) \ .append(self._parse_exp()) else: tree.append(self._scanner.get_next('UnaryOP')) return tree
def _parse_cond(self): """COND = EXP ('=='|'!='|'<='|'>='|'<'|'>') EXP""" tree = Tree('COND') \ .append(self._parse_exp()) \ .append(self._scanner.get_next('COND')) \ .append(self._parse_exp()) return tree
def _parse_block(self): """BLOCK = '{' BaseList '}' """ tree = Tree('BLOCK') \ .append(self._scanner.get_next('{')) \ .append(self._parse_base_list()) \ .append(self._scanner.get_next('}')) return tree
def _parse_base(self): """BASE = FOR | STMT ';' """ tree = Tree('BASE') if self._scanner.is_next('for'): tree.append(self._parse_for()) else: tree.append(self._parse_stmt()) tree.append(self._scanner.get_next(';')) return tree
def _parse_for(self): """FOR = 'for' '(' STMT ';' COND ';' STMT ')' BLOCK """ tree = Tree('FOR') \ .append(self._scanner.get_next('for')) \ .append(self._scanner.get_next('(')) \ .append(self._parse_stmt()) \ .append(self._scanner.get_next('END')) \ .append(self._parse_cond()) \ .append(self._scanner.get_next('END')) \ .append(self._parse_stmt()) \ .append(self._scanner.get_next(')')) \ .append(self._parse_block()) return tree
def _parse_item(self): """ITEM = id | number """ tree = Tree('ITEM') if self._scanner.is_next('ID'): tree.append(self._parse_id()) else: tree.append(self._parse_number()) return tree
def _parse_prog(self): """PROG = BaseList """ return Tree('PROG').append(self._parse_base_list())
def parse_tree(self, rule: BNFRule): tree = Tree(rule.name) for sub_rule in rule.sub_rules: first_try = True next_sub = False for token in sub_rule: try: if token.modifier is ModifierType.none: result = self.get_token(token) tree.append(result, concat=token.type is RuleType.link and self.rules[token.content].type is RuleType.internal) elif token.modifier is ModifierType.repeat_what_ever: while True: try: result = self.try_get_token(token) except ContextEndedError: break if result is None: break else: tree.append(result, concat=token.type is RuleType.link and self.rules[token.content].type is RuleType.internal) elif token.modifier is ModifierType.repeat_once_or_nothing_happened: try: result = self.try_get_token(token) except ContextEndedError: result = None if result is not None: tree.append(result, concat=token.type is RuleType.link and self.rules[token.content].type is RuleType.internal) elif token.modifier is ModifierType.repeat_more_than_once: result = self.get_token(token) tree.append(result, concat=token.type is RuleType.link and self.rules[token.content].type is RuleType.internal) while True: try: result = self.try_get_token(token) except ContextEndedError: break if result is None: break else: tree.append(result, concat=token.type is RuleType.link and self.rules[token.content].type is RuleType.internal) except (UnExceptedTokenError, ContextEndedError) as e: self.last_unexpected_error = e if first_try is True: next_sub = True break else: raise ParseError(e) # tree.append(result) first_try = False if next_sub: continue return tree raise self.last_unexpected_error
def _parse_number(self): """number = [0-9]+""" tree = Tree('Number') \ .append(self._scanner.get_next('NUMBER')) return tree
def _parse_id(self): """id = [A-Za-z_][A-Za-z0-9_]*""" tree = Tree('ID') \ .append(self._scanner.get_next('ID')) return tree