def parsetree(): return parse( simpleLanguage(), files, True, comment, lineCount = True, )
def parse(file_path): """Parse the given message file and produce a MessageFile. Arg: file_path: Source file path. Returns: A MessageFile instance with the contents of the file. """ ast = pyPEG.parse(language=file_root, lineSource=fileinput.FileInput(file_path), skipWS=True, skipComments=comment, packrat=False, lineCount=True) return MessageFile(ast)
def parseDefs(self, path): """ Parse de definitions from a file at path using pyPEG and the grammar defined above. @ input path: the path to the file to parse @ return: de pyAST with the definitions """ _f = fileinput.input(path) self.ast = pyPEG.parse( GRAMMAR, fileinput.input(path), True, COMMENT, packrat = False) for x in self.ast: try: _d = self.defs[x.what[0]] raise Error( "Define double definition: <" + x.what[0] + "> at line <" + str(x.__name__.line) + ">.") except KeyError: self.defs[x.what[0]] = x.what[1]
def parse(filePath = None): """ Use PyPEG to parse de file into a PyPEG structure. Use this structure to fill up our specific structures which are easier to work with. Returns a 'Model' instance with the parsed model. @input filePath: the path of the file to be parsed. """ if filePath == None or not os.path.isfile(filePath): raise Error( "Path <"+ str(filePath) +"> is not a valid file to "\ + "parse :S.") try: _f = open(filePath, 'a') _f.write("//Line to avoid problems with pyPEG line count.") _f.close() # packrat = True seems to be brocken :S TODO check if it is LDEBUG("Parsing with pyPEG...") _ast = pyPEG.parse(GRAMMAR, fileinput.input(filePath), False, COMMENT, packrat = False) except Exception, _e: raise Error(str(_e))
if __name__ == "__main__": _file = fileinput.input() # logging.basicConfig(filename='logfile.log', level=logging.DEBUG) # Logging levels: # CRITICAL 50 # ERROR 40 # WARNING 30 # INFO 20 # DEBUG 10 # NOTSET 0 logging.basicConfig( level=logging.DEBUG , format = '[ %(levelname)s ] ' \ + '[%(filename)s] %(message)s') LINFO("Parsing ...") _ast = parse(GRAMMAR, _file, False, packrat = False) LINFO("Parsed <%s>."%_file.filename()) logging.log(logging.INSPECT, str(_ast)) try: LINFO("Precompiling <%s> ..."%_file.filename()) precompile(_ast, _file.filename()+".precompiled") LINFO("Precompiled into <%s>."%(_file.filename()+".precompiled")) except Critical: LEXCEPTION(":S something very bad happened.") except Error,e: LERROR(str(e))
return re.compile(r'\d+') def id(): return re.compile(r"\w+") def optional(): return "OPTIONAL" def member(): return id, id, 0, optional def structureMembers(): return member, -1, (",", member) def sequence(): return "SEQUENCE", "{", structureMembers, "}" def choice(): return "CHOICE", "{", structureMembers, "}" files = fileinput.input() result = parse(typeDefinition(), files, True, comment) print result
import re, fileinput from pyPEG import parse from pyPEG import keyword, _and, _not, ignore def comment(): return [re.compile(r"--.*--"), re.compile(r"--.*")] def typeDefinition(): return id, "::=", [ sequence, choice, terminal ] def terminal(): return integerType def integerType(): return "INTEGER", 0, ( "(", literal, ".." , literal, ")" ) def literal(): return re.compile(r'\d+') def id(): return re.compile(r"\w+") def optional(): return "OPTIONAL" def member(): return id, id, 0, optional def structureMembers(): return member, -1, ( ",", member) def sequence(): return "SEQUENCE", "{", structureMembers, "}" def choice(): return "CHOICE", "{", structureMembers, "}" files = fileinput.input() result = parse(typeDefinition(), files, True, comment) print result
# tuple: production sequence # integer: count in production sequence: # 0: following element is optional # -1: following element can be omitted or repeated endless # -2: following element is required and can be repeated endless # list: options, choose one of them # _not: next element in production sequence is matched only if this would not # _and: next element in production sequence is matched only if this would, too def comment(): return [re.compile(r"//.*"), re.compile("/\*.*?\*/", re.S)] def literal(): return re.compile(r'\d*\.\d*|\d+|".*?"') def symbol(): return re.compile(r"\w+") def operator(): return re.compile(r"\+|\-|\*|\/|\=\=") def operation(): return symbol, operator, [literal, functioncall] def expression(): return [literal, operation, functioncall] def expressionlist(): return expression, -1, (",", expression) def returnstatement(): return keyword("return"), expression def ifstatement(): return keyword("if"), "(", expression, ")", block, keyword("else"), block def statement(): return [ifstatement, returnstatement], ";" def block(): return "{", -2, statement, "}" def parameterlist(): return "(", symbol, -1, (",", symbol), ")" def functioncall(): return symbol, "(", expressionlist, ")" def function(): return keyword("function"), symbol, parameterlist, block def simpleLanguage(): return function result = parse(simpleLanguage(), fileinput.input(), True, comment) print result print 'done' raw_input()
def sanitize_one(inlists, pkgname): finput = fileinput.FileInput([inlists]) ast = parse(cmake(), finput, True) oslist = '' oslist += 'if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/package.cmake)\n include(${CMAKE_CURRENT_BINARY_DIR}/package.cmake)\nendif()\n' for line in ast: if line[0] == 'macrocall': if line[1][0].lower() in ['cmake_minimum_required', 'rosbuild_init', 'rosbuild_genmsg', 'rosbuild_gensrv', 'rosbuild_find_ros_package', 'genaction', 'gencfg', 'install', 'rosbuild_check_for_sse']: continue if line[1][0].lower() == 'set': if line[1][1] in ['ROS_BUILD_TYPE', 'EXECUTABLE_OUTPUT_PATH', 'LIBRARY_OUTPUT_PATH', 'CMAKE_BUILD_TYPE', 'CMAKE_INSTALL_RPATH', 'CMAKE_INSTALL_RPATH_USE_LINK_PATH', 'CMAKE_BUILD_WITH_INSTALL_RPATH', 'CMAKE_SKIP_BUILD_RPATH', 'WXSWIG_EXECUTABLE']: continue # strip leading 'bin/' from executables if line[1][0] in ['rosbuild_add_executable', 'target_link_libraries', 'rosbuild_link_boost']: while line[1][1].startswith('bin/'): line[1][1] = line[1][1][4:] if line[1][0] == 'rosbuild_add_library': while line[1][1].startswith('lib/'): line[1][1] = line[1][1][4:] if line[1][0] == 'include': if line[1][1] == '$ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake': continue if line[1][1] == '$ENV{ROS_ROOT}/core/rosbuild/rosconfig.cmake': continue if line[1][1] == '${dynamic_reconfigure_PACKAGE_PATH}/cmake/cfgbuild.cmake': continue if line[1][1] == '$ENV{ROS_ROOT}/core/rosbuild/FindPkgConfig.cmake': continue if line[1][1] == '${actionlib_PACKAGE_PATH}/cmake/actionbuild.cmake': line[1][1] = '${actionlib_msgs_PACKAGE_PATH}/cmake/actionbuild.cmake' if line[1][1] == '$ENV{ROS_ROOT}/core/rosbuild/FindPkgConfig.cmake': continue #print line oslist += '%s(%s)\n' % (line[1][0], ' '.join([reconstitute(x) for x in line[1][1:]])) if line[0] == 'comment': oslist += line[1] + '\n' return oslist
def codegen(obj): global in_ns, pointers, line, included ctype = obj[0] if type(obj) is code: return obj try: if ctype.line: line = ctype.line except: pass if ctype == "empty": return code(u"") if ctype == "in_ns": in_ns = obj[1][0] subtree = obj[1] for sel in subtree: codegen(sel) in_ns = u"" return code(u"") elif ctype == "decl": name = u"" for data in obj[1]: if type(data) is unicode or type(data) is str: name = data try: yf = ymlFunc[name] yf.alias except: ymlFunc[name] = YF(name) yf = ymlFunc[name] if in_ns: yf.alias = in_ns + u":" + name if not enable_tracing: if in_ns == "xsl" and (name == "debug" or name=="assert" or name[:7]=="_trace_"): yf.alias = "-" yf.addParm("skip1") yf.addParm("skip2") break elif type(data) is tuple or type(data) is Symbol: if data[0] == "base": base = data[1][0] try: yf = ymlFunc[name] = ymlFunc[base].copy(name) except KeyError: if included: raise KeyError(u"in " + included + u":" + u(line) + u": " + base + u" as base for " + name) else: raise KeyError(u"in " + u(line) + u": " + base + u" as base for " + name) elif data[0] == "shape": shape = ymlFunc[data[1]] try: yf = ymlFunc[name] yf.patch(shape) except KeyError: if included: raise KeyError(u"in " + included + u":" + u(line) + u": " + base + u" as shape for " + name) else: raise KeyError(u"in " + u(line) + u": " + base + u" as shape for " + name) elif data[0] == "descend": yf.addDescend(data[1]) elif data[0] == "declParm": l = data[1] parmName = l[0] if len(l)==1: yf.addParm(parmName) else: value = l[1] if parmName[0] != "%": yf.addValue(parmName, value) if parmName[0] == "*": yf.pointers[parmName[1:]] = value yf.addParm(parmName) elif parmName[0] == "%": if type(value) is unicode or type(value) is str: yf.macros[parmName] = u(evalPython(value)) else: yf.macros[parmName] = u(evalPython(u(value))) yf.addParm(parmName) elif data[0] == "alias": if in_ns: yf.alias = in_ns + u":" + data[1][0] else: yf.alias = data[1][0] elif data[0] == "content": yf.content = data[1] return code(u"") elif ctype == "funclist": result = u"" for f in obj[1]: result += codegen(f) return code(result) elif ctype == "parentheses": if len(obj[1]): return codegen(('func', ['_parentheses', ('content', [obj[1][0]])])) else: return u"" elif ctype == "fparm": if len(obj[1]): return codegen(('func', ['_parm', ('content', [obj[1][0]])])) else: return u"" elif ctype == "generic": return codegen(('func', ['_generic', ('content', [obj[1][0]])])) elif ctype == "xbase": return codegen(('func', ['_base', ('content', [obj[1][0]])])) elif ctype == "func": avoidTag = False name = obj[1][0] if name == "decl": if ymlFunc[name] == "#error": if included: raise SyntaxError(u"in " + included + u":" + u(line) + u": syntax error in decl statement") else: raise SyntaxError(u"in " + u(line) + u": syntax error in decl statement") if name == "define" or name == "operator": if ymlFunc[name] == "#error": if included: raise SyntaxError(u"in " + included + u":" + u(line) + u": syntax error in define statement") else: raise SyntaxError(u"in " + u(line) + u": syntax error in define statement") if name[0] == "&": avoidTag = True name = name[1:] hasContent = False if len(name) > 2: if name[0:2] == "**": return code(eval('u'+pointer(name[1:]))) if name[0] == "*": name = eval(pointer(name)) if name[0] == "&": avoidTag = True name = name[1:] try: ymlFunc[name] except: try: ymlFunc["_"] return codegen(('func', ['_', ('content', [('funclist', [obj])])])) except: ymlFunc[name] = YF(name) if ymlFunc[name].alias == "-": avoidTag = True to_add = [] if len(ymlFunc[name].descends): if obj[1][-1][0] != 'content': if included: raise KeyError(u"in " + included + u":" + u(line) + u": " + name + u" has descending attributes, but no descendants are following") else: raise KeyError(u"in " + u(line) + u": " + name + u" has descending attributes, but no descendants are following") def first_func(obj): if type(obj) is tuple or type(obj) is Symbol: if obj[0] == 'func': return obj elif obj[0] == 'funclist': return first_func(obj[1]) elif obj[0] == 'content': return first_func(obj[1]) else: return None elif type(obj) == list: for e in obj: f = first_func(e) if f: return f return None def copy_without_first_func(o, found = False): c = [] for obj in o: if found: c.append(obj) else: if obj[0] == 'func': if obj[1][-1][0] == 'content': c.extend( obj[1][-1][1] ) found = True else: c.append( ( obj[0], copy_without_first_func(obj[1], False ) ) ) return c def get_parms(obj): result = [] for e in obj[1]: if type(e) is tuple or type(e) is Symbol: if e[0] == "parm": result.append( e ) return result try: add_params = get_parms(obj) for e in obj[1][-1][1]: c = e[1] for dname in ymlFunc[name].descends: f, c = first_func(c), copy_without_first_func(c) if dname[0] == "*": pointers[dname[1:]] = "'" + f[1][0] + "'" else: add_params.append( ('parm', [dname, u"'" + f[1][0] + u"'"]) ) try: add_params.extend( get_parms(f) ) except: pass new_things = [ e[1][0] ] new_things.extend( add_params ) new_things.append( ('content', c) ) to_add.append( ('func', new_things ) ) except: if included: raise KeyError(u"in " + included + u":" + u(line) + u": " + name + u" has descending attributes, and too less descendants are following") else: raise KeyError(u"in " + u(line) + u": " + name + u" has descending attributes, and too less descendants are following") if not to_add: to_add = ( obj, ) complete = u"" for obj in to_add: subtree = None try: if obj[1][-1][0] == "content": subtree = obj[1][-1][1] except: pass if ymlFunc[name].content: hasContent = True treetemplate = deepcopy(ymlFunc[name].content) subtree = replaceContent(treetemplate, subtree) if subtree: hasContent = True hasContent, result = ymlFunc[name](obj[1], hasContent, avoidTag) if subtree: for sel in subtree: result += codegen(sel) if hasContent and not(avoidTag): result += u"</" + ymlFunc[name].alias + u">" complete += result return code(complete) elif ctype == "textsection": result = u'' ll = obj[1].splitlines() space = len(ll[-1]) - 2 for l in ll[1:-1]: m = re.match(bqq, l) if m: cmd = m.group(1) try: r, x = parseLine(cmd, _inner, [], True, comment) if x: raise SyntaxError(cmd) result += _finish(r) except SyntaxError: if included: raise SyntaxError(u"in " + included + u":" + u(line) + u": syntax error in executing command: " + cmd.strip()) else: raise SyntaxError(u"in " + u(line) + u": syntax error in executing command: " + cmd.strip()) else: result += codegen(Symbol(u'lineQuote', u'| ' + l[space:])) return code(result) elif ctype == "textsectionu": result = u'' ll = obj[1].splitlines() space = len(ll[-1]) - 2 for l in ll[1:-1]: m = re.match(bqq, l) if m: cmd = m.group(1) try: r, x = parseLine(cmd, _inner, [], True, comment) if x: raise SyntaxError(cmd) result += _finish(r) except SyntaxError: if included: raise SyntaxError(u"in " + included + u":" + u(line) + u": syntax error in executing command: " + cmd.strip()) else: raise SyntaxError(u"in " + u(line) + u": syntax error in executing command: " + cmd.strip()) else: if result != u'': result += u' ' result += codegen(Symbol(u'quote', [u'> ' + l[space:]])) return code(result) elif ctype == "lineQuote" or ctype == "quote": m, text, base, inds = None, u"", 0, 0 if ctype == "lineQuote": text = obj[1] m = lq.match(text) if m: inds = len(m.group(1)) text = m.group(2)[1:] else: inds = 0 elif ctype == "quote": inds = -1 text = obj[1][0] m = sq.match(text) if m: if m.group(1): inds = int(m.group(1)) text = m.group(2)[1:] else: if type(text) is unicode or type(text) is str: text = u(evalPython(text)) ind = u"" if inds > -1: try: cmd = evalPython(u"indent(" + u(inds) + u")") result, rest = parseLine(u(cmd), _inner, [], True, comment) if rest: raise SyntaxError() ind = _finish(result) except: pass if ctype == "lineQuote": text += u"\n" hasTextFunc = False try: ymlFunc["text"] hasTextFunc = True except: pass text = executeCmd(text) return code(ind + text) elif ctype == "tagQuote": m = tq.match(obj[1]) if m.group(1) == "<": return code(u"<" + m.group(2)) else: return code(m.group(2)) elif ctype == "operator": operator.append((re.compile(evalPython(obj[1][0])), obj[1][1])) return code(u"") elif ctype == "constant": name = obj[1][0] if name[0] == "*": name = name[1:] value = obj[1][1] pointers[name] = value return code(u"") elif ctype == "include": reverse = False ktext, kxml = False, False for arg in obj[1]: if type(arg) is tuple or type(arg) is Symbol: if arg[0] == "reverse": reverse = True elif arg[0] == "ktext": ktext = True elif arg[0] == "kxml": kxml = True elif type(arg) is unicode or type(arg) is str: filemask = arg if filemask[0] == '/' or filemask[0] == '.': files = sorted(glob(filemask)) else: files = [] for directory in includePath: path = os.path.join(directory, filemask) files.extend(sorted(glob(path))) if files and reverse: files = files[-1::-1] if not(files): if included: raise IOError(u"in " + included + ":" + u(line) + u": include file(s) '" + filemask + u"' not found") else: raise IOError(u"in " + u(line) + u": include file(s) '" + filemask + u"' not found") includeFile = fileinput.input(files, mode="rU", openhook=fileinput.hook_encoded(encoding)) _included = included if ktext or kxml: text = u"" for line in includeFile: included = includeFile.filename() if kxml: if (not line[:6] == '<?xml ') and (not line[:6] == '<?XML '): text += line else: text += executeCmd(line) included = _included return code(text) else: result = parse(ymlCStyle(), includeFile, True, comment) included = u(filemask) x = _finish(result) included = _included return code(x) elif ctype == "pyExp": exp = obj[1][0] cmd = evalPython(exp) result, rest = parseLine(u(cmd), _inner, [], True, comment) if rest: raise SyntaxError(cmd) return code(_finish(result)) elif ctype == "pythonCall": parms = [] data = obj[1] for p in data: if type(p) is unicode or type(p) is str: name = p elif type(p) is tuple or type(p) is Symbol: ptype = p[0] if ptype == "parm": if p[1][0][0] == "*": parms.append(pointer(p[1][0])) else: parms.append(p[1][0]) if len(parms) == 0: exp = name + u"()" elif len(parms) == 1: exp = name + u"(" + u(parms[0]) + u")" else: exp = name + u(tuple(parms)) cmd = evalPython(exp) result, rest = parseLine(u(cmd), _inner, [], True, comment) if rest: raise SyntaxError() return code(_finish(result)) else: return code(u"")
def parse(fileinput_files, trace=False): pyPEG.print_trace = trace return pyPEG.parse(unit(), fileinput_files, skipWS=True, skipComments=comment)
def sanitize_one(inlists, pkgname): finput = fileinput.FileInput([inlists]) ast = parse(cmake(), finput, True) oslist = '' oslist += 'if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/package.cmake)\n include(${CMAKE_CURRENT_BINARY_DIR}/package.cmake)\nendif()\n' for line in ast: if line[0] == 'macrocall': if line[1][0].lower() in [ 'cmake_minimum_required', 'rosbuild_init', 'rosbuild_genmsg', 'rosbuild_gensrv', 'rosbuild_find_ros_package', 'genaction', 'gencfg', 'install', 'rosbuild_check_for_sse' ]: continue if line[1][0].lower() == 'set': if line[1][1] in [ 'ROS_BUILD_TYPE', 'EXECUTABLE_OUTPUT_PATH', 'LIBRARY_OUTPUT_PATH', 'CMAKE_BUILD_TYPE', 'CMAKE_INSTALL_RPATH', 'CMAKE_INSTALL_RPATH_USE_LINK_PATH', 'CMAKE_BUILD_WITH_INSTALL_RPATH', 'CMAKE_SKIP_BUILD_RPATH', 'WXSWIG_EXECUTABLE' ]: continue # strip leading 'bin/' from executables if line[1][0] in [ 'rosbuild_add_executable', 'target_link_libraries', 'rosbuild_link_boost' ]: while line[1][1].startswith('bin/'): line[1][1] = line[1][1][4:] if line[1][0] == 'rosbuild_add_library': while line[1][1].startswith('lib/'): line[1][1] = line[1][1][4:] if line[1][0] == 'include': if line[1][1] == '$ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake': continue if line[1][ 1] == '$ENV{ROS_ROOT}/core/rosbuild/rosconfig.cmake': continue if line[1][ 1] == '${dynamic_reconfigure_PACKAGE_PATH}/cmake/cfgbuild.cmake': continue if line[1][ 1] == '$ENV{ROS_ROOT}/core/rosbuild/FindPkgConfig.cmake': continue if line[1][ 1] == '${actionlib_PACKAGE_PATH}/cmake/actionbuild.cmake': line[1][ 1] = '${actionlib_msgs_PACKAGE_PATH}/cmake/actionbuild.cmake' if line[1][ 1] == '$ENV{ROS_ROOT}/core/rosbuild/FindPkgConfig.cmake': continue #print line oslist += '%s(%s)\n' % (line[1][0], ' '.join( [reconstitute(x) for x in line[1][1:]])) if line[0] == 'comment': oslist += line[1] + '\n' return oslist
PTFI, PIFT, PIFF, PFFI, PDUB, PLS, PRS, PFWD, PBAK, SPACE] #def pipeq(): return re.compile(r"\|=") def pipeq(): return "|=" def arr(): return arrow def ident(): return symbol, -1, (dot, symbol) def assign(): return pipeq, [ident, tupe] def place(): return [assign, ident, tupe] def expression(): return place, -1, (arr, place) def declaration(): return typedec, symbol, "=", [ident, literal] def statement(): return [declaration, expression, comment, rawstring], -2, ";" def block(): return "{", -1, [rawstring, statement], "}" def tupe(): return "(", 0, ([literal, ident], -1, (",", [literal, ident])), ")" def parameterlist(): return "(", 0, (typedec, symbol, -1, (",", typedec, symbol)), ")" def function(): return keyword("def"), symbol, parameterlist, block def mod(): return "module", symbol, "{", -1, [function, rawstring], "}" # simpleLanguage <- function; def simpleLanguage(): return -1, mod pyPEG.print_trace = False files = fileinput.input() result = parse( simpleLanguage(), files, True, comment, lineCount = True, )
# returnstatement <- k"return" expression; def returnstatement(): return keyword("return"), expression # ifstatement <- k"if" "(" expression ")" block k"else" block; def ifstatement(): return keyword("if"), "(", expression, ")", block, keyword("else"), block # statement <- (ifstatement | returnstatement) ";"; def statement(): return [ifstatement, returnstatement], ";" # block <- "{" statement+ "}"; def block(): return "{", -2, statement, "}" # parameterlist <- "(" symbol ("," symbol)* ")"; def parameterlist(): return "(", symbol, -1, (",", symbol), ")" # functioncall <- symbol "(" expressionlist ")"; def functioncall(): return symbol, "(", expressionlist, ")" # function <- k"function" symbol parameterlist block; def function(): return keyword("function"), symbol, parameterlist, block # simpleLanguage <- function; def simpleLanguage(): return function pyPEG.print_trace = True files = fileinput.input() result = parse(simpleLanguage(), files, True, comment) print result
# if len(pyAST[1])==1: # print "---", pyAST[0],"=", pyAST[1], " ", type(pyAST[1][0]) # if len(pyAST[1])==1 and type(pyAST[1][0]) is unicode: # print "---", pyAST[0],"=", pyAST[1] if type(pyAST[1][0]) is not Symbol: result = u"<" + pyAST[0].replace("_","-") + "=" + pyAST[1][0] + u"/>" else: result = u"<" + pyAST[0].replace("_", "-") + u">" for e in pyAST[1:]: result += pyAST2XML(e) result += u"</" + pyAST[0].replace("_", "-") + u">" else: result = u"" for e in pyAST: result += pyAST2XML(e) return result pyPEG.print_trace = True files = fileinput.input() result = parse((source_text,), files, True) #print result xml=pyAST2XML(result) print xml
args = optParser.parse_args() comment = r(r"(\(\*.*?\*\))|({.*?})", re.S) def iec(): return iec_source, pragma = r(r"\s*\(\*\s*\@(\w+)\s*:=\s*'(.*?)'\s*\*\)\s*") empty = r(r"^\s*$") try: files = fileinput.input(args.inputFile) ast = parse(iec, files, True, comment) #t = test() #print(t.print_()) #test.print_() #print(ast) #print(json.dumps(ast, indent=2)) #print_ast(ast, 0) execute_string, cycle_time = InitPT(ast) print(var_list) print(execute_string) print(cycle_time) result = buildPT.buildPT(var_list, execute_string, cycle_time) #result = [varl] #result.extend(l) print(result) for i in result:
def statement(): return [assignment] def number(): return re.compile(r'-?(\d*\.\d*|\d+|".+?")') def variable(): return re.compile(r'[A-Z]') def expression(): return [number, variable, operation, ("(", expression, ")")] def expr(): return [number, variable, ("(", expression, ")")] def assignment(): return expression, '->', variable def operator(): return re.compile(r"\+|-|\*|/|\^") def operation(): return expr, operator, expr pyPEG.print_trace = True files = fileinput.input() result = parse(program(), files) print result