1 ''' @file examples/exp/ast_translate.py
2 @brief Demonstrates using the AST for translation
3 of the pattern matched results.
4 Also demonstrates how to use the AST in the replace() function
5 (see @ref apg_py/exp/exp.py.)
12 sys.path.append(os.getcwd())
17 title =
'''This example will demonstrate how to use the AST
18 for matched result translations. ApgExp will be used to match
19 floating point numbers and the AST will be used to put the
20 numbers in a "normalized" form.
21 A second example will use the same AST to create a replacement
22 function to do replacements with the translated matches.
23 See also the examples/exp/ast.py and examples/exp/replace.py examples.
31 def float(state, input, index, length, data):
33 if(state == id.SEM_PRE):
36 data[
'fraction'] =
'0'
40 if(state == id.SEM_POST):
41 exponent =
'' if(data[
'exp'] == 0)
else 'e' + \
42 data[
'esign'] + str(data[
'exp'])
43 data[
'normal'] = data[
'sign'] + \
44 data[
'integer'] +
'.' + data[
'fraction'] + exponent
48 def sign(state, input, index, length, data):
50 if(state == id.SEM_PRE):
51 if(input[index] == 45):
56 def integer(state, input, index, length, data):
58 if(state == id.SEM_PRE):
60 data[
'integer'] = utils.tuple_to_string(
61 input[index:index + length])
65 def fraction(state, input, index, length, data):
67 if(state == id.SEM_PRE):
69 data[
'fraction'] = utils.tuple_to_string(
70 input[index:index + length])
74 def esign(state, input, index, length, data):
76 if(state == id.SEM_PRE):
77 if(input[index] == 45):
82 def exponent(state, input, index, length, data):
84 if(state == id.SEM_PRE):
85 exp = utils.tuple_to_string(input[index:index + length])
86 data[
'exp'] = int(exp)
90 pattern =
'''float = sign decimal exponent
92 decimal = integer [dot fraction]
97 exponent = ["e" esign exp]
109 input +=
'[ 123.e2 ]'
110 input +=
'[ .123E+1 ]'
111 input +=
'[ -1234.56789E-10 ]'
113 input +=
'[ +123e-0 ]'
114 input +=
'[ -.123e-001 ]'
115 input +=
'[ 123e+000 ]'
121 exp.include([
'float',
'sign',
'integer',
'fraction',
'esign',
'exp'])
122 result = exp.exec(input)
124 print(
'\n' + str(testno) +
') Normalize all matched floating point numbers.')
125 print(
'input string: ' + input)
128 result.ast.add_callback(
'float', float)
129 result.ast.add_callback(
'sign', sign)
130 result.ast.add_callback(
'integer', integer)
131 result.ast.add_callback(
'fraction', fraction)
132 result.ast.add_callback(
'esign', esign)
133 result.ast.add_callback(
'exp', exponent)
135 result.ast.translate(data)
136 print(result.match, end=
' => ')
137 print(data[
'normal'])
138 result = exp.exec(input)
141 def fn(input, result):
142 result.ast.add_callback(
'float', float)
143 result.ast.add_callback(
'sign', sign)
144 result.ast.add_callback(
'integer', integer)
145 result.ast.add_callback(
'fraction', fraction)
146 result.ast.add_callback(
'esign', esign)
147 result.ast.add_callback(
'exp', exponent)
149 result.ast.translate(data)
150 return data[
'normal']
158 ') Use AST translation function to replace all matches with normalized form.')
159 print(
'input string: ' + input)
161 result = exp.replace(input, fn)
The ApgExp class provides a pattern-matching engine similar to JavaScript's RegExp
def sign(state, input, index, length, data)
def float(state, input, index, length, data)
def exponent(state, input, index, length, data)
def integer(state, input, index, length, data)
def esign(state, input, index, length, data)
def fraction(state, input, index, length, data)