def get_variable(self, name): var = self.var_descs.get(name) if not var: if self.top_context: var = self.top_context.get_variable(name) else: raise SyntaxException() return var
def get_type(self, name): type_desc = self.type_descs['name'] if not type_desc and self.top_context: type_desc = self.top_context.get_type(name) if type_desc: return type_desc else: raise SyntaxException()
def str_to_val(self, valstr, n=32): ''' Converts a string to an int, and optionally limits that int to less than 2^n. ''' # using base 0 forces int() to figure out whether this is hex or decimal. val = int(valstr, 0) if (val < pow(2, n)): return val else: raise SyntaxException('Value ' + valstr + ' larger than ' + str(pow(2, n)))
def get_like(self, name): var_desc = self.var_descs['name'] if var_desc: return var_desc.type_desc else: const_desc = self.const_descs['name'] if const_desc: return const_desc.type_desc if self.top_context: return self.top_context.get_like(name) else: raise SyntaxException()
def get_register(self, r): ''' Returns the register number associated with r. If r is the string representation of a register number, it gets returned as an int. ''' if r in Mappings.registers: return Mappings.registers[r] elif (int(r) >= 0) and (int(r) <= 31): return int(r) else: raise SyntaxException('Invalid register ' + r + ' on line ' + str(self.linenum))
def add_variable(self, syn_data): if not self.var_descs.get( syn_data.varname) and not self.const_descs.get( syn_data.varname): try: type_desc = TypeDescrBase(syn_data.type_name, syn_data.length, syn_data.decimals) except: type_desc = self.get_type(syn_data.type_name) self.var_descs[syn_data.varname] = ValueDescription( syn_data.varname, type_desc) else: raise SyntaxException()
def _to_rpn(exp: Expression) -> Expression: """Parses expression to rpn format""" queue = [] stack = [] for tok in exp: # skips whitespaces if tok.type is TokenType.WHITESPACE: continue # any variable or constant -> to queue if tok.type in [TokenType.IDENTIFIER, TokenType.CONSTANT]: queue.append(tok) continue # opening bracket -> to stack if tok.type is TokenType.OPENING_BRACKET: stack.append(tok) continue # closing bracket -> move form stack to queue if tok.type is TokenType.CLOSING_BRACKET: while stack[-1].type is not TokenType.OPENING_BRACKET: queue.append(stack.pop()) stack.pop() continue # operators -> complicated xD if tok.type in [TokenType.DOUBLE_OPERATOR, TokenType.SINGLE_OPERATOR]: while len(stack) > 0 and stack[ -1].type is not TokenType.OPENING_BRACKET and ( stack[-1].precedence > tok.precedence or (stack[-1].precedence == tok.precedence and stack[-1].type is TokenType.SINGLE_OPERATOR)): queue.append(stack.pop()) stack.append(tok) continue # other -> error raise SyntaxException(tok, "Unexpected token") # move everything from stack to queue while len(stack) > 0: queue.append(stack.pop()) # return queue - expression in rpn format return queue
def parse_instruction(self, line): ''' Parses a particular line, returning the bit pattern for an instruction if possible. A SyntaxException will be raised on error. If no instruction was found on the line, this will return False. ''' r_groups = ['rt', 'rs', 'rd', 'shamt'] i_groups = ['rt', 'rs', 'i'] j_groups = ['address'] # allow for labels on the same line as an instruction. pattern = Mappings.patterns['label'] + '*' + Mappings.patterns[ 'instruction'] m = re.search(pattern, line) i = Mappings.instructions.get(m.group('instruction')) j = 1 if i is not None: for arg in i['syntax']: pattern += Mappings.patterns[arg] if j != len(i['syntax']): pattern += Mappings.patterns['comma'] j += 1 pattern += Mappings.patterns['eol'] m = re.search(pattern, line) a = {} for arg in i['syntax']: if arg == 'i(rs)': # special case try: a['i'] = m.group('i') except: raise SyntaxException('Expected i on line ' + str(self.linenum)) try: a['rs'] = m.group('rs') except: raise SyntaxException('Expected rs on line ' + str(self.linenum)) else: try: a[arg] = m.group(arg) except: raise SyntaxException('Expected ' + arg + ' on line ' + str(self.linenum)) # set unused values to 0, # then assemble bit sequence based on instruction type. if i['type'] == 'r': for arg in r_groups: if arg not in a: a[arg] = '0' bits = self.assemble_rtype(i['func'], a['rs'], a['rt'], a['rd'], a['shamt'], i['op']) elif i['type'] == 'i': for arg in i_groups: if arg not in a: a[arg] = '0' bits = self.assemble_itype(i['op'], a['rs'], a['rt'], a['i']) elif i['type'] == 'j': for arg in j_groups: if arg not in a: a[arg] = '0' bits = self.assemble_jtype(i['op'], a['address']) else: raise SyntaxException('Unsupported instruction type.') return bits else: return False
def get_constant_value(self, name): desc = self.get_constant(name) if desc == None: raise SyntaxException() return desc.value
def check_syntax(exp: Expression): """Checks syntax of given expression and throws SyntaxExceptions if needed""" indent = 0 state = 1 # for every token for tok in exp: # skips whitespaces if tok.type is TokenType.WHITESPACE: continue # if in state 1 if state == 1: # identifier -> ok, state 2 if tok.type is TokenType.IDENTIFIER: state = 2 # opening bracket -> ok, state 1 elif tok.type is TokenType.OPENING_BRACKET: indent += 1 state = 1 # single operator -> ok, state 1 elif tok.type is TokenType.SINGLE_OPERATOR: state = 1 # constatnt -> ok, state 2 elif tok.type is TokenType.CONSTANT: state = 2 # anything else -> error else: raise SyntaxException(tok, "Unexpected token") # if in state 2 else: # closing bracket -> check indentation, state 2 if tok.type is TokenType.CLOSING_BRACKET: indent -= 1 state = 2 if indent < 0: raise SyntaxException(tok, "Unexpected closing bracket") # double operator -> ok, state 1 elif tok.type is TokenType.DOUBLE_OPERATOR: state = 1 # anything else -> error else: raise SyntaxException(tok, "Unexpected token") # checks final indentation if indent != 0: raise SyntaxException(exp[-1], "Missing closing bracket") # checks final state if state != 2: raise SyntaxException(exp[-1], "Unexpected end of statement")