comparison cmd2.py @ 434:742fd308f0c9

better SkipTo around quoted strings
author catherine.devlin@gmail.com
date Sun, 21 Aug 2011 02:39:43 -0400
parents 5a814cb007ae
children bfbe4241bd6b
comparison
equal deleted inserted replaced
433:5a814cb007ae 434:742fd308f0c9
626 - args: has > inside 626 - args: has > inside
627 - multilineCommand: multiline 627 - multilineCommand: multiline
628 - terminator: ; 628 - terminator: ;
629 - terminator: ; 629 - terminator: ;
630 >>> print (c.parser.parseString('multiline command /* with comment in progress;').dump()) 630 >>> print (c.parser.parseString('multiline command /* with comment in progress;').dump())
631 ['multiline', ' command'] 631 ['multiline', ' command /* with comment in progress;']
632 - multilineCommand: multiline 632 - multilineCommand: multiline
633 >>> print (c.parser.parseString('multiline command /* with comment complete */ is done;').dump()) 633 >>> print (c.parser.parseString('multiline command /* with comment complete */ is done;').dump())
634 ['multiline', 'command /* with comment complete */ is done', ';', ''] 634 ['multiline', 'command /* with comment complete */ is done', ';', '']
635 - args: command /* with comment complete */ is done 635 - args: command /* with comment complete */ is done
636 - multilineCommand: multiline 636 - multilineCommand: multiline
647 - args: command ends 647 - args: command ends
648 - multilineCommand: multiline 648 - multilineCommand: multiline
649 - terminator: ['\n', '\n'] 649 - terminator: ['\n', '\n']
650 - terminator: ['\n', '\n'] 650 - terminator: ['\n', '\n']
651 >>> print (c.parser.parseString('multiline command "with term; ends" now\n\n').dump()) 651 >>> print (c.parser.parseString('multiline command "with term; ends" now\n\n').dump())
652 ['multiline', 'command ends', '\n', '\n'] 652 ['multiline', 'command "with term; ends" now', '\n', '\n']
653 - args: command "with term; ends" now 653 - args: command "with term; ends" now
654 - multilineCommand: multiline 654 - multilineCommand: multiline
655 - statement: ['multiline', '"with term; ends" now', '\n', '\n'] 655 - statement: ['multiline', 'command "with term; ends" now', '\n', '\n']
656 - args: command "with term; ends" now 656 - args: command "with term; ends" now
657 - multilineCommand: multiline 657 - multilineCommand: multiline
658 - terminator: ['\n', '\n'] 658 - terminator: ['\n', '\n']
659 - terminator: ['\n', '\n'] 659 - terminator: ['\n', '\n']
660 >>> print (c.parser.parseString('what if "ending is in quotes" but').dump()) 660 >>> print (c.parser.parseString('what if "quoted strings /* seem to " start comments?').dump())
661 ['what', 'if "ending is in quotes" but'] 661 ['what', 'if "quoted strings /* seem to " start comments?']
662 - args: if "ending is in quotes" but 662 - args: if "quoted strings /* seem to " start comments?
663 - command: what 663 - command: what
664 - statement: ['what', 'if "ending is in quotes" but'] 664 - statement: ['what', 'if "quoted strings /* seem to " start comments?']
665 - args: if "ending is in quotes" but 665 - args: if "quoted strings /* seem to " start comments?
666 - command: what
667 >>> print (c.parser.parseString('what if "ending is in quotes"').dump())
668 ['what', 'if "ending is in quotes"']
669 - args: if "ending is in quotes"
670 - command: what
671 - statement: ['what', 'if "ending is in quotes"']
672 - args: if "ending is in quotes"
673 - command: what 666 - command: what
674 ''' 667 '''
675 outputParser = (pyparsing.Literal('>>') | (pyparsing.WordStart() + '>') | pyparsing.Regex('[^=]>'))('output') 668 outputParser = (pyparsing.Literal('>>') | (pyparsing.WordStart() + '>') | pyparsing.Regex('[^=]>'))('output')
676 669
677 terminatorParser = pyparsing.Or([(hasattr(t, 'parseString') and t) or pyparsing.Literal(t) for t in self.terminators])('terminator') 670 terminatorParser = pyparsing.Or([(hasattr(t, 'parseString') and t) or pyparsing.Literal(t) for t in self.terminators])('terminator')
678 terminatorParser.ignore(pyparsing.quotedString) #fail
679 stringEnd = pyparsing.stringEnd ^ '\nEOF' 671 stringEnd = pyparsing.stringEnd ^ '\nEOF'
680 self.multilineCommand = pyparsing.Or([pyparsing.Keyword(c, caseless=self.case_insensitive) for c in self.multilineCommands])('multilineCommand') 672 self.multilineCommand = pyparsing.Or([pyparsing.Keyword(c, caseless=self.case_insensitive) for c in self.multilineCommands])('multilineCommand')
681 oneLineCommand = (~self.multilineCommand + pyparsing.Word(self.legalChars))('command') 673 oneLineCommand = (~self.multilineCommand + pyparsing.Word(self.legalChars))('command')
682 pipe = pyparsing.Keyword('|', identChars='|') 674 pipe = pyparsing.Keyword('|', identChars='|')
683 self.commentGrammars.ignore(pyparsing.quotedString).setParseAction(lambda x: '') 675 self.commentGrammars.ignore(pyparsing.quotedString).setParseAction(lambda x: '')
684 doNotParse = self.commentGrammars | commentInProgress 676 doNotParse = self.commentGrammars | self.commentInProgress | pyparsing.quotedString
685 afterElements = \ 677 afterElements = \
686 pyparsing.Optional(pipe + pyparsing.SkipTo(outputParser ^ stringEnd)('pipeTo')) + \ 678 pyparsing.Optional(pipe + pyparsing.SkipTo(outputParser ^ stringEnd, ignore=doNotParse)('pipeTo')) + \
687 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd).setParseAction(lambda x: x[0].strip())('outputTo')) 679 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd, ignore=doNotParse).setParseAction(lambda x: x[0].strip())('outputTo'))
688 if self.case_insensitive: 680 if self.case_insensitive:
689 self.multilineCommand.setParseAction(lambda x: x[0].lower()) 681 self.multilineCommand.setParseAction(lambda x: x[0].lower())
690 oneLineCommand.setParseAction(lambda x: x[0].lower()) 682 oneLineCommand.setParseAction(lambda x: x[0].lower())
691 if self.blankLinesAllowed: 683 if self.blankLinesAllowed:
692 self.blankLineTerminationParser = pyparsing.NoMatch 684 self.blankLineTerminationParser = pyparsing.NoMatch
693 else: 685 else:
694 self.blankLineTerminator = (pyparsing.lineEnd + pyparsing.lineEnd)('terminator') 686 self.blankLineTerminator = (pyparsing.lineEnd + pyparsing.lineEnd)('terminator')
695 self.blankLineTerminator.setResultsName('terminator') 687 self.blankLineTerminator.setResultsName('terminator')
696 self.blankLineTerminationParser = ((self.multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(self.blankLineTerminator).setParseAction(lambda x: x[0].strip())('args') + self.blankLineTerminator)('statement') 688 self.blankLineTerminationParser = ((self.multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(self.blankLineTerminator, ignore=doNotParse).setParseAction(lambda x: x[0].strip())('args') + self.blankLineTerminator)('statement')
697 self.multilineParser = (((self.multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser, ignore=self.commentInProgress).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') + 689 self.multilineParser = (((self.multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser, ignore=doNotParse).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') +
698 pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd).setParseAction(lambda x: x[0].strip())('suffix') + afterElements) 690 pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd, ignore=doNotParse).setParseAction(lambda x: x[0].strip())('suffix') + afterElements)
699 self.multilineParser.ignore(self.commentInProgress) 691 self.multilineParser.ignore(self.commentInProgress)
700 self.singleLineParser = ((oneLineCommand + pyparsing.SkipTo(terminatorParser ^ stringEnd ^ pipe ^ outputParser).setParseAction(lambda x:x[0].strip())('args'))('statement') + 692 self.singleLineParser = ((oneLineCommand + pyparsing.SkipTo(terminatorParser ^ stringEnd ^ pipe ^ outputParser, ignore=doNotParse).setParseAction(lambda x:x[0].strip())('args'))('statement') +
701 pyparsing.Optional(terminatorParser) + afterElements) 693 pyparsing.Optional(terminatorParser) + afterElements)
702 #self.multilineParser = self.multilineParser.setResultsName('multilineParser') 694 #self.multilineParser = self.multilineParser.setResultsName('multilineParser')
703 #self.singleLineParser = self.singleLineParser.setResultsName('singleLineParser') 695 #self.singleLineParser = self.singleLineParser.setResultsName('singleLineParser')
704 self.blankLineTerminationParser = self.blankLineTerminationParser.setResultsName('statement') 696 self.blankLineTerminationParser = self.blankLineTerminationParser.setResultsName('statement')
705 self.parser = self.prefixParser + ( 697 self.parser = self.prefixParser + (
706 stringEnd | 698 stringEnd |
707 self.multilineParser | 699 self.multilineParser |
708 self.singleLineParser | 700 self.singleLineParser |
709 self.blankLineTerminationParser | 701 self.blankLineTerminationParser |
710 self.multilineCommand + pyparsing.SkipTo(stringEnd) 702 self.multilineCommand + pyparsing.SkipTo(stringEnd, ignore=doNotParse)
711 ) 703 )
712 #self.parser.ignore(pyparsing.quotedString).ignore(self.commentGrammars)
713 self.parser.ignore(self.commentGrammars) 704 self.parser.ignore(self.commentGrammars)
714 705
715 inputMark = pyparsing.Literal('<') 706 inputMark = pyparsing.Literal('<')
716 inputMark.setParseAction(lambda x: '') 707 inputMark.setParseAction(lambda x: '')
717 fileName = pyparsing.Word(self.legalChars + '/\\') 708 fileName = pyparsing.Word(self.legalChars + '/\\')
719 inputFrom.setParseAction(replace_with_file_contents) 710 inputFrom.setParseAction(replace_with_file_contents)
720 # a not-entirely-satisfactory way of distinguishing < as in "import from" from < 711 # a not-entirely-satisfactory way of distinguishing < as in "import from" from <
721 # as in "lesser than" 712 # as in "lesser than"
722 self.inputParser = inputMark + pyparsing.Optional(inputFrom) + pyparsing.Optional('>') + \ 713 self.inputParser = inputMark + pyparsing.Optional(inputFrom) + pyparsing.Optional('>') + \
723 pyparsing.Optional(fileName) + (pyparsing.stringEnd | '|') 714 pyparsing.Optional(fileName) + (pyparsing.stringEnd | '|')
724 #self.inputParser.ignore(pyparsing.quotedString).ignore(self.commentGrammars).ignore(self.commentInProgress) 715 self.inputParser.ignore(self.commentInProgress)
725 self.inputParser.ignore(self.commentGrammars).ignore(self.commentInProgress)
726 716
727 def preparse(self, raw, **kwargs): 717 def preparse(self, raw, **kwargs):
728 return raw 718 return raw
729 def postparse(self, parseResult): 719 def postparse(self, parseResult):
730 return parseResult 720 return parseResult