source: coopr.pyomo/stable/2.3/coopr/pyomo/data/parse_datacmds.py @ 2360

Last change on this file since 2360 was 2360, checked in by wehart, 11 years ago

Merged revisions 2315-2359 via svnmerge from
https://software.sandia.gov/svn/public/coopr/coopr.pyomo/trunk

........

r2330 | wehart | 2010-02-14 13:47:44 -0700 (Sun, 14 Feb 2010) | 7 lines


Setting directory properties to ignore *.pyc files.


Reworking parser management for data command files, to
directly manage the generation of the parsetab.py file.
This file is not called parse_table_datacmds.py, and it is
committed to the coopr.pyomo repository.

........

r2344 | wehart | 2010-02-15 13:44:18 -0700 (Mon, 15 Feb 2010) | 2 lines


Extending definition of svn:ignore to include *.egg-info files.

........

r2350 | wehart | 2010-02-15 15:17:53 -0700 (Mon, 15 Feb 2010) | 3 lines


Unfortunately, this file is being regenerated with path information.
For now, I'm going to delete this from the subversion repository.

........

r2359 | wehart | 2010-02-15 20:26:44 -0700 (Mon, 15 Feb 2010) | 30 lines


  1. Renaming the 'presolve' phase in Pyomo to 'preprocess'. We'll

eventually want an explicit presolve phase, but that will be applied
as a transformation, right before the problem is written and sent
to the solver. Currently, this preprocess phase collects data about
the model and computes the canonical representations for expressions.


  1. Created the ability to support the construction of concrete models.

