Tokenize the input and parse it into a [cmd2.parsing.Statement][] object. Stripping comments, expanding aliases and shortcuts, and extracting output redirection directives. :param line: the command line being parsed :return: a new [cmd2.parsing.Statement][] object :
(self, line: str)
| 420 | return self.split_on_punctuation(tokens) |
| 421 | |
| 422 | def parse(self, line: str) -> Statement: |
| 423 | """Tokenize the input and parse it into a [cmd2.parsing.Statement][] object. |
| 424 | |
| 425 | Stripping comments, expanding aliases and shortcuts, and extracting output redirection directives. |
| 426 | |
| 427 | :param line: the command line being parsed |
| 428 | :return: a new [cmd2.parsing.Statement][] object |
| 429 | :raises Cmd2ShlexError: if a shlex error occurs (e.g. No closing quotation) |
| 430 | """ |
| 431 | # handle the special case/hardcoded terminator of a blank line |
| 432 | # we have to do this before we tokenize because tokenizing |
| 433 | # destroys all unquoted whitespace in the input |
| 434 | terminator = "" |
| 435 | if line[-1:] == constants.LINE_FEED: |
| 436 | terminator = constants.LINE_FEED |
| 437 | |
| 438 | command = "" |
| 439 | args = "" |
| 440 | |
| 441 | # lex the input into a list of tokens |
| 442 | tokens = self.tokenize(line) |
| 443 | |
| 444 | # of the valid terminators, find the first one to occur in the input |
| 445 | terminator_pos = len(tokens) + 1 |
| 446 | for pos, cur_token in enumerate(tokens): |
| 447 | for test_terminator in self.terminators: |
| 448 | if cur_token.startswith(test_terminator): |
| 449 | terminator_pos = pos |
| 450 | terminator = test_terminator |
| 451 | # break the inner loop, and we want to break the |
| 452 | # outer loop too |
| 453 | break |
| 454 | else: |
| 455 | # this else clause is only run if the inner loop |
| 456 | # didn't execute a break. If it didn't, then |
| 457 | # continue to the next iteration of the outer loop |
| 458 | continue |
| 459 | # inner loop was broken, break the outer |
| 460 | break |
| 461 | |
| 462 | if terminator: |
| 463 | if terminator == constants.LINE_FEED: |
| 464 | terminator_pos = len(tokens) + 1 |
| 465 | |
| 466 | # everything before the first terminator is the command and the args |
| 467 | (command, args) = self._command_and_args(tokens[:terminator_pos]) |
| 468 | |
| 469 | # we will set the suffix later |
| 470 | # remove all the tokens before and including the terminator |
| 471 | tokens = tokens[terminator_pos + 1 :] |
| 472 | else: |
| 473 | (testcommand, testargs) = self._command_and_args(tokens) |
| 474 | if testcommand in self.multiline_commands: |
| 475 | # no terminator on this line but we have a multiline command |
| 476 | # everything else on the line is part of the args |
| 477 | # because redirectors can only be after a terminator |
| 478 | command = testcommand |
| 479 | args = testargs |