pyemaps 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyemaps/COPYING +798 -0
- pyemaps/CifFile/CifFile_module.py +3117 -0
- pyemaps/CifFile/StarFile.py +2496 -0
- pyemaps/CifFile/TypeContentsParser.py +82 -0
- pyemaps/CifFile/YappsStarParser_1_0.py +289 -0
- pyemaps/CifFile/YappsStarParser_1_1.py +288 -0
- pyemaps/CifFile/YappsStarParser_2_0.py +369 -0
- pyemaps/CifFile/YappsStarParser_STAR2.py +382 -0
- pyemaps/CifFile/__init__.py +7 -0
- pyemaps/CifFile/drel/__init__.py +1 -0
- pyemaps/CifFile/drel/drel_ast_yacc.py +582 -0
- pyemaps/CifFile/drel/drel_lex.py +228 -0
- pyemaps/CifFile/drel/drel_runtime.py +126 -0
- pyemaps/CifFile/drel/parsetab.py +185 -0
- pyemaps/CifFile/drel/py_from_ast.py +628 -0
- pyemaps/CifFile/parsetab.py +185 -0
- pyemaps/CifFile/yapps3_compiled_rt.py +390 -0
- pyemaps/README.md +201 -0
- pyemaps/__config__.py +91 -0
- pyemaps/__init__.py +233 -0
- pyemaps/__main__.py +219 -0
- pyemaps/__version__.py +1 -0
- pyemaps/cdata/Aluminium.xtl +4 -0
- pyemaps/cdata/AluminiumOxide.xtl +5 -0
- pyemaps/cdata/Aluminium_FCC.xtl +4 -0
- pyemaps/cdata/BariumTitanate_180k.xtl +6 -0
- pyemaps/cdata/BariumTitanate_270k.xtl +7 -0
- pyemaps/cdata/BariumTitanate_Tetra.xtl +7 -0
- pyemaps/cdata/BiMnO3.xtl +27 -0
- pyemaps/cdata/Boron_Tetra.xtl +8 -0
- pyemaps/cdata/CadmiumSelenide_Hex.xtl +5 -0
- pyemaps/cdata/CadmiumSulfide_Cubic.xtl +5 -0
- pyemaps/cdata/CadmiumSulfide_Hex.xtl +5 -0
- pyemaps/cdata/Chromium_BCC.xtl +4 -0
- pyemaps/cdata/CoSb3_Skutterudite.xtl +5 -0
- pyemaps/cdata/CopperOxide.xtl +5 -0
- pyemaps/cdata/Copper_FCC.xtl +4 -0
- pyemaps/cdata/Cu2O_Cuprite.xtl +5 -0
- pyemaps/cdata/Diamond.xtl +4 -0
- pyemaps/cdata/ErbiumPyrogermanate.xtl +9 -0
- pyemaps/cdata/FePd_Tetra.xtl +5 -0
- pyemaps/cdata/FeS2_Pyrite.xtl +15 -0
- pyemaps/cdata/GalliumAntimonide.xtl +5 -0
- pyemaps/cdata/GalliumArsenide.xtl +5 -0
- pyemaps/cdata/GalliumNitride.xtl +5 -0
- pyemaps/cdata/Germanium.xtl +4 -0
- pyemaps/cdata/Gold_FCC.xtl +4 -0
- pyemaps/cdata/IndiumArsenide.xtl +5 -0
- pyemaps/cdata/LaMnO3.xtl +7 -0
- pyemaps/cdata/LeadZirconateTitanate.xtl +8 -0
- pyemaps/cdata/Li2MnO3.xtl +13 -0
- pyemaps/cdata/NaFeO2.xtl +6 -0
- pyemaps/cdata/Nb3Sn.xtl +5 -0
- pyemaps/cdata/Pentacene.xtl +39 -0
- pyemaps/cdata/Silicon.xtl +4 -0
- pyemaps/cdata/StrontiumTitanate.xtl +6 -0
- pyemaps/cdata/TelluriumDioxide.xtl +5 -0
- pyemaps/cdata/TinDioxide_RT.xtl +5 -0
- pyemaps/cdata/TitaniumDioxide_Anatase.xtl +5 -0
- pyemaps/cdata/TitaniumDioxide_Rutile.xtl +5 -0
- pyemaps/cdata/TungstenDiselenide.xtl +5 -0
- pyemaps/cdata/VanadiumDioxide_RT.xtl +6 -0
- pyemaps/cdata/ZincOxide.xtl +5 -0
- pyemaps/cdata/Zinc_HCP.xtl +4 -0
- pyemaps/cdata/ZirconiumNitride.xtl +5 -0
- pyemaps/cdata/limno2.xtl +6 -0
- pyemaps/crystals.py +1415 -0
- pyemaps/ddiffs.py +147 -0
- pyemaps/diffract/__init__.py +70 -0
- pyemaps/diffract/bloch_dec.py +779 -0
- pyemaps/diffract/csf_dec.py +242 -0
- pyemaps/diffract/dif_dec.py +519 -0
- pyemaps/diffract/dpgen_dec.py +175 -0
- pyemaps/diffract/mxtal_dec.py +201 -0
- pyemaps/diffract/powder_dec.py +137 -0
- pyemaps/diffract/stereo_dec.py +111 -0
- pyemaps/display.py +791 -0
- pyemaps/emcontrols.py +1017 -0
- pyemaps/errors.py +266 -0
- pyemaps/fileutils.py +1001 -0
- pyemaps/kdiffs.py +1221 -0
- pyemaps/license.txt +42 -0
- pyemaps/samples/adf.py +137 -0
- pyemaps/samples/al.img +0 -0
- pyemaps/samples/al_dpgen.py +57 -0
- pyemaps/samples/al_ediom.py +94 -0
- pyemaps/samples/convert_image.py +88 -0
- pyemaps/samples/dm_diff.py +225 -0
- pyemaps/samples/mask.im3 +0 -0
- pyemaps/samples/powder.py +51 -0
- pyemaps/samples/raw.img +0 -0
- pyemaps/samples/si_bloch.py +120 -0
- pyemaps/samples/si_constructor.py +51 -0
- pyemaps/samples/si_csf.py +59 -0
- pyemaps/samples/si_dif.py +134 -0
- pyemaps/samples/si_lacbed.py +59 -0
- pyemaps/samples/si_pyemaps.py +80 -0
- pyemaps/samples/si_scm.py +156 -0
- pyemaps/samples/si_stereo.py +116 -0
- pyemaps/scattering/__init__.py +26 -0
- pyemaps/scattering/sct_dec.py +31 -0
- pyemaps/spg/__init__.py +25 -0
- pyemaps/spg/spg_dec.py +60 -0
- pyemaps/stackimg.py +1031 -0
- pyemaps/xtal.py +222 -0
- pyemaps-2.0.0.dist-info/METADATA +231 -0
- pyemaps-2.0.0.dist-info/RECORD +112 -0
- pyemaps-2.0.0.dist-info/WHEEL +5 -0
- pyemaps-2.0.0.dist-info/entry_points.txt +2 -0
- pyemaps-2.0.0.dist-info/licenses/COPYING +798 -0
- pyemaps-2.0.0.dist-info/licenses/license.txt +42 -0
- pyemaps-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
# A dREL grammar written for python-ply
|
|
2
|
+
#
|
|
3
|
+
# The output is an Abstract Syntax Tree that represents a
|
|
4
|
+
# function fragment that needs to be wrapped with information
|
|
5
|
+
# appropriate to the target language.
|
|
6
|
+
|
|
7
|
+
# The grammar is based on the Python 2.7 grammar, in
|
|
8
|
+
# consultation with Doug du Boulay's JsCifBrowser
|
|
9
|
+
# grammar (also derived from a Python grammar).
|
|
10
|
+
|
|
11
|
+
# To maximize python3/python2 compatibility
|
|
12
|
+
from __future__ import print_function
|
|
13
|
+
from __future__ import unicode_literals
|
|
14
|
+
from __future__ import absolute_import
|
|
15
|
+
|
|
16
|
+
from .drel_lex import lexer,tokens
|
|
17
|
+
import ply.yacc as yacc
|
|
18
|
+
|
|
19
|
+
# Overall translation unit
|
|
20
|
+
|
|
21
|
+
# Our input is a sequence of statements
|
|
22
|
+
def p_input(p):
|
|
23
|
+
'''input : maybe_nline statement
|
|
24
|
+
| input statement '''
|
|
25
|
+
if p[1] is None:
|
|
26
|
+
p[0] = p[2]
|
|
27
|
+
else:
|
|
28
|
+
so_far = p[1][1]
|
|
29
|
+
new_statements = p[2][1]
|
|
30
|
+
p[0] = ["STATEMENTS",p[1][1] + p[2][1]]
|
|
31
|
+
#print('input now {!r}'.format(p[0]))
|
|
32
|
+
|
|
33
|
+
# We distinguish between compound statements and
|
|
34
|
+
# small statements. Small statements may be
|
|
35
|
+
# chained together on a single line with semicolon
|
|
36
|
+
# separators. Compound statements are not separated
|
|
37
|
+
# in this way, and will always be terminated by
|
|
38
|
+
# a newline.
|
|
39
|
+
def p_statement(p):
|
|
40
|
+
'''statement : simple_stmt newlines
|
|
41
|
+
| simple_stmt ";" newlines
|
|
42
|
+
| compound_stmt '''
|
|
43
|
+
p[0] = p[1]
|
|
44
|
+
|
|
45
|
+
# A simple statement is a sequence of small statements terminated by
|
|
46
|
+
# a NEWLINE or EOF
|
|
47
|
+
def p_simple_stmt(p):
|
|
48
|
+
''' simple_stmt : small_stmt
|
|
49
|
+
| simple_stmt ";" small_stmt '''
|
|
50
|
+
if len(p) == 2:
|
|
51
|
+
p[0] = ["STATEMENTS",[p[1]]]
|
|
52
|
+
else:
|
|
53
|
+
p[0] = ["STATEMENTS",p[1][1] + [p[3]]]
|
|
54
|
+
|
|
55
|
+
# This production appears inside a set of braces. Any statement
|
|
56
|
+
# will be automatically terminated by a newline so we do not
|
|
57
|
+
# need to include that here
|
|
58
|
+
def p_statements(p):
|
|
59
|
+
'''statements : statement
|
|
60
|
+
| statements statement '''
|
|
61
|
+
if len(p) == 2: p[0] = p[1]
|
|
62
|
+
else: p[0] = ["STATEMENTS", p[1][1] + [p[2]]]
|
|
63
|
+
|
|
64
|
+
def p_small_stmt(p):
|
|
65
|
+
'''small_stmt : expr_stmt
|
|
66
|
+
| print_stmt
|
|
67
|
+
| break_stmt
|
|
68
|
+
| next_stmt'''
|
|
69
|
+
p[0] = p[1]
|
|
70
|
+
|
|
71
|
+
def p_break_stmt(p):
|
|
72
|
+
'''break_stmt : BREAK'''
|
|
73
|
+
p[0] = ["BREAK"]
|
|
74
|
+
|
|
75
|
+
def p_next_stmt(p):
|
|
76
|
+
'''next_stmt : NEXT'''
|
|
77
|
+
p[0] = ["NEXT"]
|
|
78
|
+
|
|
79
|
+
def p_print_stmt(p):
|
|
80
|
+
'''print_stmt : PRINT expression '''
|
|
81
|
+
p[0] = ['PRINT', p[2]]
|
|
82
|
+
|
|
83
|
+
# Note here that a simple testlist_star_expr is useless as in our
|
|
84
|
+
# side-effect-free world it will be evaluated and discarded. We
|
|
85
|
+
# could just drop it right now but we let it go through to the
|
|
86
|
+
# AST processor for language-dependent processing
|
|
87
|
+
def p_expr_stmt(p):
|
|
88
|
+
''' expr_stmt : testlist_star_expr
|
|
89
|
+
| testlist_star_expr AUGOP testlist_star_expr
|
|
90
|
+
| testlist_star_expr "=" testlist_star_expr
|
|
91
|
+
| fancy_drel_assignment_stmt '''
|
|
92
|
+
if len(p) == 2 and p[1][0] != 'FANCY_ASSIGN': # we have a list of expressions which we
|
|
93
|
+
p[0] = ["EXPRLIST",p[1]]
|
|
94
|
+
elif len(p) == 2 and p[1][0] == 'FANCY_ASSIGN':
|
|
95
|
+
p[0] = p[1]
|
|
96
|
+
else:
|
|
97
|
+
p[0] = ["ASSIGN",p[1],p[2],p[3]]
|
|
98
|
+
|
|
99
|
+
def p_testlist_star_expr(p): # list of expressions in fact
|
|
100
|
+
''' testlist_star_expr : expression
|
|
101
|
+
| testlist_star_expr "," maybe_nline expression '''
|
|
102
|
+
if len(p) == 2:
|
|
103
|
+
p[0] = [p[1]]
|
|
104
|
+
else:
|
|
105
|
+
p[0] = p[1] + [p[4]]
|
|
106
|
+
|
|
107
|
+
# Simplified from the python 2.5 version due to apparent conflict with
|
|
108
|
+
# the other type of IF expression...
|
|
109
|
+
#
|
|
110
|
+
def p_expression(p):
|
|
111
|
+
'''expression : or_test '''
|
|
112
|
+
p[0] = ["EXPR",p[1]]
|
|
113
|
+
|
|
114
|
+
# This is too generous, as it allows a function call on the
|
|
115
|
+
# LHS to be assigned to. This will cause a syntax error on
|
|
116
|
+
# execution.
|
|
117
|
+
|
|
118
|
+
def p_or_test(p):
|
|
119
|
+
''' or_test : and_test
|
|
120
|
+
| or_test OR and_test
|
|
121
|
+
| or_test BADOR and_test'''
|
|
122
|
+
if len(p) == 2: p[0] = p[1]
|
|
123
|
+
else: p[0] = ["MATHOP","or",p[1],p[3]]
|
|
124
|
+
|
|
125
|
+
def p_and_test(p):
|
|
126
|
+
'''and_test : not_test
|
|
127
|
+
| and_test AND not_test
|
|
128
|
+
| and_test BADAND not_test'''
|
|
129
|
+
if len(p) == 2: p[0] = p[1]
|
|
130
|
+
else: p[0] = ["MATHOP","and", p[1],p[3]]
|
|
131
|
+
|
|
132
|
+
def p_not_test(p):
|
|
133
|
+
'''not_test : comparison
|
|
134
|
+
| NOT not_test'''
|
|
135
|
+
if len(p) == 2: p[0] = p[1]
|
|
136
|
+
else: p[0] = ["UNARY","not",p[2]]
|
|
137
|
+
|
|
138
|
+
def p_comparison(p):
|
|
139
|
+
'''comparison : a_expr
|
|
140
|
+
| a_expr comp_operator a_expr'''
|
|
141
|
+
if len(p) == 2: p[0] = p[1]
|
|
142
|
+
else:
|
|
143
|
+
p[0] = ["MATHOP",p[2],p[1],p[3]]
|
|
144
|
+
|
|
145
|
+
def p_comp_operator(p):
|
|
146
|
+
'''comp_operator : restricted_comp_operator
|
|
147
|
+
| IN
|
|
148
|
+
| NOT IN '''
|
|
149
|
+
if len(p)==3:
|
|
150
|
+
p[0] = "not in"
|
|
151
|
+
else: p[0] = p[1]
|
|
152
|
+
|
|
153
|
+
def p_restricted_comp_operator(p): #for loop tests
|
|
154
|
+
'''restricted_comp_operator : "<"
|
|
155
|
+
| ">"
|
|
156
|
+
| GTE
|
|
157
|
+
| LTE
|
|
158
|
+
| NEQ
|
|
159
|
+
| ISEQUAL '''
|
|
160
|
+
p[0] = p[1]
|
|
161
|
+
|
|
162
|
+
def p_a_expr(p):
|
|
163
|
+
'''a_expr : m_expr
|
|
164
|
+
| a_expr "+" m_expr
|
|
165
|
+
| a_expr "-" m_expr'''
|
|
166
|
+
if len(p) == 2:
|
|
167
|
+
p[0] = p[1]
|
|
168
|
+
else:
|
|
169
|
+
p[0] = ["MATHOP",p[2], p[1], p[3]]
|
|
170
|
+
|
|
171
|
+
def p_m_expr(p): #note bitwise and and or are pycifrw extensions
|
|
172
|
+
'''m_expr : u_expr
|
|
173
|
+
| m_expr "*" u_expr
|
|
174
|
+
| m_expr "/" u_expr
|
|
175
|
+
| m_expr "^" u_expr
|
|
176
|
+
| m_expr "&" u_expr
|
|
177
|
+
| m_expr "|" u_expr '''
|
|
178
|
+
if len(p) == 2:
|
|
179
|
+
p[0] = p[1]
|
|
180
|
+
else:
|
|
181
|
+
p[0] = ["MATHOP",p[2],p[1],p[3]]
|
|
182
|
+
|
|
183
|
+
def p_u_expr(p):
|
|
184
|
+
'''u_expr : power
|
|
185
|
+
| "-" u_expr
|
|
186
|
+
| "+" u_expr'''
|
|
187
|
+
if len(p) == 2:
|
|
188
|
+
p[0] = p[1]
|
|
189
|
+
else:
|
|
190
|
+
p[0] = ["SIGN",p[1],p[2]]
|
|
191
|
+
|
|
192
|
+
def p_power(p):
|
|
193
|
+
'''power : primary
|
|
194
|
+
| primary POWER u_expr'''
|
|
195
|
+
if len(p) == 2:
|
|
196
|
+
p[0] = p[1]
|
|
197
|
+
else:
|
|
198
|
+
p[0] = ["MATHOP","**",p[1] , p[3]]
|
|
199
|
+
# print('At power: p[0] is {!r}'.format(p[0]))
|
|
200
|
+
|
|
201
|
+
def p_primary(p):
|
|
202
|
+
'''primary : atom
|
|
203
|
+
| attributeref
|
|
204
|
+
| subscription
|
|
205
|
+
| slicing
|
|
206
|
+
| call'''
|
|
207
|
+
# print 'Primary -> %s' % repr(p[1])
|
|
208
|
+
p[0] = p[1]
|
|
209
|
+
|
|
210
|
+
def p_atom(p):
|
|
211
|
+
'''atom : ID
|
|
212
|
+
| item_tag
|
|
213
|
+
| literal
|
|
214
|
+
| enclosure'''
|
|
215
|
+
# print 'Atom -> %s' % repr(p[1])
|
|
216
|
+
p[0] = ["ATOM",p[1]]
|
|
217
|
+
|
|
218
|
+
def p_item_tag(p):
|
|
219
|
+
'''item_tag : ITEM_TAG'''
|
|
220
|
+
p[0] = ["ITEM_TAG",p[1]]
|
|
221
|
+
|
|
222
|
+
def p_literal(p):
|
|
223
|
+
'''literal : stringliteral
|
|
224
|
+
| INTEGER
|
|
225
|
+
| HEXINT
|
|
226
|
+
| OCTINT
|
|
227
|
+
| BININT
|
|
228
|
+
| REAL
|
|
229
|
+
| IMAGINARY'''
|
|
230
|
+
# print 'literal-> %s' % repr(p[1])
|
|
231
|
+
p[0] = ["LITERAL",p[1]]
|
|
232
|
+
|
|
233
|
+
def p_stringliteral(p):
|
|
234
|
+
'''stringliteral : STRPREFIX SHORTSTRING
|
|
235
|
+
| STRPREFIX LONGSTRING
|
|
236
|
+
| SHORTSTRING
|
|
237
|
+
| LONGSTRING'''
|
|
238
|
+
if len(p)==3: p[0] = p[1]+p[2]
|
|
239
|
+
else: p[0] = p[1]
|
|
240
|
+
|
|
241
|
+
def p_enclosure(p):
|
|
242
|
+
'''enclosure : parenth_form
|
|
243
|
+
| string_conversion
|
|
244
|
+
| list_display
|
|
245
|
+
| table_display '''
|
|
246
|
+
p[0]=p[1]
|
|
247
|
+
|
|
248
|
+
def p_parenth_form(p):
|
|
249
|
+
'''parenth_form : OPEN_PAREN testlist_star_expr CLOSE_PAREN
|
|
250
|
+
| OPEN_PAREN CLOSE_PAREN '''
|
|
251
|
+
if len(p) == 3: p[0] = ["GROUP"]
|
|
252
|
+
else:
|
|
253
|
+
p[0] = ["GROUP",p[2]]
|
|
254
|
+
# print('Parens: {!r}'.format(p[0]))
|
|
255
|
+
|
|
256
|
+
def p_string_conversion(p):
|
|
257
|
+
'''string_conversion : "`" testlist_star_expr "`" '''
|
|
258
|
+
# WARNING: NOT IN PUBLISHED dREL papaer
|
|
259
|
+
p[0] = ["FUNC_CALL","str",p[2]]
|
|
260
|
+
|
|
261
|
+
def p_list_display(p):
|
|
262
|
+
''' list_display : "[" maybe_nline listmaker maybe_nline "]"
|
|
263
|
+
| "[" maybe_nline "]" '''
|
|
264
|
+
if len(p) == 4: p[0] = ["LIST"]
|
|
265
|
+
else:
|
|
266
|
+
p[0] = ["LIST"] + p[3]
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
# scrap the trailing comma
|
|
270
|
+
def p_listmaker(p):
|
|
271
|
+
'''listmaker : expression listmaker2 '''
|
|
272
|
+
p[0] = [p[1]] + p[2]
|
|
273
|
+
# print('listmaker: {!r}'.format(p[0]))
|
|
274
|
+
|
|
275
|
+
def p_listmaker2(p):
|
|
276
|
+
'''listmaker2 : "," maybe_nline expression
|
|
277
|
+
| listmaker2 "," maybe_nline expression
|
|
278
|
+
| '''
|
|
279
|
+
if len(p) == 4:
|
|
280
|
+
p[0] = [p[3]]
|
|
281
|
+
elif len(p) < 2:
|
|
282
|
+
p[0] = []
|
|
283
|
+
else:
|
|
284
|
+
p[0] = p[1] + [p[4]]
|
|
285
|
+
|
|
286
|
+
# define tables
|
|
287
|
+
def p_table_display(p):
|
|
288
|
+
''' table_display : "{" maybe_nline tablemaker maybe_nline "}"
|
|
289
|
+
| "{" maybe_nline "}" '''
|
|
290
|
+
if len(p) == 4:
|
|
291
|
+
p[0] = ["TABLE"]
|
|
292
|
+
else:
|
|
293
|
+
p[0] = ["TABLE"] + p[3]
|
|
294
|
+
|
|
295
|
+
def p_tablemaker(p):
|
|
296
|
+
'''tablemaker : stringliteral ":" expression tablemaker2 '''
|
|
297
|
+
p[0] = [(p[1],p[3])] + p[4]
|
|
298
|
+
|
|
299
|
+
def p_tablemaker2(p):
|
|
300
|
+
'''tablemaker2 : "," maybe_nline stringliteral ":" expression
|
|
301
|
+
| tablemaker2 "," maybe_nline stringliteral ":" expression
|
|
302
|
+
| '''
|
|
303
|
+
if len(p) == 6:
|
|
304
|
+
p[0] = [(p[3],p[5])]
|
|
305
|
+
elif len(p) < 2:
|
|
306
|
+
p[0] = []
|
|
307
|
+
else:
|
|
308
|
+
p[0] = p[1] + [(p[4],p[6])]
|
|
309
|
+
|
|
310
|
+
# Note that we need to catch tags of the form 't.12', which
|
|
311
|
+
# our lexer will interpret as ID REAL. We therefore also
|
|
312
|
+
# accept t.12(3), which is not allowed, but we don't bother
|
|
313
|
+
# trying to catch this error here.
|
|
314
|
+
|
|
315
|
+
def p_attributeref(p):
|
|
316
|
+
'''attributeref : primary attribute_tag '''
|
|
317
|
+
p[0] = ["ATTRIBUTE",p[1],p[2]]
|
|
318
|
+
|
|
319
|
+
def p_attribute_tag(p):
|
|
320
|
+
'''attribute_tag : "." ID
|
|
321
|
+
| REAL '''
|
|
322
|
+
if len(p) == 3:
|
|
323
|
+
p[0] = p[2]
|
|
324
|
+
else:
|
|
325
|
+
p[0] = p[1][1:]
|
|
326
|
+
|
|
327
|
+
def p_subscription(p):
|
|
328
|
+
'''subscription : primary "[" expression "]" '''
|
|
329
|
+
p[0] = ["SUBSCRIPTION",p[1],p[3]]
|
|
330
|
+
|
|
331
|
+
def p_slicing(p):
|
|
332
|
+
'''slicing : primary "[" proper_slice "]"
|
|
333
|
+
| primary "[" slice_list "]" '''
|
|
334
|
+
p[0] = ["SLICE", p[1], p[3] ]
|
|
335
|
+
|
|
336
|
+
def p_proper_slice(p):
|
|
337
|
+
'''proper_slice : short_slice
|
|
338
|
+
| long_slice '''
|
|
339
|
+
p[0] = [p[1]]
|
|
340
|
+
|
|
341
|
+
# Our AST slice convention is that, if anything is mentioned,
|
|
342
|
+
# the first element is always
|
|
343
|
+
# explicitly mentioned. A single element will be a starting
|
|
344
|
+
# element. Two elements are start and finish. An empty list
|
|
345
|
+
# is all elements. Three elements are start, finish, step.
|
|
346
|
+
# We combine these into a list of slices.
|
|
347
|
+
|
|
348
|
+
def p_short_slice(p):
|
|
349
|
+
'''short_slice : ":"
|
|
350
|
+
| expression ":" expression
|
|
351
|
+
| ":" expression
|
|
352
|
+
| expression ":" '''
|
|
353
|
+
if len(p) == 2: p[0] = []
|
|
354
|
+
if len(p) == 4: p[0] = [p[1],p[3]]
|
|
355
|
+
if len(p) == 3 and p[1] == ":":
|
|
356
|
+
p[0] = [0,p[2]]
|
|
357
|
+
if len(p) == 3 and p[2] == ":":
|
|
358
|
+
p[0] = [p[1]]
|
|
359
|
+
|
|
360
|
+
def p_long_slice(p):
|
|
361
|
+
'''long_slice : short_slice ":" expression '''
|
|
362
|
+
if len(p) == 4:
|
|
363
|
+
p[0] = p[1] + [p[3]]
|
|
364
|
+
else:
|
|
365
|
+
p[0] = p[1]
|
|
366
|
+
|
|
367
|
+
def p_slice_list(p):
|
|
368
|
+
''' slice_list : slice_item
|
|
369
|
+
| slice_list "," slice_item '''
|
|
370
|
+
if len(p) == 2:
|
|
371
|
+
p[0] = [p[1]]
|
|
372
|
+
else:
|
|
373
|
+
p[0] = p[1] + [p[3]]
|
|
374
|
+
|
|
375
|
+
def p_slice_item(p):
|
|
376
|
+
''' slice_item : expression
|
|
377
|
+
| proper_slice '''
|
|
378
|
+
p[0] = p[1]
|
|
379
|
+
|
|
380
|
+
def p_call(p):
|
|
381
|
+
'''call : ID OPEN_PAREN CLOSE_PAREN
|
|
382
|
+
| ID OPEN_PAREN argument_list CLOSE_PAREN '''
|
|
383
|
+
if len(p) == 4:
|
|
384
|
+
p[0] = ["FUNC_CALL",p[1],[]]
|
|
385
|
+
else:
|
|
386
|
+
p[0] = ["FUNC_CALL",p[1],p[3]]
|
|
387
|
+
#print("Function call: {!r}".format(p[0]))
|
|
388
|
+
|
|
389
|
+
# These are the arguments to a call, not a definition
|
|
390
|
+
|
|
391
|
+
def p_argument_list(p):
|
|
392
|
+
'''argument_list : func_arg
|
|
393
|
+
| argument_list "," func_arg '''
|
|
394
|
+
if len(p) == 2:
|
|
395
|
+
p[0] = [p[1]]
|
|
396
|
+
else:
|
|
397
|
+
p[0] = p[1] + [p[3]]
|
|
398
|
+
|
|
399
|
+
def p_func_arg(p):
|
|
400
|
+
'''func_arg : expression '''
|
|
401
|
+
p[0] = p[1]
|
|
402
|
+
|
|
403
|
+
def p_fancy_drel_assignment_stmt(p):
|
|
404
|
+
'''fancy_drel_assignment_stmt : ID OPEN_PAREN dotlist CLOSE_PAREN '''
|
|
405
|
+
p[0] = ["FANCY_ASSIGN",p[1],p[3]]
|
|
406
|
+
# print("Fancy assignment -> {!r}".format(p[0]))
|
|
407
|
+
|
|
408
|
+
# Something made up specially for drel. A newline is OK between assignments
|
|
409
|
+
|
|
410
|
+
def p_dotlist(p):
|
|
411
|
+
'''dotlist : "." ID "=" expression
|
|
412
|
+
| dotlist "," "." ID "=" expression '''
|
|
413
|
+
if len(p) <= 5: #first element of dotlist
|
|
414
|
+
p[0] = [[p[2],p[4]]]
|
|
415
|
+
else: #append to previous elements
|
|
416
|
+
p[0] = p[1] + [[p[4],p[6]]]
|
|
417
|
+
|
|
418
|
+
def p_exprlist(p):
|
|
419
|
+
''' exprlist : a_expr
|
|
420
|
+
| exprlist "," a_expr '''
|
|
421
|
+
if len(p) == 2:
|
|
422
|
+
p[0] = [p[1]]
|
|
423
|
+
else: p[0] = p[1] + [p[3]]
|
|
424
|
+
|
|
425
|
+
# a (potentially enclosed) list of ids
|
|
426
|
+
def p_id_list(p):
|
|
427
|
+
''' id_list : ID
|
|
428
|
+
| id_list "," ID '''
|
|
429
|
+
|
|
430
|
+
if len(p) == 2:
|
|
431
|
+
p[0] = [p[1]]
|
|
432
|
+
else:
|
|
433
|
+
p[0] = p[1] + [p[3]]
|
|
434
|
+
|
|
435
|
+
# now for the compound statements. We prepare them as a "STATEMENT"
|
|
436
|
+
# list for smooth processing in the simple_stmt production
|
|
437
|
+
|
|
438
|
+
def p_compound_stmt(p):
|
|
439
|
+
'''compound_stmt : if_stmt
|
|
440
|
+
| if_else_stmt
|
|
441
|
+
| for_stmt
|
|
442
|
+
| do_stmt
|
|
443
|
+
| loop_stmt
|
|
444
|
+
| with_stmt
|
|
445
|
+
| repeat_stmt
|
|
446
|
+
| funcdef '''
|
|
447
|
+
p[0] = ["STATEMENTS",[p[1]]]
|
|
448
|
+
#print "Compound statement: \n" + p[0]
|
|
449
|
+
|
|
450
|
+
# There must only be one else statement at the end of the else if statements,
|
|
451
|
+
# so we show this by creating a separate production
|
|
452
|
+
def p_if_else_stmt(p):
|
|
453
|
+
'''if_else_stmt : if_stmt ELSE suite'''
|
|
454
|
+
p[0] = p[1]
|
|
455
|
+
p[0].append(p[3])
|
|
456
|
+
|
|
457
|
+
# The AST node is [IF_EXPR,cond, suite,[[elseif cond1,suite],[elseifcond2,suite]...]]
|
|
458
|
+
def p_if_stmt(p):
|
|
459
|
+
'''if_stmt : IF OPEN_PAREN expression CLOSE_PAREN maybe_nline suite
|
|
460
|
+
| if_stmt ELSEIF OPEN_PAREN expression CLOSE_PAREN maybe_nline suite '''
|
|
461
|
+
if len(p) == 7:
|
|
462
|
+
p[0] = ["IF_EXPR"]
|
|
463
|
+
p[0].append(p[3])
|
|
464
|
+
p[0].append(p[6])
|
|
465
|
+
p[0].append([])
|
|
466
|
+
else:
|
|
467
|
+
p[0] = p[1]
|
|
468
|
+
p[0][3].append([p[4],p[7]])
|
|
469
|
+
|
|
470
|
+
# Note the dREL divergence from Python here: we allow compound
|
|
471
|
+
# statements to follow without a separate block (like C etc.) Where
|
|
472
|
+
# we have a single statement immediately following we have to make the
|
|
473
|
+
# statement block. A small_stmt will be a single production, so must
|
|
474
|
+
# be put into a list in order to match the 'statements' structure
|
|
475
|
+
# (i.e. 2nd element is a list of statements). A compound_stmt is thus
|
|
476
|
+
# forced to be also a non-listed object.
|
|
477
|
+
|
|
478
|
+
def p_suite(p):
|
|
479
|
+
'''suite : statement
|
|
480
|
+
| "{" maybe_nline statements "}" maybe_nline '''
|
|
481
|
+
if len(p) == 2:
|
|
482
|
+
p[0] = p[1]
|
|
483
|
+
else:
|
|
484
|
+
p[0] = p[3] #already have a statement block
|
|
485
|
+
|
|
486
|
+
def p_for_stmt(p):
|
|
487
|
+
'''for_stmt : FOR id_list IN testlist_star_expr suite
|
|
488
|
+
| FOR "[" id_list "]" IN testlist_star_expr suite '''
|
|
489
|
+
if len(p)==6:
|
|
490
|
+
p[0] = ["FOR", p[2], p[4], p[5]]
|
|
491
|
+
else:
|
|
492
|
+
p[0] = ["FOR", p[3], p[6], p[7]]
|
|
493
|
+
|
|
494
|
+
def p_loop_stmt(p):
|
|
495
|
+
'''loop_stmt : loop_head suite '''
|
|
496
|
+
p[0] = ["LOOP"] + p[1] + [p[2]]
|
|
497
|
+
|
|
498
|
+
# We capture a list of all the actually present items in the current
|
|
499
|
+
# datafile
|
|
500
|
+
def p_loop_head(p):
|
|
501
|
+
'''loop_head : LOOP ID AS ID
|
|
502
|
+
| LOOP ID AS ID ":" ID
|
|
503
|
+
| LOOP ID AS ID ":" ID restricted_comp_operator ID '''
|
|
504
|
+
|
|
505
|
+
p[0] = [p[2],p[4]]
|
|
506
|
+
if len(p)>= 7:
|
|
507
|
+
p[0] = p[0] + [p[6]]
|
|
508
|
+
else: p[0] = p[0] + [""]
|
|
509
|
+
if len(p) >= 9:
|
|
510
|
+
p[0] = p[0] + [p[7],p[8]]
|
|
511
|
+
else: p[0] = p[0] + ["",""]
|
|
512
|
+
|
|
513
|
+
def p_do_stmt(p):
|
|
514
|
+
'''do_stmt : do_stmt_head suite '''
|
|
515
|
+
p[0] = p[1] + [p[2]]
|
|
516
|
+
|
|
517
|
+
# To translate the dREL do to a for statement, we need to make the
|
|
518
|
+
# end of the range included in the range
|
|
519
|
+
|
|
520
|
+
def p_do_stmt_head(p):
|
|
521
|
+
'''do_stmt_head : DO ID "=" expression "," expression
|
|
522
|
+
| DO ID "=" expression "," expression "," expression'''
|
|
523
|
+
|
|
524
|
+
p[0] = ["DO",p[2],p[4],p[6]]
|
|
525
|
+
if len(p)==9:
|
|
526
|
+
p[0] = p[0] + [p[8]]
|
|
527
|
+
else:
|
|
528
|
+
p[0] = p[0] + [["EXPR",["LITERAL","1"]]]
|
|
529
|
+
|
|
530
|
+
def p_repeat_stmt(p):
|
|
531
|
+
'''repeat_stmt : REPEAT suite'''
|
|
532
|
+
p[0] = ["REPEAT",p[2]]
|
|
533
|
+
|
|
534
|
+
def p_with_stmt(p):
|
|
535
|
+
'''with_stmt : with_head maybe_nline suite'''
|
|
536
|
+
p[0] = p[1]+[p[3]]
|
|
537
|
+
|
|
538
|
+
def p_with_head(p):
|
|
539
|
+
'''with_head : WITH ID AS ID'''
|
|
540
|
+
p[0] = ["WITH",p[2],p[4]]
|
|
541
|
+
|
|
542
|
+
def p_funcdef(p):
|
|
543
|
+
''' funcdef : FUNCTION ID OPEN_PAREN arglist CLOSE_PAREN suite '''
|
|
544
|
+
p[0] = ["FUNCTION",p[2],p[4],p[6]]
|
|
545
|
+
|
|
546
|
+
def p_arglist(p):
|
|
547
|
+
''' arglist : ID ":" list_display
|
|
548
|
+
| arglist "," ID ":" list_display '''
|
|
549
|
+
if len(p) == 4: p[0] = [(p[1],p[2])]
|
|
550
|
+
else: p[0] = p[1] + [(p[3],p[5])]
|
|
551
|
+
|
|
552
|
+
# This production allows us to insert optional newlines
|
|
553
|
+
|
|
554
|
+
def p_maybe_nline(p):
|
|
555
|
+
''' maybe_nline : newlines
|
|
556
|
+
| empty '''
|
|
557
|
+
pass
|
|
558
|
+
|
|
559
|
+
# We need to allow multiple newlines here and not just in the lexer as
|
|
560
|
+
# an intervening comment can cause multiple newline tokens to appear
|
|
561
|
+
|
|
562
|
+
def p_newlines(p):
|
|
563
|
+
''' newlines : NEWLINE
|
|
564
|
+
| newlines NEWLINE '''
|
|
565
|
+
pass
|
|
566
|
+
|
|
567
|
+
def p_empty(p):
|
|
568
|
+
''' empty : '''
|
|
569
|
+
pass
|
|
570
|
+
|
|
571
|
+
def p_error(p):
|
|
572
|
+
try:
|
|
573
|
+
print('Syntax error at position %d, line %d token %s, value %s' % (p.lexpos,p.lineno,p.type,p.value))
|
|
574
|
+
print('Surrounding text: ' + p.lexer.lexdata[max(p.lexpos - 100,0): p.lexpos] + "*" + \
|
|
575
|
+
p.lexer.lexdata[p.lexpos:min(p.lexpos + 100,len(p.lexer.lexdata))])
|
|
576
|
+
except:
|
|
577
|
+
pass
|
|
578
|
+
parser.restart()
|
|
579
|
+
raise SyntaxError
|
|
580
|
+
|
|
581
|
+
#lexer = drel_lex.lexer
|
|
582
|
+
parser = yacc.yacc()
|