#!/usr/bin/env python # # LiberMate # # Copyright (C) 2009 Eric C. Schug # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # __author__ = "Eric C. Schug (schugschug@gmail.com)" __version__ = "0.1" __copyright__ = "Copyright (c) 2009 Eric C. Schug" __license__ = "GNU General Public License" __revision__ = "$Id$" # Standard Python import sys import re from copy import copy import glob import os import stat import pprint import clips has_syck=False try: import syck has_syck=True class DumpNoTuple(syck.Dumper): def represent_tuple(self, object): return _syck.Seq(list(object), tag="tag:python.yaml.org,2002:seq") except ImportError: pass ### class "calcLexer extends Lexer" will generate python ### module "calcLexer" with class "Lexer". import MatlabLexer import MatlabParser import Mat2Py import translate_new import antlr import CommandLine import BaseRules def ASTtoTree(ast): 'Build' a=ast b=[] while a: c=ASTtoTree(a.getFirstChild()) node=BaseRules.ASTNode(a.getType(), a.getText(), c) b.append(node) a=a.getNextSibling() return b python_priority = { "": -4, "=": -3, ",": -1, ":": 0, "lambda": 0, "or": 1, "and": 2, "not": 3, ">": 6, "<": 6, "<=": 6, ">=": 6, "==": 6, "!=": 6, "|": 7, "^": 8, "&": 9, "+": 11, "-": 11, "*": 12, "/": 12, " +": 13, " -": 13, "~": 14, "**": 15, ".": 16, "x(":17, "NAME": 18, "VAR": 18, } # n = numel(A) returns the number of elements, n, in array A. class MatParse(MatlabParser.Parser): 'Higher level logic for parser' def __init__(self, *args, **kwargs): MatlabParser.Parser.__init__(self, *args, **kwargs) self.vars=set() self.funcs=set() self.is_dot=False self.inside_args=False def new_scope(self): 'Create a new function scope' self.vars=set() self.funcs=set() def get_scope(self): 'Get current scope' ast=self.astFactory.create(MatlabParser.SCOPE,", ".join(self.vars)+"\n # Function calls: "+", ".join(self.funcs)) print 'The following appear to be variables:' print ' ',", ".join(self.vars) print 'The following appear to be functions:' print ' ',", ".join(self.funcs) return ast def as_global(self,vartoken): 'add variable as a global' vartoken.setType(MatlabParser.VAR) self.vars.add(vartoken.getText()) def as_persistant(self,vartoken): 'add variable as a persistant' vartoken.setType(MatlabParser.VAR) self.vars.add(vartoken.getText()) def as_var(self,vartoken): 'NAME token is a variable' vartoken.setType(MatlabParser.VAR) self.vars.add(vartoken.getText()) def as_func(self,functoken): 'NAME token is a function' self.funcs.add(functoken.getText()) def var_lookup(self,vartoken): 'Lookup NAME token in scope and set type' #print("Checking var",vartoken.getText()) if(self.is_dot or (vartoken.getText() in self.vars)): vartoken.setType(MatlabParser.VAR) else: self.as_func(vartoken) def var_names(self): return list(self.vars) def print_tree(self,tree): pprint.pprint(ASTtoTree(tree)) sys.stdout.flush() numpy_names=['abs', 'absolute', 'add', 'add_docstring', 'add_newdoc', 'add_newdocs', 'alen', 'all', 'allclose', 'alltrue', 'alterdot', 'amax', 'amin', 'angle', 'any', 'append', 'apply_along_axis', 'apply_over_axes', 'arange', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2', 'arctanh', 'argmax', 'argmin', 'argsort', 'argwhere', 'around', 'array', 'array2string', 'array_equal', 'array_equiv', 'array_repr', 'array_split', 'array_str', 'asanyarray', 'asarray', 'asarray_chkfinite', 'ascontiguousarray', 'asfarray', 'asfortranarray', 'asmatrix', 'asscalar', 'atleast_1d', 'atleast_2d', 'atleast_3d', 'average', 'bartlett', 'base_repr', 'binary_repr', 'bincount', 'bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', 'blackman', 'bmat', 'bool', 'bool8', 'bool_', 'broadcast', 'byte', 'byte_bounds', 'c_', 'can_cast', 'cast', 'cdouble', 'ceil', 'cfloat', 'char', 'character', 'chararray', 'choose', 'clip', 'clongdouble', 'clongfloat', 'column_stack', 'common_type', 'compare_chararrays', 'complex', 'complex128', 'complex192', 'complex64', 'complex_', 'complexfloating', 'compress', 'concatenate', 'conj', 'conjugate', 'convolve', 'copy', 'core', 'corrcoef', 'correlate', 'cos', 'cosh', 'cov', 'cross', 'csingle', 'ctypeslib', 'cumprod', 'cumproduct', 'cumsum', 'delete', 'deprecate', 'diag', 'diagflat', 'diagonal', 'diff', 'digitize', 'disp', 'distutils', 'divide', 'dot', 'double', 'dsplit', 'dstack', 'dtype', 'e', 'ediff1d', 'emath', 'empty', 'empty_like', 'equal', 'errstate', 'exp', 'expand_dims', 'expm1', 'extract', 'eye', 'fabs', 'fastCopyAndTranspose', 'fft', 'finfo', 'fix', 'flatiter', 'flatnonzero', 'flexible', 'fliplr', 'flipud', 'float', 'float32', 'float64', 'float96', 'float_', 'floating', 'floor', 'floor_divide', 'fmod', 'format_parser', 'frexp', 'frombuffer', 'fromfile', 'fromfunction', 'fromiter', 'frompyfunc', 'fromstring', 'generic', 'get_array_wrap', 'get_include', 'get_numarray_include', 'get_numpy_include', 'get_printoptions', 'getbuffer', 'getbufsize', 'geterr', 'geterrcall', 'geterrobj', 'gradient', 'greater', 'greater_equal', 'hamming', 'hanning', 'histogram', 'histogram2d', 'histogramdd', 'hsplit', 'hstack', 'hypot', 'i0', 'identity', 'iinfo', 'imag', 'index_exp', 'indices', 'inexact', 'inf', 'info', 'infty', 'inner', 'insert', 'int', 'int0', 'int16', 'int32', 'int64', 'int8', 'int_', 'int_asbuffer', 'intc', 'integer', 'interp', 'intersect1d', 'intersect1d_nu', 'intp', 'invert', 'iscomplex', 'iscomplexobj', 'isfinite', 'isfortran', 'isinf', 'isnan', 'isneginf', 'isposinf', 'isreal', 'isrealobj', 'isscalar', 'issctype', 'issubclass_', 'issubdtype', 'issubsctype', 'iterable', 'ix_', 'kaiser', 'kron', 'ldexp', 'left_shift', 'less', 'less_equal', 'lexsort', 'lib', 'linalg', 'linspace', 'little_endian', 'load', 'loads', 'loadtxt', 'log', 'log10', 'log1p', 'log2', 'logical_and', 'logical_not', 'logical_or', 'logical_xor', 'logspace', 'long', 'longcomplex', 'longdouble', 'longfloat', 'longlong', 'ma', 'mat', 'math', 'matrix', 'max', 'maximum', 'maximum_sctype', 'may_share_memory', 'mean', 'median', 'memmap', 'meshgrid', 'mgrid', 'min', 'minimum', 'mintypecode', 'mod', 'modf', 'msort', 'multiply', 'nan', 'nan_to_num', 'nanargmax', 'nanargmin', 'nanmax', 'nanmin', 'nansum', 'nbytes', 'ndarray', 'ndenumerate', 'ndim', 'ndindex', 'negative', 'newaxis', 'newbuffer', 'nonzero', 'not_equal', 'number', 'obj2sctype', 'object', 'object0', 'object_', 'ogrid', 'oldnumeric', 'ones', 'ones_like', 'outer', 'pi', 'piecewise', 'pkgload', 'place', 'poly', 'poly1d', 'polyadd', 'polyder', 'polydiv', 'polyfit', 'polyint', 'polymul', 'polysub', 'polyval', 'power', 'prod', 'product', 'ptp', 'put', 'putmask', 'r_', 'random', 'rank', 'ravel', 'real', 'real_if_close', 'rec', 'recarray', 'reciprocal', 'record', 'remainder', 'repeat', 'require', 'reshape', 'resize', 'restoredot', 'right_shift', 'rint', 'roll', 'rollaxis', 'roots', 'rot90', 'round', 'round_', 'row_stack', 's_', 'savetxt', 'sctype2char', 'sctypeDict', 'sctypeNA', 'sctypes', 'searchsorted', 'select', 'set_numeric_ops', 'set_printoptions', 'set_string_function', 'setbufsize', 'setdiff1d', 'seterr', 'seterrcall', 'seterrobj', 'setmember1d', 'setxor1d', 'shape', 'short', 'show_config', 'sign', 'signbit', 'signedinteger', 'sin', 'sinc', 'single', 'singlecomplex', 'sinh', 'size', 'sometrue', 'sort', 'sort_complex', 'source', 'split', 'sqrt', 'square', 'squeeze', 'std', 'str', 'str_', 'string0', 'string_', 'subtract', 'sum', 'swapaxes', 'take', 'tan', 'tanh', 'tensordot', 'test', 'testing', 'tile', 'trace', 'transpose', 'trapz', 'tri', 'tril', 'trim_zeros', 'triu', 'true_divide', 'typeDict', 'typeNA', 'typecodes', 'typename', 'ubyte', 'ufunc', 'uint', 'uint0', 'uint16', 'uint32', 'uint64', 'uint8', 'uintc', 'uintp', 'ulonglong', 'unicode', 'unicode0', 'unicode_', 'union1d', 'unique', 'unique1d', 'unravel_index', 'unsignedinteger', 'unwrap', 'ushort', 'vander', 'var', 'vdot', 'vectorize', 'version', 'void', 'void0', 'vsplit', 'vstack', 'where', 'who', 'zeros', 'zeros_like'] pylab_names=['absolute', 'acorr', 'add', 'add_docstring', 'add_newdoc', 'add_newdocs', 'alen', 'all', 'allclose', 'alltrue', 'alterdot', 'amap', 'amax', 'amin', 'angle', 'annotate', 'any', 'append', 'apply_along_axis', 'apply_over_axes', 'approx_real', 'arange', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2', 'arctanh', 'argmax', 'argmin', 'argsort', 'argwhere', 'around', 'array', 'array2string', 'array_equal', 'array_equiv', 'array_repr', 'array_split', 'array_str', 'arrow', 'asanyarray', 'asarray', 'asarray_chkfinite', 'ascontiguousarray', 'asfarray', 'asfortranarray', 'asmatrix', 'asscalar', 'atleast_1d', 'atleast_2d', 'atleast_3d', 'autumn', 'average', 'axes', 'axhline', 'axhspan', 'axis', 'axvline', 'axvspan', 'bar', 'barh', 'bartlett', 'base_repr', 'beta', 'binary_repr', 'bincount', 'binomial', 'bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', 'bivariate_normal', 'blackman', 'bmat', 'bone', 'bool8', 'bool_', 'box', 'boxplot', 'broadcast', 'broken_barh', 'byte', 'byte_bounds', 'bytes', 'c_', 'can_cast', 'cast', 'cdouble', 'ceil', 'center_matrix', 'cfloat', 'char', 'character', 'chararray', 'chisquare', 'cholesky', 'choose', 'cla', 'clabel', 'clf', 'clim', 'clip', 'clongdouble', 'clongfloat', 'close', 'cm', 'cohere', 'colorbar', 'colorbar_doc', 'colormaps', 'colors', 'column_stack', 'common_type', 'compare_chararrays', 'complex128', 'complex192', 'complex64', 'complex_', 'complexfloating', 'compress', 'concatenate', 'conj', 'conjugate', 'connect', 'contour', 'contourf', 'conv', 'convolve', 'cool', 'copper', 'copy', 'corrcoef', 'correlate', 'cos', 'cosh', 'cov', 'cross', 'csd', 'csingle', 'csv2rec', 'ctypeslib', 'cumprod', 'cumproduct', 'cumsum', 'date2num', 'datestr2num', 'dedent', 'delaxes', 'delete', 'demean', 'deprecate', 'det', 'detrend', 'detrend_linear', 'detrend_mean', 'detrend_none', 'diag', 'diagflat', 'diagonal', 'diagonal_matrix', 'diff', 'digitize', 'disconnect', 'disp', 'dist', 'dist_point_to_segment', 'divide', 'dot', 'double', 'drange', 'draw', 'draw_if_interactive', 'dsplit', 'dstack', 'dtype', 'e', 'ediff1d', 'eig', 'eigh', 'eigvals', 'eigvalsh', 'emath', 'empty', 'empty_like', 'entropy', 'enumerate', 'epoch2num', 'equal', 'errorbar', 'errstate', 'exception_to_str', 'exp', 'exp_safe', 'expand_dims', 'expm1', 'exponential', 'extract', 'eye', 'f', 'fabs', 'fastCopyAndTranspose', 'fft', 'fft2', 'fftfreq', 'fftn', 'fftpack', 'fftpack_lite', 'fftshift', 'fftsurr', 'figaspect', 'figimage', 'figlegend', 'figtext', 'figure', 'fill', 'find', 'finfo', 'fix', 'flag', 'flatiter', 'flatnonzero', 'flatten', 'flexible', 'fliplr', 'flipud', 'float32', 'float64', 'float96', 'float_', 'floating', 'floor', 'floor_divide', 'fmod', 'format_parser', 'frange', 'frexp', 'frombuffer', 'fromfile', 'fromfunction', 'fromfunction_kw', 'fromiter', 'frompyfunc', 'fromstring', 'gamma', 'gca', 'gcf', 'gci', 'generic', 'geometric', 'get', 'get_array_wrap', 'get_backend', 'get_cmap', 'get_current_fig_manager', 'get_include', 'get_numarray_include', 'get_numpy_include', 'get_plot_commands', 'get_printoptions', 'get_sparse_matrix', 'get_state', 'get_xyz_where', 'getbuffer', 'getbufsize', 'geterr', 'geterrcall', 'geterrobj', 'getp', 'gradient', 'gray', 'greater', 'greater_equal', 'grid', 'gumbel', 'hamming', 'hanning', 'helper', 'hfft', 'hist', 'histogram', 'histogram2d', 'histogramdd', 'hlines', 'hold', 'hot', 'hsplit', 'hstack', 'hsv', 'hypergeometric', 'hypot', 'i0', 'identity', 'ifft', 'ifft2', 'ifftn', 'ifftshift', 'ihfft', 'iinfo', 'imag', 'imread', 'imshow', 'index_exp', 'indices', 'inexact', 'inf', 'info', 'infty', 'inner', 'insert', 'inside_poly', 'int0', 'int16', 'int32', 'int64', 'int8', 'int_', 'int_asbuffer', 'intc', 'integer', 'interp', 'intersect1d', 'intersect1d_nu', 'intp', 'inv', 'invert', 'ioff', 'ion', 'irefft', 'irefft2', 'irefftn', 'irfft', 'irfft2', 'irfftn', 'is_numlike', 'is_string_like', 'iscomplex', 'iscomplexobj', 'isfinite', 'isfortran', 'ishold', 'isinf', 'isinteractive', 'isnan', 'isneginf', 'isposinf', 'ispower2', 'isreal', 'isrealobj', 'isscalar', 'issctype', 'issubclass_', 'issubdtype', 'issubsctype', 'iterable', 'ix_', 'jet', 'kaiser', 'kron', 'l1norm', 'l2norm', 'lapack_lite', 'laplace', 'ldexp', 'left_shift', 'legend', 'less', 'less_equal', 'levypdf', 'lexsort', 'liaupunov', 'linalg', 'linspace', 'little_endian', 'load', 'loads', 'loadtxt', 'log', 'log10', 'log1p', 'log2', 'logical_and', 'logical_not', 'logical_or', 'logical_xor', 'logistic', 'loglog', 'lognormal', 'logseries', 'logspace', 'longcomplex', 'longdouble', 'longest_contiguous_ones', 'longest_ones', 'longfloat', 'longlong', 'lstsq', 'ma', 'mat', 'math', 'matplotlib', 'matrix', 'matshow', 'maximum', 'maximum_sctype', 'may_share_memory', 'mean', 'mean_flat', 'median', 'memmap', 'meshgrid', 'mfuncC', 'mgrid', 'minimum', 'mintypecode', 'mlab', 'mod', 'modf', 'movavg', 'mpl', 'msort', 'multinomial', 'multiply', 'multivariate_normal', 'mx2num', 'nan', 'nan_to_num', 'nanargmax', 'nanargmin', 'nanmax', 'nanmin', 'nansum', 'nbytes', 'ndarray', 'ndenumerate', 'ndim', 'ndindex', 'negative', 'negative_binomial', 'new_figure_manager', 'newaxis', 'newbuffer', 'noncentral_chisquare', 'noncentral_f', 'nonzero', 'norm', 'norm_flat', 'normal', 'normalize', 'normpdf', 'not_equal', 'npy', 'num2date', 'num2epoch', 'number', 'obj2sctype', 'object0', 'object_', 'ogrid', 'ones', 'ones_like', 'orth', 'outer', 'over', 'pareto', 'pcolor', 'pcolormesh', 'permutation', 'pi', 'pie', 'piecewise', 'pink', 'pinv', 'pkgload', 'place', 'plot', 'plot_date', 'plotfile', 'plotting', 'poisson', 'polar', 'poly', 'poly1d', 'poly_below', 'poly_between', 'polyadd', 'polyder', 'polydiv', 'polyfit', 'polyint', 'polymul', 'polysub', 'polyval', 'popd', 'power', 'prctile', 'prctile_rank', 'prepca', 'prism', 'prod', 'product', 'psd', 'ptp', 'put', 'putmask', 'pylab_setup', 'qr', 'quiver', 'quiverkey', 'r_', 'rand', 'randint', 'randn', 'random', 'random_integers', 'random_sample', 'ranf', 'rank', 'ravel', 'rayleigh', 'rc', 'rcParams', 'rcParamsDefault', 'rcdefaults', 'real', 'real_if_close', 'rec', 'rec2csv', 'rec_append_field', 'rec_drop_fields', 'rec_join', 'recarray', 'reciprocal', 'record', 'refft', 'refft2', 'refftn', 'relativedelta', 'rem', 'remainder', 'repeat', 'require', 'reshape', 'resize', 'restoredot', 'rfft', 'rfft2', 'rfftn', 'rgrids', 'right_shift', 'rint', 'rk4', 'rms_flat', 'roll', 'rollaxis', 'roots', 'rot90', 'round_', 'row_stack', 'rrule', 's_', 'sample', 'save', 'savefig', 'savetxt', 'scatter', 'sci', 'sctype2char', 'sctypeDict', 'sctypeNA', 'sctypes', 'searchsorted', 'seed', 'segments_intersect', 'select', 'semilogx', 'semilogy', 'set_numeric_ops', 'set_printoptions', 'set_state', 'set_string_function', 'setbufsize', 'setdiff1d', 'seterr', 'seterrcall', 'seterrobj', 'setmember1d', 'setp', 'setxor1d', 'shape', 'short', 'show', 'show_config', 'shuffle', 'sign', 'signbit', 'signedinteger', 'silent_list', 'sin', 'sinc', 'single', 'singlecomplex', 'sinh', 'size', 'slopes', 'solve', 'sometrue', 'sort', 'sort_complex', 'source', 'specgram', 'spectral', 'split', 'spring', 'spy', 'sqrt', 'sqrtm', 'square', 'squeeze', 'standard_cauchy', 'standard_exponential', 'standard_gamma', 'standard_normal', 'standard_t', 'std', 'stem', 'step', 'stineman_interp', 'str_', 'string0', 'string_', 'strpdate2num', 'subplot', 'subplot_tool', 'subplots_adjust', 'subtract', 'sum', 'sum_flat', 'summer', 'svd', 'swapaxes', 'switch_backend', 'sys', 'table', 'take', 'tan', 'tanh', 'tensordot', 'tensorinv', 'tensorsolve', 'test', 'text', 'thetagrids', 'tile', 'title', 'trace', 'transpose', 'trapz', 'tri', 'triangular', 'tril', 'trim_zeros', 'triu', 'true_divide', 'twinx', 'twiny', 'typeDict', 'typeNA', 'typecodes', 'typename', 'ubyte', 'ufunc', 'uint', 'uint0', 'uint16', 'uint32', 'uint64', 'uint8', 'uintc', 'uintp', 'ulonglong', 'unicode0', 'unicode_', 'uniform', 'union1d', 'unique', 'unique1d', 'unravel_index', 'unsignedinteger', 'unwrap', 'ushort', 'vander', 'var', 'vdot', 'vectorize', 'vlines', 'void', 'void0', 'vonmises', 'vsplit', 'vstack', 'wald', 'warnings', 'weibull', 'where', 'who', 'window_hanning', 'window_none', 'winter', 'xcorr', 'xlabel', 'xlim', 'xticks', 'ylabel', 'ylim', 'yticks', 'zeros', 'zeros_like', 'zipf'] import keyword class Mat2PyTrans(translate_new.Mat2Py): 'Higher level logic for translator' def __init__(self): #Mat2Py.Walker.__init__(self) translate_new.Mat2Py.__init__(self) self.nl="\n" self.indcnt=0 self.indent="" self.in_var=False self.is_simple_rhs=False self.is_lhs=False self.token_stack=[] # Define simple mapping of functions self.mapping={'size':'matcompat.size', 'ndims':'matcompat.ndim', 'eps':'finfo(float).eps', 'i':'1j', 'find':'nonzero', 'rand':'np.random.rand', 'meshgrid':'matcompat.meshgrid', 'repmat':'matcompat.repmat', 'max':'matcompat.max', 'min':'matcompat.max', 'error':'matcompat.error', 'warning':'matcompat.warning', 'norm':'linalg.norm', 'bitand':'&Error', 'bitor':'|Error', 'inv':'linalg.inv', 'pinv':'linalg.pinv', 'chol':'linalg.cholesky', 'eig':'linalg.eig', 'qr':'scipy.linalg.qr', 'lu':'scipy.linalg.lu', 'conjgrad':'scipy.linalg.cg', 'regress':'linalg.lstsqError', 'decimate':'matcompat.decimate', 'assert':'matcompat.assert', } def incr(self): 'increment indent' self.indcnt+=1 self.indent=" "*(self.indcnt*4) self.nl="\n"+self.indent #print 'increment "'+self.indent+'"' def decr(self): 'decrement indent' self.indcnt-=1 self.indent=" "*(self.indcnt*4) self.nl="\n"+self.indent #print 'decrement "'+self.indent+'"' def Lookup(self, name): 'Do simple function mapping' if(name in self.mapping): return self.mapping[name] if(name in numpy_names): return 'np.'+name if(name in pylab_names): return 'plt.'+name if(keyword.iskeyword(name)): if(name!='assert'): name=name+'_rename' return name def bop(self, op, ptoken, a, b, add_padding=False): 'binary operator' if(add_padding): pad=' ' else: pad='' if(not a): a='Error' if(not b): b='Error' k=a+pad+op.strip()+pad+b #print 'bop "%s"[%d] <- "%s"[%d] %s %s' % ( ptoken, python_priority[ptoken], op, python_priority[op], a, b) if(python_priority[ptoken]>python_priority[op]): #print '('+k+')' return '('+k+')' else: return k def preop(self, op, ptoken, a, add_padding=False): 'Prefix operator' if(add_padding): pad=' ' else: pad='' if(not a): a='Error' k=op.strip()+pad+a #print 'preop "%s"[%d] <- "%s"[%d] %s' % ( ptoken, python_priority[ptoken], op, python_priority[op], a) if(python_priority[ptoken]>python_priority[op]): #print '('+k+')' return '('+k+')' else: return k def multiop(self, op, ptoken, c, add_padding=False): 'multiple operator' if(add_padding): pad=' ' else: pad='' k=(pad+op.strip()+pad).join(c) if(python_priority[ptoken]>python_priority[op]): return '('+k+')' else: return k def colonop(self, ptoken, cc): 'colon operator' a=cc[0] b=cc[1] if(len(cc)>2): c=cc[2] else: c=None if( self.in_var): if(not a and not b): sstr=":" else: if(a.replace('.','').isdigit()): a=str(int(float(a))-1) else: a="int("+a+")-1" if(c): if(c=='xend'): c='' sstr=a+":"+c+":"+b else: if(b=='xend'): b='' sstr=a+":"+b else: if(not a and not b): sstr="Error:Error" else: if(c): if(c.replace('.','').isdigit() and b.replace('.','').isdigit()): c=str(float(c)+float(b)) else: c="("+c+")+("+b+")" sstr="np.arange("+a+", "+c+", "+b+")" else: if(b.replace('.','').isdigit()): b=str(float(b)+1) else: b="("+b+")+1" sstr="np.arange("+a+", "+b+")" return sstr def join_args(self, cc, braces=False, ptoken=None): def mapper(ii): if(":" in ii): return ii elif(ii.isdigit()): return str(int(ii)-1) else: return 'int('+ii+')-1' if(self.in_var or self.is_lhs or ptoken=="VAR"): if(braces): sstr=".cell[" else: sstr="[" cc=[mapper(ii) for ii in cc] k=",".join(cc) if(k==':' and not self.is_lhs and not braces): return '.flatten(1)' else: sstr+=k if(braces): sstr+="]" else: sstr+="]" else: if(braces): sstr=".cell_getattr("+", ".join(cc)+")" else: sstr="("+", ".join(cc)+")" return sstr default_header=""" import numpy as np import scipy import matcompat # if available import pylab (from matlibplot) try: import matplotlib.pylab as plt except ImportError: pass """ class MainApp(CommandLine.App): usage_str='[options] [matfile]...' about_str='Translates MATLAB file(s) matfile (.m) to Python files (.py)' def __init__(self): # Specify configuration options build an array of options defined as # [Name, shortkey, description, type, default] #type can be 'str','dir','file','bool','num', or a list of strings (enumeration) self.config_options=[ ['help','h','display help and quit','bool',False], ['astdump','','dump Abstract Syntax Tree to file, .ast','bool',False], ['headerfile','','load header from ARG','file', None], #TODO ['output','o','log output to file ARG','file','libermate.log'], #TODO ['quite','','run silently hush all but prompts','bool',False], ] args=self.command_line() self.files=[] for ifile in args: #files=glob.glob(ifile) files=[ifile] self.files.extend(files) for filename in self.files: try: stat_info=os.stat(filename) except OSError, desc: print 'Error: could not open file %s' % filename sys.exit(2) if(stat.S_ISDIR(stat_info[stat.ST_MODE])): print 'Error: %s is a directory but should be a file' % filename sys.exit(2) if filename.replace('.m','.py') == filename: print "Error: file %s must have a .m suffix" % filename sys.exit(2) #print self.files self.main() def main(self): if(self.headerfile): f=open(self.headerfile) header=''.join(f.readlines()) f.close() else: header=default_header for filename in self.files: print '\n'+'-'*20 print 'Opening File', filename f = file(filename, "r") lexer = MatlabLexer.Lexer(f) ### create a lexer for calculator print 'Starting Parser' p = MatParse(lexer) p.script() print 'Parser Complete' a = p.getAST() root = ASTtoTree(a) rules=BaseRules.BaseRules() for node in root: node.assert_all() #clips.PrintAgenda() #clips.SaveFacts(filename.replace('.m','.facts')) rules.run() #clips.SaveFacts(filename.replace('.m','.facts2')) if(self.astdump): outfile = filename.replace('.m', '.ast') print 'writing to file', outfile f = open(outfile, 'w') astlist=[node.to_list() for node in root] if(has_syck and False): f.write(syck.dump(astlist, Dumper=DumpNoTuple)) else: f.write(pprint.pformat(astlist)) f.close() if(0): outfile = filename.replace('.m', '.nast') print 'writing to file', outfile f=open(outfile, 'w') if(has_syck and False): f.write(syck.dump(root, Dumper=DumpNoTuple)) else: f.write(pprint.pformat(root)) walk = Mat2PyTrans() print "Starting Translator" s=walk.translate(root) #Simple conversions s=re.sub(r'pi\(\)','pi',s) s=re.sub(r'Inf\(\)','inf',s) s=re.sub(r'nan\(\)','nan',s) s=re.sub(r'int\(([\d]+)\.\)',r'\1',s) def sub_eval(m): return str(eval(m.group(1))) s=re.sub(r"np.random.rand\('state',","random.set_state(",s) #s=re.sub(r"random.rand\(\),","random.set_state(",s) s=re.sub(r'([\d]+\.?-1)',sub_eval,s) #s=re.sub(r'matdiv\((.+?),\ (\d+.)\)',r'(\1)/\2',s) #s=re.sub(r'matdiv\((\d+.),\ ',r'\1/(',s) #s=re.sub(r'np.dot\((.+?),\ (\d+.)\)',r'(\1)*\2',s) #s=re.sub(r'np.dot\((\d+.),\ ',r'\1*(',s) s=re.sub(r'shape\.Error\(([\w\.]+),\ ([\w\.]+)\)',r'\1.shape[\2-1]',s) s=re.sub(r'shape\.Error\((\w+)\)',r'\1.shape',s) s=re.sub(r'\.flatten\(1\)\.conj\(\)\.T',r'.flatten(0).conj()',s) s=re.sub(r'\.flatten\(1\)\.T',r'.flatten(0)',s) s=re.sub(r'\.flatten\(1\)\.T',r'.flatten(0)',s) s=re.sub(r'xend',r'0',s) print 'Translation Complete' #print p.var_names() outfile=filename.replace('.m', '.py') print 'writing to file', outfile f=open(outfile,'w') f.write( header ) f.write(s) f.close() def testLexer(files): 'do quick scan of selected files' #files=glob.glob('/home/eric/Downloads/mpi-ikl-simplemkl-1.0/*.m') quick_scan(files) def testLexer(filename): 'test parsing of specified file' f = file(filename, "r") lexer = MatlabLexer.Lexer(f) ### create a lexer for calculator pcount=0 for token in lexer: ## do something with token print token.getText(), if token.getType() in [MatlabParser.END,MatlabParser.ARRAY_END,MatlabParser.STRING,MatlabParser.TRANS]: print "\\"+str(pcount)+MatlabParser._tokenNames[token.getType()]+'/', if(token.getType() in [MatlabParser.LPAREN,MatlabParser.LBRACE,MatlabParser.ATPAREN]): pcount+=1 print '\\'+str(pcount)+'/', if(token.getType() in [MatlabParser.RPAREN,MatlabParser.RBRACE]): pcount-=1 print '\\'+str(pcount)+'/', def testParser(files): 'Test parsing of specified files' for filename in files: f = file(filename, "r") lexer = MatlabLexer.Lexer(f) ### create a lexer for calculator p = MatParse(lexer) p.script() a=p.getAST() b=ASTtoTree(a) def main(): app=MainApp() if __name__ == "__main__": main()