# HG changeset patch # User catherine@Elli.myhome.westell.com # Date 1214239897 14400 # Node ID 4e028e9ec4c2bfa8549f458aed72b6403bf3d270 # Parent a0f7702f2a4b3516222bd0d0d5dc9e2ef1d6274f punctFinder going to go in diff -r a0f7702f2a4b -r 4e028e9ec4c2 cmd2.py --- a/cmd2.py Sat Jun 21 19:54:57 2008 -0400 +++ b/cmd2.py Mon Jun 23 12:51:37 2008 -0400 @@ -18,7 +18,7 @@ As of 0.3.0, options should be specified as `optparse` options. See README.txt. flagReader.py options are still supported for backward compatibility """ -import cmd, re, os, sys, optparse, subprocess, tempfile, pyparsing +import cmd, re, os, sys, optparse, subprocess, tempfile, pyparsing, doctest from optparse import make_option class OptionParser(optparse.OptionParser): @@ -123,7 +123,41 @@ def getPasteBuffer(): raise OSError, pastebufferr % ('xclip', 'On Debian/Ubuntu, install with "sudo apt-get install xclip"') setPasteBuffer = getPasteBuffer - + +def punctuationParser(punctuators): + """ + Produces a string parser based on a list of targets to search for. + Output is a parser function. + Parser's output is a tuple: (before the target, [elements of the target], after the target) + >>> p = punctuationParser([';', 'EOF']) + >>> p('is terminated;') + ('is terminated', [';'], '') + >>> p('is terminated EOF after the end') + ('is terminated', ['EOF'], ' after the end') + >>> p('is not terminated') + >>> pattern1 = pyparsing.Literal(';') + pyparsing.Optional(pyparsing.Word(pyparsing.nums)) + >>> p2 = punctuationParser([pattern1, 'EOF']) + >>> p2('the quick brown fox;4') + ('the quick brown fox', [';', '4'], '') + >>> p2('the quick brown foxEOF') + ('the quick brown fox', ['EOF'], '') + >>> p2('nothing') + """ + processed = punctuators[:] + if not hasattr(processed[0], 'parseString'): + processed[0] = pyparsing.Literal(processed[0]) + processed = reduce(lambda x, y: x ^ y, processed) + processed.ignore(pyparsing.sglQuotedString) + processed.ignore(pyparsing.dblQuotedString) + pattern = pyparsing.SkipTo(processed) + processed + pyparsing.restOfLine + def parser(txt): + result = pattern.searchString(txt) + if result: + return result[0][0], result[0][1:-1], result[0][-1] + else: + return None + return parser + class Cmd(cmd.Cmd): caseInsensitive = True multilineCommands = [] @@ -143,7 +177,7 @@ break settable = ['prompt', 'continuationPrompt', 'defaultFileName', 'editor', 'caseInsensitive'] - terminators = ';\n' + terminators = [';','\n'] _TO_PASTE_BUFFER = 1 def do_cmdenvironment(self, args): self.stdout.write(""" @@ -152,7 +186,7 @@ Settable parameters: %(settable)s """ % { 'casesensitive': ('not ' and self.caseInsensitive) or '', - 'terminators': ' '.join(self.terminators), + 'terminators': ' '.join(str(self.terminators)), 'settable': ' '.join(self.settable) }) @@ -173,7 +207,12 @@ """Lists single-key shortcuts available.""" result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in self.shortcuts.items()) self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result)) - + + commmand_terminator_finder = punctuationParser(terminators) + outputTo_finder = punctuationParser(['>']) + inputFrom_finder = punctuationParser(['<']) + pipe_finder = punctuationParser(['|']) + notAPipe = pyparsing.SkipTo('|') notAPipe.ignore(pyparsing.sglQuotedString) notAPipe.ignore(pyparsing.dblQuotedString) @@ -650,3 +689,7 @@ def restore(self): for attrib in self.attribs: setattr(self.obj, attrib, getattr(self, attrib)) + +if __name__ == '__main__': + doctest.testmod() + \ No newline at end of file diff -r a0f7702f2a4b -r 4e028e9ec4c2 lineend.py --- a/lineend.py Sat Jun 21 19:54:57 2008 -0400 +++ b/lineend.py Mon Jun 23 12:51:37 2008 -0400 @@ -1,8 +1,8 @@ import pyparsing, sys, doctest -intgr = pyparsing.Optional(pyparsing.Word(pyparsing.nums)) -terminators = [pyparsing.Literal(';') + intgr, - pyparsing.Literal('\\t') + intgr] +integer_pattern = pyparsing.Optional(pyparsing.Word(pyparsing.nums)) +terminators = [pyparsing.Literal(';') + integer_pattern, + pyparsing.Literal('\\t') + integer_pattern] complete_pattern = reduce(lambda x, y: x ^ y, terminators) redirect_pattern = pyparsing.oneOf('< >') + pyparsing.restOfLine pipe_pattern = pyparsing.Literal('|') + pyparsing.restOfLine @@ -11,21 +11,21 @@ pattern.ignore(pyparsing.sglQuotedString) pattern.ignore(pyparsing.dblQuotedString) -def parse(txt, mustBeTerminated=False): +def parse(txt): """ - >>> sorted(parse('select * from dual;', True).items()) + >>> sorted(parse('select * from dual;').items()) [('inputFrom', None), ('outputTo', None), ('pipeTo', None), ('terminator', [';'])] - >>> sorted(parse('select * from dual E', True).items()) + >>> sorted(parse('select * from dual E').items()) [('inputFrom', None), ('outputTo', None), ('pipeTo', None), ('terminator', None)] - >>> sorted(parse('select * from', True).items()) + >>> sorted(parse('select * from').items()) [('inputFrom', None), ('outputTo', None), ('pipeTo', None), ('terminator', None)] - >>> sorted(parse('select * from dual; > result.txt', True).items()) + >>> sorted(parse('select * from dual; > result.txt').items()) [('inputFrom', None), ('outputTo', 'result.txt'), ('pipeTo', None), ('terminator', [';'])] - >>> sorted(parse("select * from dual where val = 'x > y'", True).items()) + >>> sorted(parse("select * from dual where val = 'x > y'").items()) [('inputFrom', None), ('outputTo', None), ('pipeTo', None), ('terminator', None)] - >>> sorted(parse('select * from dual; | wc -c', True).items()) + >>> sorted(parse('select * from dual; | wc -c').items()) [('inputFrom', None), ('outputTo', None), ('pipeTo', 'wc -c'), ('terminator', [';'])] - >>> sorted(parse('select * from dual; | sort > sorted.txt', True).items()) + >>> sorted(parse('select * from dual; | sort > sorted.txt').items()) [('inputFrom', None), ('outputTo', None), ('pipeTo', 'sort > sorted.txt'), ('terminator', [';'])] """ result = {'inputFrom': None, 'outputTo': None, 'pipeTo': None, 'terminator': None}