The concrete_mode() method for Model objects enables this mode.
When in the concrete mode, each component added to the model has
its construct() method called immediately after the component is
added to the model. The symbolic_mode() method for Model objects
can be called to switch back to a symbolic mode (which defers the
execution of construct().


Bad things might happen if you switch back and forth between these
modes. Notably, if you ever generate components in symbolic mode,
then you need to switch back to symbolic mode before calling create().


Note that the Model.create() method is still called when the model
construction is 'done', even when done completely in concrete mode.
This basically calls the preprocessing steps, and this method returns
the current model (i.e. no cloning is done when building a concrete
model).


  1. Created an example directory for concrete models. Note that these

can still be solved with the Pyomo command line. In this
instance, the command line simply executes the script and applies
a solver.

........

File size: 9.3 KB
Line 
1
2#  _________________________________________________________________________
3#
4#  Coopr: A COmmon Optimization Python Repository
5#  Copyright (c) 2008 Sandia Corporation.
6#  This software is distributed under the BSD License.
7#  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8#  the U.S. Government retains certain rights in this software.
9#  For more information, see the Coopr README.txt file.
10#  _________________________________________________________________________
11
12__all__ = ['parse_data_commands']
13
14import re
15import os
16import os.path
17import ply.lex as lex
18import ply.yacc as yacc
19from pyutilib.misc import flatten
20from pyutilib.ply import t_newline, t_ignore, _find_column, p_error, ply_init
21
22tabmodule = 'parse_table_datacmds'
23outputdir = os.path.dirname(os.path.abspath(__file__))+os.sep
24
25## -----------------------------------------------------------
26##
27## Lexer definitions for tokenizing the input
28##
29## -----------------------------------------------------------
30
31_parse_info = None
32debugging = False
33
34reserved = {
35    'data' : 'DATA',
36    'set' : 'SET',
37    'param' : 'PARAM',
38    'end' : 'END',
39    'import' : 'IMPORT',
40    'include' : 'INCLUDE',
41}
42
43# Token names
44tokens = [
45    "COMMA",
46#    "LBRACE",
47#    "RBRACE",
48#    "NUMBER",
49    "SEMICOLON",
50    "COLON",
51    "COLONEQ",
52    "LBRACKET",
53    "RBRACKET",
54    "LPAREN",
55    "RPAREN",
56#    "RANGE",
57    "WORD",
58    "WORDWITHINDEX",
59    "STRING",
60    "QUOTEDSTRING",
61    "FILENAME",
62    "EQ",
63    "TR",
64    "ASTERISK",
65    "NONWORD",
66] + reserved.values()
67
68# Regular expression rules
69t_COMMA     = r","
70t_LBRACKET  = r"\["
71t_RBRACKET  = r"\]"
72#t_NUMBER    = r"[0-9]+(\.[0-9]+){0,1}"
73t_SEMICOLON = r";"
74t_COLON     = r":"
75t_COLONEQ   = r":="
76t_EQ        = r"="
77t_TR        = r"\(tr\)"
78#t_LT        = r"<"
79#t_GT        = r">"
80#t_LBRACE    = r"{"
81#t_RBRACE    = r"}"
82t_LPAREN    = r"\("
83t_RPAREN    = r"\)"
84t_ASTERISK  = r"\*"
85
86# Discard comments
87def t_COMMENT(t):
88    r'\#[^\n]*'
89    #global _comment_list
90    #_comment_list.append(t.value)
91
92def t_WORDWITHINDEX(t):
93    r'[a-zA-Z_0-9][a-zA-Z_0-9\.\-]*\[[a-zA-Z_0-9\.\-,\*]*\]'
94    t.type = reserved.get(t.value,'WORDWITHINDEX')    # Check for reserved words
95    return t
96
97def t_WORD(t):
98    r'[a-zA-Z_0-9][a-zA-Z_0-9\.\-]*'
99    t.type = reserved.get(t.value,'WORD')    # Check for reserved words
100    return t
101
102def t_STRING(t):
103    r'[a-zA-Z_0-9\.+\-]+'
104    t.type = reserved.get(t.value,'STRING')    # Check for reserved words
105    return t
106
107def t_QUOTEDSTRING(t):
108    r'"([^"]|\"\")*"|\'([^\']|\'\')*\''
109    t.type = reserved.get(t.value,'QUOTEDSTRING')    # Check for reserved words
110    return t
111
112def t_FILENAME(t):
113    r'[a-zA-Z_0-9\./\\]*(/|\\)[a-zA-Z_0-9\./\\]*'
114    t.type = reserved.get(t.value,'FILENAME')    # Check for reserved words
115    return t
116
117t_NONWORD   = r"[^\.A-Za-z0-9,;:=<>\*\(\)\#{}\[\] \n\t\r]+"
118
119# Error handling rule
120def t_error(t):             #pragma:nocover
121    raise IOError, "Illegal character '%s'" % t.value[0]
122    t.lexer.skip(1)
123
124
125## -----------------------------------------------------------
126##
127## Yacc grammar for data commands
128##
129## -----------------------------------------------------------
130
131def p_expr(p):
132    '''expr : statements
133            | '''
134
135def p_statements(p):
136    '''statements : statement statements
137                  | statement '''
138
139def p_statement(p):
140    '''statement : SET WORD COLONEQ setdecl SEMICOLON
141                 | SET WORD COLONEQ SEMICOLON
142                 | SET WORD COLON items COLONEQ setdecl SEMICOLON
143                 | SET WORD COLON items COLONEQ SEMICOLON
144                 | SET WORDWITHINDEX COLONEQ setdecl SEMICOLON
145                 | SET WORDWITHINDEX COLONEQ SEMICOLON
146                 | PARAM items COLONEQ paramdecl SEMICOLON
147                 | IMPORT importdecl SEMICOLON
148                 | INCLUDE WORD SEMICOLON
149                 | INCLUDE QUOTEDSTRING SEMICOLON
150                 | DATA SEMICOLON
151                 | END SEMICOLON
152    '''
153    global _parse_info
154    #print "STATEMENT",len(p), p[1:]
155    if p[1] in ['set','param']:
156        _parse_info.append( flatten(p[1:-1]) )
157    elif p[1] in ['include']:
158        _parse_info.append( p[1:-1] )
159    elif p[1] in ['import']:
160        _parse_info.append( [p[1]]+ p[2] )
161        #_parse_info.append( [p[1], p[2][0], p[1:-1] )
162
163def p_setdecl(p):
164    '''setdecl : items'''
165    p[0] = p[1]
166
167def p_paramdecl(p):
168    '''paramdecl : items'''
169    p[0] = p[1]
170
171def p_importdecl(p):
172    '''importdecl : filename import_options
173                  | filename
174                  | filename import_options COLON WORD EQ indices variable_options
175                  | filename COLON WORD EQ indices variable_options
176                  | filename import_options COLON indices variable_options
177                  | filename COLON indices variable_options
178                  | filename import_options COLON variable_options
179                  | filename COLON variable_options
180    '''
181    tmp = {'filename':p[1]}
182    if len(p) == 2:
183        p[0] = [tmp, (None,[]), {}]
184    elif len(p) == 3:
185        tmp.update(p[2])
186        p[0] = [tmp, (None,[]), {}]
187    elif len(p) == 4:
188        p[0] = [tmp, (None,[]), p[3]]
189    elif len(p) == 5:
190        if p[2] == ':':
191            p[0] = [tmp, (None,p[3]), p[4]]
192        else:
193            tmp.update(p[2])
194            p[0] = [tmp, (None,[]), p[4]]
195    elif len(p) == 6:
196        tmp.update(p[2])
197        p[0] = [tmp, (None,p[4]), p[5]]
198    elif len(p) == 7:
199        p[0] = [tmp, (p[3],p[5]), p[6]]
200    elif len(p) == 8:
201        tmp.update(p[2])
202        p[0] = [tmp, (p[4],p[6]), p[7]]
203    else:
204        raise IOError, "Unexpected condition"
205
206def p_import_options(p):
207    '''import_options : WORD EQ STRING import_options
208                      | WORD EQ STRING
209                      | WORD EQ QUOTEDSTRING import_options
210                      | WORD EQ QUOTEDSTRING
211                      | WORD EQ WORD import_options
212                      | WORD EQ WORD
213                      | WORD EQ PARAM import_options
214                      | WORD EQ PARAM
215                      | WORD EQ SET import_options
216                      | WORD EQ SET
217    '''
218    tmp = {p[1]:p[3]}
219    if len(p) == 4:
220        p[0] = tmp
221    else:
222        tmp.update(p[4])
223        p[0] = tmp
224
225def p_variable_options(p):
226    '''variable_options : variable variable_options
227                        | variable
228    '''
229    if len(p) == 2:
230        p[0] = p[1]
231    else:
232        p[1].update(p[2])
233        p[0] = p[1]
234
235def p_variable(p):
236    '''variable : WORD
237                | WORD EQ WORD
238    '''
239    if len(p) == 2:
240        p[0] = {p[1]:p[1]}
241    else:
242        p[0] = {p[3]:p[1]}
243
244def p_indices(p):
245    '''indices : LBRACKET WORD index_list RBRACKET
246               | LBRACKET WORD RBRACKET
247    '''
248    if len(p) == 5:
249        p[0] = [p[2]] + p[3]
250    else:
251        p[0] = [p[2]]
252
253def p_index_list(p):
254    '''index_list : COMMA WORD index_list
255                  | COMMA ASTERISK index_list
256                  | COMMA WORD
257                  | COMMA ASTERISK
258    '''
259    if len(p) == 4:
260        p[0] = [p[2]]+p[3]
261    else:
262        p[0] = [p[2]]
263
264def p_template(p):
265    '''template : LPAREN WORD index_list RPAREN
266                | LPAREN ASTERISK index_list RPAREN
267                | LPAREN WORD RPAREN
268                | LPAREN ASTERISK RPAREN
269    '''
270    if len(p) == 5:
271        p[0] = p[1]+",".join([p[2]]+p[3])+p[4]
272    else:
273        p[0] = p[1]+p[2]+p[3]
274
275def p_items(p):
276    '''items : item items
277             | item'''
278    if len(p) == 2:
279        p[0] = [p[1]]
280    else:
281        p[0] = [p[1]] + p[2]
282
283def p_item(p):
284    '''item : WORD
285            | WORDWITHINDEX
286            | NONWORD
287            | STRING
288            | QUOTEDSTRING
289            | COMMA
290            | COLON
291            | LBRACKET
292            | RBRACKET
293            | TR
294            | LPAREN
295            | RPAREN
296            | ASTERISK
297            | template
298    '''
299    p[0] = p[1]
300
301def p_filename(p):
302    '''filename : WORD
303                | STRING
304                | QUOTEDSTRING
305                | FILENAME
306                | WORD COLON FILENAME
307    '''
308    if len(p) == 2:
309        p[0] = p[1]
310    else:
311        p[0] = p[1]+p[2]+p[3]
312
313#
314# The function that performs the parsing
315#
316def parse_data_commands(data=None, filename=None, debug=0):
317    global debugging
318    #
319    # Always remove the parser.out file, which is generated to create debugging
320    #
321    if os.path.exists("parser.out"):        #pragma:nocover
322       os.remove("parser.out")
323    if debug > 0:                           #pragma:nocover
324        #
325        # Remove the parsetab.py* files.  These apparently need to be removed
326        # to ensure the creation of a parser.out file.
327        #
328        if os.path.exists("parsetab.py"):
329           os.remove("parsetab.py")
330        if os.path.exists("parsetab.pyc"):
331           os.remove("parsetab.pyc")
332        debugging=True
333    #
334    # Build lexer
335    #
336    lex.lex()
337    #
338    # Initialize parse object
339    #
340    global _parse_info
341    _parse_info = []
342    #
343    # Build yaccer
344    #
345    yacc.yacc(debug=debug, tabmodule=tabmodule, outputdir=outputdir)
346    #
347    # Parse the file
348    #
349    global _parsedata
350    if not data is None:
351        _parsedata=data
352        ply_init(_parsedata)
353        yacc.parse(data,debug=debug)
354    elif not filename is None:
355        f = open(filename)
356        data = f.read()
357        f.close()
358        _parsedata=data
359        ply_init(_parsedata)
360        yacc.parse(data, debug=debug)
361    else:
362        _parse_info = None
363    #
364    # Disable parsing I/O
365    #
366    debugging=False
367    return _parse_info
368
Note: See TracBrowser for help on using the repository browser.