The root cause of difficulty in semantic analysis is the availability of syntax. Deep recursion makes the decomposition of the problem quite complex. However, if the recursive problem can be converted into an iteration problem, the model can be greatly simplified. The key to recursive transformation to iteration is to find all the features of the deepest recursive structure and iterate it to solve the problem. Generally, in the face of complex recursive problems, people also find their deep recursive structure based on their syntax rules, resolve it, and iterate step by step. In this way, the problem is solved. Human thinking is very good at converting recursive problems into iterative problems. The process of learning knowledge can be seen as understanding and mastering various grammar rules. The recursion problem of unary operators and binary operators can be easily converted into iteration. The situation of Multivariate operators is more complex. All operators and their priorities, such as typeof, address fetch, and pointer pointing, are not implemented here. The implementation includes arithmetic formula, logical formula, function call and brackets. It is sufficient to understand the semantic analysis process. For simple expressions that do not contain parentheses and functions, the semantic analysis process is as follows: Our Data Structure: copy the Code 1 ''' 2 ________________________ Syntax Tree 3 Parenthesis: 4 ["(", None] 5 [")", None] 6 Operators (grouped by precedence): 7 Unary: 8 1 + -! ~ ["+", None] ["-", None] ["! ", None] [" ~ ", None] 9 Binary: 10 2 */% [" * ", None] ["/", None] [" % ", none] 11 3 +-["+", None] ["-", None] 12 4 <> ["<", None] ["> ", none] 13 5 >>=< <= [">", None] ["> =", None] ["<", None] ["<= ", none] 14 6 =! = ["=", None] ["! = ", None] 15 7 & [" & ", None] 16 8 ^ [" ^ ", None] 17 9 | [" | ", none] 18 10 & ["&", None] 19 11 | ["|", None] 20 Ternary: 21 12 expr? Expr: expr ["? ", None] [": ", None] [" @ expr ","?: ", ListPtr0, listPtr1, listPtr2] 22 13 expr, expr, expr... 23 Var, Num, Expr, Function: 24 ["@ var", "varName"] 25 ["@ num", "num_string"] 26 ["@ expr ", "Operator", listPtr,...] 27 ["@ func", "funcName", listPtr1,...] 28 ["@ expr_list", ["@ var" | "@ num" | "@ expr" | "@ func",...],...] 29 ''' copy the Code. This is our final code module diagram. The figure is like the module_x_y function. x indicates the priority of this operator, and y indicates the horizontal sequence number, starting from scratch. Code comments have been written in great detail. Please refer to the source Code: although the Code above View Code is large, it is the simplest part. In fact, you can take some methods to significantly reduce the amount of Code, however, the time is limited. The following describes the semantic analysis process of unary operators, binary operators, ternary operators, and comma delimiters. This is one of the core codes in this article: copy code 1 ##################################### ### global list 2 # construct a module dictionary 3 # module_dic_tuple [priority] ['operator'] (lis, i) 4 module_dic_tuple = ({},{ '+': module_00000, '-': module_1_1 ,'! ': Module_1_2 ,'~ ': Module_1_3}, \ 5 {' * ': module_2_0,'/': module_2_1,' % ': module_2_2}, \ 6 {' + ': module_3_0 ,'-': module_3_1}, \ 7 {'<': module_4_0, '>': module_4_1}, \ 8 {'>': module_5_0, '> =': module_5_1, '<': module_5_2, '<=': module_5_3}, \ 9 {'=': module_6_0 ,'! = ': Module_6_1}, \ 10 {' & ': module_7_0}, \ 11 {' ^ ': module_8_0}, \ 12 {' | ': module_9_0 }, \ 13 {'&': module_10_0}, \ 14 {'|': module_11_0}, \ 15 {'?: ': Module_12_0}, \ 16 {', ': module_13_0}) 17 18 operator_priority_tuple = (), (' + ','-','! ','~ '), (' * ','/',' % '), \ 19 (' + ','-'), (' <', '>'), \ 20 ('>', '> =', '<', '<='), ('= ','! = '), \ 21 (' & '), (' ^ '), (' | '), (' & '), (' | '), ('? ',':'),(',')) 22 23 ########################### parse: unary, binary, ternary, comma expr24 ########### return value: 25 ############ 0 parsed sucessfully26 ############## 1 syntax error27 def parse_simple_expr (lis ): 28 if len (lis) = 0: 29 return 130 # if lis [len (lis)-1] [0] [0]! = '@': 31 # return 132 # if lis [0] [0] [0]! = '@' And lis [0] [0] not in ('+ ','-','! ','~ '): 33 # return 1 34 for pri in range (1135): # pri 1, 2, 4, 5, 6, 7, 8, 9, 10, I = 036 while if len (lis) = 1 and lis [0] [0] [0] = '@': 38 return 039 if I> = len (lis ): 40 break41 if lis [I] [0] in operator_priority_tuple [pri]: 42 if module_dic_tuple [pri] [lis [I] [0] (lis, I) = I = 044 continue45 else: 46 I = I + 147 continue48 else: 49 I = I + 150 for pri in range (): # pri 12 # parse... a? A:... 51 I = 052 while :53 if len (lis) = 1 and lis [0] [0] [0] = '@': 54 return 055 if I> = len (lis): 56 break57 if lis [I] [0] = ': 58 if module_dic_tuple [pri] ['?: '] (Lis, I) = 0: 59 I = 060 continue61 else: 62 I = I + 163 continue64 else: 65 I = I + 166 return module_dic_tuple [13] [', '] (lis, 0) 67 return 1 copy the code above and use the dictionary linked list referenced by the function to simplify the number of code in this part. This part is not verified and displayed. The specific process is similar to the description in the previous article "A simple Semantic Analysis Algorithm: single-step algorithm-Python implementation. After the parse_simple_expr function is implemented, Semantic Analysis of the remaining functions and parentheses becomes simpler. The calculation process is as follows: code implementation: copy code 1 ########## return value: [intStatusCode, indexOf '(', indexOf ') '] 2 ############ intStatusCode 3 ############## 0 sucessfully 4 ###### ####### 1 no parenthesis matched 5 ############# 2 list is null :( 6 def module_parenthesis_place (lis): 7 length = len (lis) 8 err = 0 9 x = 010 y = 011 if length = 0: 12 return [2, None, None] 13 try: 14 x = lis. index ([")", None]) 15 minutes T: 16 err = 117 lis. reverse () 18 try: 19 y = lis. index (["(", None], length-x-1) 20 kg/t: 21 err = 122 lis. reverse () 23 y = length-y-124 if err = return [1, None, None] 26 else: 27 return [0, y, x] 28 29 30 ############################# parse: unary binary ternary prenthesis function expr31 ########### return value: 32 ############ 0 parsed sucessfully33 ############## 1 syntax error34 ####### ### ################## Find first ') '35 def parse_comp_expr (lis): 36 while if len (lis) = return 139 if len (lis) = if lis [0] [0] [0] = '@': 41 return 042 else: 43 return 144 place = module_parenthesis_place (lis) 45 if place [0] = 0: 46 mirror = lis [(place [1] + 1 ): place [2] 47 if parse_simple_expr (mirror) = 0: 48 if place [1]> = 1 and lis [place [1]-1] [0] = '@ var ': 49 '''func''' 50 funcName = lis [place [1]-1] [1] 51 del Lis [place [1]-1 :( place [2] + 1)] 52 lis. insert (place [1]-1, ["@ func", funcName, mirror [0]) 53 else: 54 del lis [place [1] :( place [2] + 1)] 55 lis. insert (place [1], mirror [0]) 56 else: 57 return 158 else: 59 return parse_simple_expr (lis) 60 return 1 copy the code so that the Code ends here. The following shows the experiment result: copy the code >>> ls = [['(', None], ['@ var', 'F'], ['(', None], ['@ num', '1'], [', ', None], [' @ num', '2'], [',', None], ['@ num', '3'], [', ', None], ['! ', None], ['-', None], [' @ var ', 'x'], ['? ', None], [' @ var', 'y'], [':', None], ['~ ', None], [' @ var', 'z'], [')', None], ['-', None], ['@ num ', '3'], [')', None], ['/', None], ['@ num ', '4'] >>> ls [['(', None], ['@ var', 'F'], [' (', None], ['@ num', '1'], [', ', None], [' @ num', '2'], [',', None], ['@ num', '3'], [', ', None], ['! ', None], ['-', None], [' @ var ', 'x'], ['? ', None], [' @ var', 'y'], [':', None], ['~ ', None], [' @ var', 'z'], [')', None], ['-', None], ['@ num ', '3'], [')', None], ['/', None], ['@ num', '4'] >>> len (ls) 23 >>> parse_comp_expr (ls); ls0 [['@ expr','/', [' @ expr', '-', ['@ func ', 'F', ['@ expr_list', ['@ num', '1'], [' @ num', '2'], ['@ num ', '3'], ['@ expr ','?: ', [' @ Expr ','! ', [' @ Expr', '-', ['@ var', 'x'], ['@ var', 'y'], ['@ expr ','~ ', [' @ Var', 'z'], ['@ num', '3'], [' @ num ', '4'] >>> len (ls) 1 >>> copy code