Changeset 2278


Ignore:
Timestamp:
Feb 7, 2010 3:06:10 PM (10 years ago)
Author:
wehart
Message:

A major rework of the parsing of data command files (formerly known
as AMPL DAT files). This rework is the first step towards a full
parse of these files. I've used PLY to lex/yacc these files. This should
resolve a variety of issues that we've observed relating to the sensitivity of
the old parser to whitespace. This is also a first step towards a careful parse
of command lines for the 'import' command.

Location:
coopr.pyomo/trunk/coopr/pyomo
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • coopr.pyomo/trunk/coopr/pyomo/data/__init__.py

    r2227 r2278  
    1212import text
    1313import sheet
     14import parse_datacmds
    1415#import db
  • coopr.pyomo/trunk/coopr/pyomo/data/process_data.py

    r2274 r2278  
    1212import copy
    1313import math
    14 from pyutilib.misc import quote_split
     14from parse_datacmds import parse_data_commands
     15from pyutilib.misc import quote_split, Options
    1516from coopr.pyomo.base.plugin import *
    1617from coopr.pyomo.base import pyomo
     18from coopr.pyomo.base.plugin import *
    1719
    1820global Lineno
     
    101103        if len(cmd) == 0:
    102104           return []
    103         sd = getattr(_model,sname)
     105        try:
     106            sd = getattr(_model,sname)
     107        except AttributeError:
     108            raise IOError, "Cannot process data for set '%s' because it is not defined in model '%s'" % (sname, _model.name)
    104109        #d = sd.dimen
    105110        cmd = _data_eval(cmd)
     
    386391    global Lineno
    387392    Lineno = 0
     393
     394    try:
     395        cmds = parse_data_commands(filename=cmd[1])
     396    except IOError, err:
     397        raise IOError, "Error parsing file '%s': %s" % (Filename, str(err))
     398    for cmd in cmds:
     399        _process_data(cmd, _model, _data, _default, Filename, Lineno)
     400    return True
     401
     402
     403def X_process_include(cmd, _model, _data, _default):
     404    if len(cmd) == 1:
     405        raise IOError, "Cannot execute 'include' command without a filename"
     406    if len(cmd) > 2:
     407        raise IOError, "The 'include' command only accepts a single filename"
     408
     409    global Filename
     410    Filename = cmd[1]
     411    global Lineno
     412    Lineno = 0
    388413    cmd=""
    389414    status=True
     
    416441
    417442
     443def _process_import(cmd, _model, _data, _default):
     444    #print "IMPROT",cmd
     445    if len(cmd) < 2:
     446        raise IOError, "The 'import' command must specify a filename"
     447
     448    global Filename
     449    Filename = cmd[1]
     450    global Lineno
     451    Lineno = 0
     452
     453    options = Options()
     454    options.file = cmd[1]
     455    cndx = 2
     456    while cndx < len(cmd) and cmd[cndx] != ':':
     457        cndx += 1
     458    #
     459    # Parse options
     460    #
     461    ndx = 2
     462    while ndx < cndx:
     463        if cmd[ndx] == 'range':
     464            if cndx == ndx+1:
     465                raise ValueError, "No argument for 'range' option"
     466            options.range = cmd[ndx+1]
     467            ndx += 2
     468        elif cmd[ndx] == 'format':   
     469            if cndx == ndx+1:
     470                raise ValueError, "No argument for 'format' option"
     471            options.format = cmd[ndx+1]
     472            ndx += 2
     473        elif cmd[ndx] == 'using':   
     474            if cndx == ndx+1:
     475                raise ValueError, "No argument for 'using' option"
     476            options.using = cmd[ndx+1]
     477            ndx += 2
     478        elif cmd[ndx] == 'query':   
     479            if cndx == ndx+1:
     480                raise ValueError, "No argument for 'query' option"
     481            options.query = cmd[ndx+1]
     482            ndx += 2
     483        else:
     484            raise ValueError, "Unknown option '%s'" % cmd[ndx]
     485    #
     486    # TODO: process mapping info
     487    #
     488    tmp = options.file.split(".")[-1]
     489    data = DataManagerFactory(tmp)
     490    data.initialize(options.file)
     491    data.open()
     492    data.read()
     493    data.close()
     494    data.process(_model, _data, _default)
     495       
     496   
     497
     498
    418499def _process_data(cmd, _model, _data, _default, Filename_, Lineno_=0):
    419500        """
     
    421502        subroutines to process different types of data
    422503        """
     504        #print "CMD",cmd
    423505        global Lineno
    424506        global Filename
     
    443525        elif cmd[0] == 'include':
    444526           _process_include(cmd, _model, _data, _default)
     527        elif cmd[0] == 'import':
     528           _process_import(cmd, _model, _data, _default)
    445529        else:
    446530           raise IOError, "ERROR: Unknown data command: "+" ".join(cmd)
  • coopr.pyomo/trunk/coopr/pyomo/tests/unit/test_modeldata.py

    r2274 r2278  
    1313
    1414currdir=dirname(abspath(__file__))+os.sep
    15 example_dir=coopr_dir+os.sep+"example"+os.sep+"pyomo"+os.sep+"tutorials"+os.sep+"tab"+os.sep
     15example_dir=coopr_dir+os.sep+".."+os.sep+"examples"+os.sep+"pyomo"+os.sep+"tutorials"+os.sep+"tab"+os.sep
    1616
    1717try:
     
    284284
    285285
     286class TestImport(unittest.TestCase):
     287
     288    def test_tableA(self):
     289        pyutilib.misc.setup_redirect(currdir+'importA.dat')
     290        print "import "+os.path.abspath(example_dir+'A.tab')+" ;"
     291        pyutilib.misc.reset_redirect()
     292        model=Model()
     293        model.A = Set()
     294        instance = model.create(currdir+'importA.dat')
     295        self.failUnlessEqual(instance.A.data(), set(['A1', 'A2', 'A3']))
     296        os.remove(currdir+'importA.dat')
     297
     298
    286299if __name__ == "__main__":
    287300   unittest.main()
Note: See TracChangeset for help on using the changeset viewer.