1 ''' @file apg_py/api/semantic_callbacks.py
2 @brief All the semantic AST translation callback functions.
10 ast.add_callback(
'file', semantic_file)
11 ast.add_callback(
'rule', semantic_rule)
12 ast.add_callback(
'rule-lookup', semantic_rule_lookup)
13 ast.add_callback(
'rule-name', semantic_rule_name)
14 ast.add_callback(
'defined', semantic_defined)
15 ast.add_callback(
'inc-alt', semantic_inc_alt)
16 ast.add_callback(
'alternation', semantic_alternation)
17 ast.add_callback(
'concatenation', semantic_concatenation)
18 ast.add_callback(
'repetition', semantic_repetition)
19 ast.add_callback(
'option-open', semantic_option_open)
20 ast.add_callback(
'rep-op', semantic_rep_op)
21 ast.add_callback(
'rep-min', semantic_rep_min)
22 ast.add_callback(
'rep-max', semantic_rep_max)
23 ast.add_callback(
'rep-min-max', semantic_rep_min_max)
24 ast.add_callback(
'and-op', semantic_and_op)
25 ast.add_callback(
'not-op', semantic_not_op)
26 ast.add_callback(
'rnm-op', semantic_rnm_op)
27 ast.add_callback(
'abg-op', semantic_abg_op)
28 ast.add_callback(
'aen-op', semantic_aen_op)
29 ast.add_callback(
'bka-op', semantic_bka_op)
30 ast.add_callback(
'bkn-op', semantic_bkn_op)
31 ast.add_callback(
'ci', semantic_ci)
32 ast.add_callback(
'cs', semantic_cs)
33 ast.add_callback(
'um', semantic_um)
34 ast.add_callback(
'rm', semantic_rm)
35 ast.add_callback(
'bkr-name', semantic_bkr_name)
36 ast.add_callback(
'bkr-op', semantic_bkr_op)
37 ast.add_callback(
'udt-empty', semantic_udt_empty)
38 ast.add_callback(
'udt-non-empty', semantic_udt_non_empty)
39 ast.add_callback(
'tls-op', semantic_tls_op)
40 ast.add_callback(
'tls-string', semantic_tls_string)
41 ast.add_callback(
'cls-string', semantic_cls_string)
42 ast.add_callback(
'tbs-op', semantic_tbs_op)
43 ast.add_callback(
'd-string', semantic_d_string)
44 ast.add_callback(
'b-string', semantic_b_string)
45 ast.add_callback(
'x-string', semantic_x_string)
46 ast.add_callback(
'trg-op', semantic_trg_op)
47 ast.add_callback(
'dmin', semantic_dmin)
48 ast.add_callback(
'bmin', semantic_bmin)
49 ast.add_callback(
'xmin', semantic_xmin)
50 ast.add_callback(
'xmax', semantic_xmax)
51 ast.add_callback(
'bmax', semantic_bmax)
52 ast.add_callback(
'dmax', semantic_dmax)
57 for i
in range(beg, beg + len):
58 num = 10 * num + chars[i] - 48
64 for i
in range(beg, beg + len):
65 num = 2 * num + chars[i] - 48
71 for i
in range(beg, beg + len):
73 if(digit >= 48
and digit <= 57):
75 elif(digit >= 65
and digit <= 70):
77 elif(digit >= 97
and digit <= 102):
81 'semantic-callbacks: hexnum: hex digit out of range', digit)
82 num = 16 * num + digit
87 if(state == id.SEM_PRE):
89 data[
'alt_stack'] = []
90 data[
'top_alt'] =
None
91 data[
'top_rule'] =
None
92 data[
'definedas'] =
None
93 data[
'rule_name'] =
None
96 data[
'top_rep'] =
None
101 data[
'bkr_name'] =
None
102 data[
'tbs_str'] =
None
104 for rule
in data[
'rules']:
105 for op
in rule[
'opcodes']:
107 if(op[
'type'] == id.RNM):
108 name = op[
'index'][
'name']
109 ph = op[
'index'][
'phrase_index']
110 lookup = data[
'rule_names'].get(name)
113 msg =
'rule name \'' + name +
'\' used but not defined'
114 data[
'errors'].append({
115 'line': data[
'find_line'](ph),
119 op[
'index'] = lookup[
'index']
120 if(op[
'type'] == id.BKR):
121 name = op[
'name'][
'name']
122 um = op[
'bkr_mode'] == id.BKR_MODE_UM
123 ph = op[
'name'][
'phrase_index']
127 lookup = data[
'rule_names'].get(name)
130 lookup = data[
'udt_names'].get(name)
134 msg =
'back referenced name \'' + name + \
135 '\' not a rule or UDT name'
136 data[
'errors'].append({
137 'line': data[
'find_line'](ph),
142 udt = data[
'udts'][lookup[
'index']]
144 op[
'empty'] = udt[
'empty']
145 op[
'index'] = udt[
'index']
147 udt[
'is_bkru'] =
True
149 udt[
'is_bkrr'] =
True
151 ru = data[
'rules'][lookup[
'index']]
152 op[
'index'] = lookup[
'index']
161 if(state == id.SEM_POST):
162 if(data[
'definedas'] ==
'='):
163 rule_name = data[
'rule_names'].add(data[
'rule_name'])
166 msg =
'Rule name \'' + \
167 data[
'rule_name'] +
'\' previously defined.'
168 data[
'errors'].append({
'line': data[
'find_line'](phrase_index),
169 'index': phrase_index,
173 data[
'top_rule'] = {
'name': rule_name[
'name'],
174 'lower': rule_name[
'lower'],
175 'index': rule_name[
'index'],
176 'line': data[
'find_line'](phrase_index),
181 data[
'rules'].append(data[
'top_rule'])
183 rule_name = data[
'rule_names'].get(data[
'rule_name'])
186 msg =
'Rule name \'' + \
187 data[
'rule_name'] + \
188 '\' for incremental alternative not previously defined.'
189 data[
'errors'].append({
'line': data[
'find_line'](phrase_index),
190 'index': phrase_index,
193 data[
'top_rule'] = data[
'rules'][rule_name[
'index']]
198 if(state == id.SEM_PRE):
199 data[
'alt_stack'].clear()
200 data[
'top_stack'] =
None
205 if(state == id.SEM_PRE):
206 data[
'rule_name'] = utils.tuple_to_string(
207 input[phrase_index:phrase_index + phrase_length])
212 if(state == id.SEM_PRE):
213 data[
'definedas'] =
'='
218 if(state == id.SEM_PRE):
219 data[
'definedas'] =
'=/'
224 if(state == id.SEM_PRE):
225 if(data[
'top_stack']
is None):
226 if(data[
'definedas'] ==
'='):
233 data[
'alt_stack'].append(data[
'top_alt'])
234 data[
'top_rule'][
'opcodes'].append(data[
'top_alt'][
'alt'])
237 assert(data[
'definedas'] ==
'=/'),
'invalid defined-as'
239 'alt': data[
'top_rule'][
'opcodes'][0],
'cat':
None}
240 data[
'alt_stack'].append(data[
'top_alt'])
248 data[
'alt_stack'].append(data[
'top_alt'])
249 data[
'top_rule'][
'opcodes'].append(data[
'top_alt'][
'alt'])
251 assert(state == id.SEM_POST),
'invalid AST translation state'
253 data[
'alt_stack'].pop()
254 if(
len(data[
'alt_stack']) > 0):
255 data[
'top_alt'] = data[
'alt_stack'][-1]
257 data[
'top_alt'] =
None
262 if(state == id.SEM_PRE):
263 data[
'top_alt'][
'alt'][
'children'].append(
264 len(data[
'top_rule'][
'opcodes']))
265 data[
'top_alt'][
'cat'] = {
'type': id.CAT,
'children': []}
266 data[
'top_rule'][
'opcodes'].append(data[
'top_alt'][
'cat'])
268 assert(state == id.SEM_POST),
'invalid AST translation state'
269 data[
'top_alt'][
'cat'] =
None
274 if(state == id.SEM_PRE):
275 data[
'top_alt'][
'cat'][
'children'].append(
276 len(data[
'top_rule'][
'opcodes']))
281 if(state == id.SEM_PRE):
282 data[
'top_rule'][
'opcodes'].append(
283 {
'type': id.REP,
'min': 0,
'max': 1})
288 if(state == id.SEM_PRE):
290 data[
'max'] = sys.maxsize
291 data[
'top_rep'] = {
'type': id.REP,
'min': 0,
'max': sys.maxsize}
292 data[
'top_rule'][
'opcodes'].append(data[
'top_rep'])
294 assert(state == id.SEM_POST),
'invalid AST translation state'
295 if(data[
'min'] > data[
'max']):
296 min = str(data[
'min'])
297 max = str(data[
'max'])
298 msg =
'repetition min(' + min +
') > max(' + max +
')'
299 data[
'errors'].append({
'line': data[
'find_line'](phrase_index),
300 'index': phrase_index,
'msg': msg})
301 if(data[
'min'] == 0
and data[
'max'] == 0):
302 msg =
'repetition 0*0 not allowed - '
303 msg +=
'for explicit empty string use ""'
304 data[
'errors'].append({
'line': data[
'find_line'](phrase_index),
305 'index': phrase_index,
'msg': msg})
306 data[
'top_rep'][
'min'] = data[
'min']
307 data[
'top_rep'][
'max'] = data[
'max']
312 if(state == id.SEM_POST):
313 data[
'min'] =
decnum(input, phrase_index, phrase_length)
318 if(state == id.SEM_POST):
319 data[
'max'] =
decnum(input, phrase_index, phrase_length)
324 if(state == id.SEM_POST):
325 data[
'max'] =
decnum(input, phrase_index, phrase_length)
326 data[
'min'] = data[
'max']
331 if(state == id.SEM_POST):
332 data[
'top_rule'][
'opcodes'].append({
'type': id.AND, })
337 if(state == id.SEM_POST):
338 data[
'top_rule'][
'opcodes'].append({
'type': id.NOT, })
343 if(state == id.SEM_POST):
346 name = utils.tuple_to_string(
347 input[phrase_index:phrase_index + phrase_length])
348 data[
'top_rule'][
'opcodes'].append({
350 'index': {
'name': name,
'phrase_index': phrase_index}})
355 if(state == id.SEM_POST):
356 data[
'top_rule'][
'opcodes'].append({
'type': id.ABG, })
361 if(state == id.SEM_POST):
362 data[
'top_rule'][
'opcodes'].append({
'type': id.AEN, })
367 if(state == id.SEM_POST):
368 data[
'top_rule'][
'opcodes'].append({
'type': id.BKA, })
373 if(state == id.SEM_POST):
374 data[
'top_rule'][
'opcodes'].append({
'type': id.BKN, })
379 if(state == id.SEM_POST):
386 if(state == id.SEM_POST):
393 if(state == id.SEM_POST):
399 if(state == id.SEM_POST):
405 if(state == id.SEM_POST):
407 name = utils.tuple_to_string(
408 input[phrase_index:phrase_index + phrase_length])
409 data[
'bkr_name'] = {
'name': name,
'phrase_index': phrase_index}
414 if(state == id.SEM_PRE):
421 assert(state == id.SEM_POST),
'invalid AST translation state'
422 case = id.BKR_MODE_CS if(data[
'cs'])
else id.BKR_MODE_CI
423 mode = id.BKR_MODE_RM if(data[
'ur'])
else id.BKR_MODE_UM
424 data[
'top_rule'][
'opcodes'].append({
426 'name': data[
'bkr_name'],
427 'lower': data[
'bkr_name'][
'name'].lower(),
434 def generic_udt(input, phrase_index, phrase_length, data, empty=False):
435 name = utils.tuple_to_string(
436 input[phrase_index:phrase_index + phrase_length])
437 udt_name = data[
'udt_names'].add(name)
440 udt_name = data[
'udt_names'].get(name)
441 assert(udt_name != -1),
'UDT name list look up error'
444 data[
'udts'].append({
445 'name': udt_name[
'name'],
446 'lower': udt_name[
'lower'],
447 'index': udt_name[
'index'],
452 data[
'top_rule'][
'opcodes'].append({
455 'index': udt_name[
'index']
460 if(state == id.SEM_POST):
471 if(state == id.SEM_POST):
482 if(state == id.SEM_PRE):
489 if(state == id.SEM_POST):
490 tup = input[phrase_index:phrase_index + phrase_length]
493 string = utils.tuple_to_string(tup)
494 tup = utils.string_to_tuple(string.lower())
495 data[
'top_rule'][
'opcodes'].append({
501 data[
'top_rule'][
'opcodes'].append({
509 if(state == id.SEM_POST):
510 tup = input[phrase_index:phrase_index + phrase_length]
513 data[
'top_rule'][
'opcodes'].append({
519 data[
'top_rule'][
'opcodes'].append({
527 if(state == id.SEM_PRE):
530 data[
'top_rule'][
'opcodes'].append({
532 'string': tuple(data[
'tbs_str'])
538 if(state == id.SEM_POST):
539 data[
'tbs_str'].append(
decnum(input, phrase_index, phrase_length))
544 if(state == id.SEM_POST):
545 data[
'tbs_str'].append(
binnum(input, phrase_index, phrase_length))
550 if(state == id.SEM_POST):
551 data[
'tbs_str'].append(
hexnum(input, phrase_index, phrase_length))
556 if(state == id.SEM_PRE):
560 if(data[
'min'] > data[
'max']):
561 min = str(data[
'min'])
562 max = str(data[
'max'])
563 msg =
'TRG, terminal range, min(' + min +
') > max(' + max +
')'
564 data[
'errors'].append({
'line': data[
'find_line'](phrase_index),
565 'index': phrase_index,
'msg': msg})
567 data[
'top_rule'][
'opcodes'].append({
576 if(state == id.SEM_POST):
577 data[
'min'] =
decnum(input, phrase_index, phrase_length)
582 if(state == id.SEM_POST):
583 data[
'max'] =
decnum(input, phrase_index, phrase_length)
588 if(state == id.SEM_POST):
589 data[
'min'] =
binnum(input, phrase_index, phrase_length)
594 if(state == id.SEM_POST):
595 data[
'max'] =
binnum(input, phrase_index, phrase_length)
600 if(state == id.SEM_POST):
601 data[
'min'] =
hexnum(input, phrase_index, phrase_length)
606 if(state == id.SEM_POST):
607 data[
'max'] =
hexnum(input, phrase_index, phrase_length)
def semantic_file(state, input, phrase_index, phrase_length, data)
def semantic_repetition(state, input, phrase_index, phrase_length, data)
def semantic_and_op(state, input, phrase_index, phrase_length, data)
def semantic_tls_string(state, input, phrase_index, phrase_length, data)
def add_ast_callbacks(ast)
def semantic_bkr_name(state, input, phrase_index, phrase_length, data)
def decnum(chars, beg, len)
def semantic_bmax(state, input, phrase_index, phrase_length, data)
def semantic_trg_op(state, input, phrase_index, phrase_length, data)
def hexnum(chars, beg, len)
def semantic_rnm_op(state, input, phrase_index, phrase_length, data)
def semantic_bkn_op(state, input, phrase_index, phrase_length, data)
def semantic_bmin(state, input, phrase_index, phrase_length, data)
def semantic_udt_non_empty(state, input, phrase_index, phrase_length, data)
def semantic_rep_min_max(state, input, phrase_index, phrase_length, data)
def semantic_rep_max(state, input, phrase_index, phrase_length, data)
def semantic_inc_alt(state, input, phrase_index, phrase_length, data)
def semantic_rep_op(state, input, phrase_index, phrase_length, data)
def semantic_option_open(state, input, phrase_index, phrase_length, data)
def semantic_rm(state, input, phrase_index, phrase_length, data)
def semantic_cs(state, input, phrase_index, phrase_length, data)
def semantic_d_string(state, input, phrase_index, phrase_length, data)
def semantic_b_string(state, input, phrase_index, phrase_length, data)
def generic_udt(input, phrase_index, phrase_length, data, empty=False)
def semantic_rule_name(state, input, phrase_index, phrase_length, data)
def semantic_bka_op(state, input, phrase_index, phrase_length, data)
def semantic_ci(state, input, phrase_index, phrase_length, data)
def semantic_defined(state, input, phrase_index, phrase_length, data)
def semantic_rule_lookup(state, input, phrase_index, phrase_length, data)
def semantic_tls_op(state, input, phrase_index, phrase_length, data)
def semantic_um(state, input, phrase_index, phrase_length, data)
def semantic_x_string(state, input, phrase_index, phrase_length, data)
def semantic_concatenation(state, input, phrase_index, phrase_length, data)
def semantic_xmax(state, input, phrase_index, phrase_length, data)
def semantic_not_op(state, input, phrase_index, phrase_length, data)
def semantic_bkr_op(state, input, phrase_index, phrase_length, data)
def semantic_dmax(state, input, phrase_index, phrase_length, data)
def semantic_rep_min(state, input, phrase_index, phrase_length, data)
def semantic_udt_empty(state, input, phrase_index, phrase_length, data)
def semantic_tbs_op(state, input, phrase_index, phrase_length, data)
def semantic_xmin(state, input, phrase_index, phrase_length, data)
def semantic_aen_op(state, input, phrase_index, phrase_length, data)
def semantic_dmin(state, input, phrase_index, phrase_length, data)
def semantic_rule(state, input, phrase_index, phrase_length, data)
def binnum(chars, beg, len)
def semantic_alternation(state, input, phrase_index, phrase_length, data)
def semantic_cls_string(state, input, phrase_index, phrase_length, data)
def semantic_abg_op(state, input, phrase_index, phrase_length, data)