Mercurial > python-cmd2
comparison cmd2.py @ 146:9ffb01d8876f
streamlining parsing
author | catherine@dellzilla |
---|---|
date | Thu, 20 Nov 2008 14:21:11 -0500 |
parents | 0e0fc729e1a2 |
children | cda32481187c |
comparison
equal
deleted
inserted
replaced
145:0e0fc729e1a2 | 146:9ffb01d8876f |
---|---|
189 pass | 189 pass |
190 | 190 |
191 def __init__(self, *args, **kwargs): | 191 def __init__(self, *args, **kwargs): |
192 cmd.Cmd.__init__(self, *args, **kwargs) | 192 cmd.Cmd.__init__(self, *args, **kwargs) |
193 self.history = History() | 193 self.history = History() |
194 self.terminatorPattern = (pyparsing.oneOf(self.terminators) ^ (pyparsing.Literal('\nEOF') + pyparsing.lineEnd))('terminator') | |
194 for p in (self.terminatorPattern, self.pipePattern, self.redirectInPattern, self.redirectOutPattern, self.punctuationPattern): | 195 for p in (self.terminatorPattern, self.pipePattern, self.redirectInPattern, self.redirectOutPattern, self.punctuationPattern): |
195 p.ignore(pyparsing.sglQuotedString) | 196 p.ignore(pyparsing.sglQuotedString) |
196 p.ignore(pyparsing.dblQuotedString) | 197 p.ignore(pyparsing.dblQuotedString) |
197 p.ignore(self.commentGrammars) | 198 p.ignore(self.commentGrammars) |
198 p.ignore(self.commentInProgress) | 199 p.ignore(self.commentInProgress) |
204 result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in self.shortcuts.items()) | 205 result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in self.shortcuts.items()) |
205 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result)) | 206 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result)) |
206 | 207 |
207 commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment]) | 208 commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment]) |
208 commentInProgress = pyparsing.Literal('/*') + pyparsing.SkipTo(pyparsing.stringEnd) | 209 commentInProgress = pyparsing.Literal('/*') + pyparsing.SkipTo(pyparsing.stringEnd) |
209 | 210 terminators = [';', '\n\n'] |
210 specialTerminators = {'/*': pyparsing.Literal('*/')('terminator') } | |
211 terminatorPattern = ((pyparsing.Literal(';') ^ pyparsing.Literal('\n\n')) | |
212 ^ (pyparsing.Literal('\nEOF') + pyparsing.lineEnd))('terminator') | |
213 argSeparatorPattern = pyparsing.Word(pyparsing.printables)('command') \ | 211 argSeparatorPattern = pyparsing.Word(pyparsing.printables)('command') \ |
214 + pyparsing.SkipTo(pyparsing.StringEnd())('args') | 212 + pyparsing.SkipTo(pyparsing.StringEnd())('args') |
215 filenamePattern = pyparsing.Word(pyparsing.alphanums + '#$-_~{},.!:\\/') | 213 filenamePattern = pyparsing.Word(pyparsing.alphanums + '#$-_~{},.!:\\/') |
216 integerPattern = pyparsing.Word(pyparsing.nums).setParseAction( lambda s,l,t: [ int(t[0]) ] ) | 214 integerPattern = pyparsing.Word(pyparsing.nums).setParseAction( lambda s,l,t: [ int(t[0]) ] ) |
217 pipePattern = pyparsing.Literal('|')('pipe') + pyparsing.restOfLine('pipeTo') | 215 pipePattern = pyparsing.Literal('|')('pipe') + pyparsing.restOfLine('pipeTo') |
219 + pyparsing.Optional(filenamePattern)('outputTo') | 217 + pyparsing.Optional(filenamePattern)('outputTo') |
220 redirectInPattern = pyparsing.Literal('<')('input') \ | 218 redirectInPattern = pyparsing.Literal('<')('input') \ |
221 + pyparsing.Optional(filenamePattern)('inputFrom') | 219 + pyparsing.Optional(filenamePattern)('inputFrom') |
222 punctuationPattern = pipePattern ^ redirectInPattern ^ redirectOutPattern | 220 punctuationPattern = pipePattern ^ redirectInPattern ^ redirectOutPattern |
223 | 221 |
222 def p2(self, s, assumeComplete=False): | |
223 ''' | |
224 >>> c = Cmd() | |
225 >>> print c.p2('barecommand').dump() | |
226 >>> print c.p2('command with args').dump() | |
227 >>> print c.p2('command with args and terminator; and suffix').dump() | |
228 >>> print c.p2('command with args, terminator;sufx | piped').dump() | |
229 >>> print c.p2('simple | piped').dump() | |
230 >>> print c.p2('output into > afile.txt').dump() | |
231 >>> print c.p2('output into;sufx | pipethrume plz > afile.txt').dump() | |
232 >>> print c.p2('output to paste buffer >> ').dump() | |
233 ''' | |
234 outputParser = pyparsing.oneOf(['>>','>'])('output') | |
235 terminatorParser = pyparsing.oneOf(self.terminators)('terminator') | |
236 (pyparsing.stringEnd ^ pyparsing.oneOf(self.terminators) ^ '\nEOF' ^ '|' ^ outputParser)('terminator') | |
237 statementParser = pyparsing.Combine(pyparsing.Word(pyparsing.printables)('command') + | |
238 pyparsing.SkipTo(terminatorParser ^ '\nEOF' ^ '|' ^ outputParser ^ pyparsing.stringEnd)('args') + | |
239 pyparsing.Optional(terminatorParser) | |
240 )('statement') | |
241 parser = statementParser + \ | |
242 pyparsing.SkipTo(outputParser ^ '|' ^ pyparsing.stringEnd)('suffix') + \ | |
243 pyparsing.Optional('|' + pyparsing.SkipTo(outputParser ^ pyparsing.stringEnd)('pipeDest')) + \ | |
244 pyparsing.Optional(outputParser + pyparsing.SkipTo(pyparsing.stringEnd)('outputDest')) | |
245 self.commentGrammars.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).setParseAction(lambda x: '') | |
246 self.commentInProgress.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(pyparsing.cStyleComment) | |
247 parser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress) | |
248 return parser.parseString(s) | |
249 | |
224 def parsed(self, s, assumeComplete=False): | 250 def parsed(self, s, assumeComplete=False): |
251 pass | |
225 ''' | 252 ''' |
226 >>> c = Cmd() | 253 >>> c = Cmd() |
227 >>> r = c.parsed('quotes "are > ignored" < inp.txt') | 254 >>> r = c.parsed('quotes "are > ignored" < inp.txt') |
228 >>> r.statement, r.input, r.inputFrom, r.output, r.outputFrom | 255 >>> r.statement, r.input, r.inputFrom, r.output, r.outputFrom |
229 ('quotes "are > ignored" ', '<', 'inp.txt', '', '') | 256 ('quotes "are > ignored" ', '<', 'inp.txt', '', '') |
265 result['parseable'] = result.after | 292 result['parseable'] = result.after |
266 else: | 293 else: |
267 # does not catch output marks | 294 # does not catch output marks |
268 if (not assumeComplete) and (command in self.multilineCommands): | 295 if (not assumeComplete) and (command in self.multilineCommands): |
269 return result # don't bother with the rest, we're still collecting input | 296 return result # don't bother with the rest, we're still collecting input |
270 result['statement'] = result['unterminated'] = result.before | |
271 result += parseSearchResults(self.punctuationPattern, s) | 297 result += parseSearchResults(self.punctuationPattern, s) |
298 result['statement'] = result['unterminated'] = result.before | |
272 result += parseSearchResults(self.pipePattern, result.parseable) | 299 result += parseSearchResults(self.pipePattern, result.parseable) |
273 result += parseSearchResults(self.redirectInPattern, result.parseable) | 300 result += parseSearchResults(self.redirectInPattern, result.parseable) |
274 result += parseSearchResults(self.redirectOutPattern, result.parseable) | 301 result += parseSearchResults(self.redirectOutPattern, result.parseable) |
275 result += parseSearchResults(self.argSeparatorPattern, result.statement) | 302 result += parseSearchResults(self.argSeparatorPattern, result.statement) |
276 if self.caseInsensitive: | 303 if self.caseInsensitive: |