opuntiaOS - an operating system targeting x86 and ARMv7
1# Copyright 2021 Nikita Melekhin. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5from Lexer.lexer import Lexer 6from token import Token 7from type_file import Type 8from connection import Connection 9 10 11class Parser: 12 13 def set_code_lines(self, code: [str]): 14 self.lexer = Lexer(code) 15 self.token = Token() 16 self.current_token_id = -1 17 self.read_tokens = 0 18 self.lexer_rich_the_end = 0 19 self.tokens = [] 20 self.next_token() 21 22 def next_token(self): 23 self.current_token_id += 1 24 self.token = self.get_token_at(self.current_token_id) 25 26 def get_token_at(self, pos): 27 if pos >= self.read_tokens and not self.lexer_rich_the_end: 28 for i in range(pos - self.read_tokens + 1): 29 self.tokens.append(self.lexer.next_token()) 30 self.read_tokens += 1 31 if self.tokens[-1].type == Type.Special.EOF: 32 self.lexer_rich_the_end = True 33 break 34 35 return self.tokens[min(pos, self.read_tokens - 1)] 36 37 def is_nth(self, type_of_token, n): 38 if isinstance(type_of_token, list): 39 for type_of_cur_token in type_of_token: 40 if self.get_token_at(self.current_token_id+n).type == type_of_cur_token: 41 return True 42 return False 43 return self.get_token_at(self.current_token_id+n).type == type_of_token 44 45 def is_next(self, type_of_token): 46 if isinstance(type_of_token, list): 47 for type_of_cur_token in type_of_token: 48 if self.token.type == type_of_cur_token: 49 return True 50 return False 51 return self.token.type == type_of_token 52 53 def must_next(self, type_of_token): 54 if not self.is_next(type_of_token): 55 print("{0} is not {1}".format(self.token, type_of_token)) 56 exit(1) 57 58 def __init__(self): 59 pass 60 61 def eat_name(self): 62 self.must_next(Type.Reserved.Name) 63 self.next_token() 64 self.must_next(Type.Lang.Colon) 65 self.next_token() 66 self.must_next(Type.Word) 67 res = self.token.value 68 self.next_token() 69 return res 70 71 def eat_protected(self): 72 if (self.is_next(Type.Reserved.KeyProtected)): 73 self.next_token() 74 return True 75 return False 76 77 def eat_magic(self): 78 self.must_next(Type.Reserved.Magic) 79 self.next_token() 80 self.must_next(Type.Lang.Colon) 81 self.next_token() 82 self.must_next(Type.Number.Integer) 83 res = self.token.value 84 self.next_token() 85 return res 86 87 def eat_params(self): 88 params = [] 89 self.must_next(Type.Lang.LeftBracket) 90 self.next_token() 91 while not self.is_next(Type.Lang.RightBracket): 92 self.must_next(Type.Word) 93 typ = self.token.value 94 self.next_token() 95 96 self.must_next(Type.Word) 97 nam = self.token.value 98 self.next_token() 99 100 params.append([typ, nam]) 101 102 if self.is_next(Type.Lang.Comma): 103 self.must_next(Type.Lang.Comma) 104 self.next_token() 105 106 self.must_next(Type.Lang.RightBracket) 107 self.next_token() 108 return params 109 110 def eat_message(self, decoder): 111 self.must_next(Type.Word) 112 msgname = self.token.value 113 self.next_token() 114 decoder.add_message(msgname, self.eat_params()) 115 return msgname 116 117 def eat_function(self, decoder): 118 ms1 = self.eat_message(decoder) 119 ms2 = None 120 121 if self.is_next(Type.Reserved.Return): 122 self.must_next(Type.Reserved.Return) 123 self.next_token() 124 ms2 = self.eat_message(decoder) 125 126 decoder.add_function(ms1, ms2) 127 128 def eat_decoder(self): 129 self.must_next(Type.Reserved.Begin) 130 self.next_token() 131 is_protected = self.eat_protected() 132 decoder = Connection(self.eat_name(), self.eat_magic(), is_protected) 133 while not self.is_next(Type.Reserved.End): 134 self.eat_function(decoder) 135 self.must_next(Type.Reserved.End) 136 self.next_token() 137 return decoder 138 139 def parse(self): 140 decoders = [] 141 while self.is_next(Type.Reserved.Begin): 142 decoders.append(self.eat_decoder()) 143 print("connc: {0} decoders parsed!".format(len(decoders))) 144 return decoders