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