コード例 #1
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_consume_part_of_current_line__consume_all_characters(self):
     for source_string, expectation in self.test_cases_for_consume_all_characters_of_current_line:
         with self.subTest(msg='consume_part_of_current_line: ' + repr(source_string)):
             source = ParseSource(source_string)
             source.consume_part_of_current_line(len(source.current_line_text))
             expectation.apply_with_message(self, source,
                                            'consume_part_of_current_line:{}'.format(repr(source_string)))
コード例 #2
0
 def parse_from_source(self, source: ParseSource) -> SetupPhaseInstruction:
     args = source.remaining_part_of_current_line
     source.consume_current_line()
     components = args.split()
     if len(components) != self.num_args:
         raise ValueError('Expecting {} args. Found {} args'.format(self.num_args, len(components)))
     return self._parse(components)
コード例 #3
0
ファイル: token_parse.py プロジェクト: emilkarlen/exactly
def parse_token_or_none_on_current_line(source: ParseSource,
                                        argument_description: str = 'argument') -> Token:
    """
    Parses a single, optional token from remaining part of current line.

    Tokens must be separated by space.

    :param source: Must have a current line. Initial space is consumed. Text for token is consumed.
    :raise SingleInstructionInvalidArgumentException: The token has invalid syntax
    """
    source.consume_initial_space_on_current_line()
    if source.is_at_eol:
        return None
    part_of_current_line = source.remaining_part_of_current_line
    source_io = io.StringIO(part_of_current_line)
    lexer = shlex.shlex(source_io, posix=True)
    lexer.whitespace_split = True
    token_type = _derive_token_type(lexer, source.remaining_part_of_current_line[0])
    try:
        token_string = lexer.get_token()
    except ValueError as ex:
        msg = 'Invalid {}: {}'.format(argument_description, str(ex))
        raise SingleInstructionInvalidArgumentException(msg)
    source_string = _get_source_string_and_consume_token_characters(source, source_io)
    return Token(token_type, token_string, source_string)
コード例 #4
0
ファイル: token_parse.py プロジェクト: emilkarlen/exactly
def parse_token_or_none_on_current_line(source: ParseSource,
                                        argument_description: str = 'argument'
                                        ) -> Token:
    """
    Parses a single, optional token from remaining part of current line.

    Tokens must be separated by space.

    :param source: Must have a current line. Initial space is consumed. Text for token is consumed.
    :raise SingleInstructionInvalidArgumentException: The token has invalid syntax
    """
    source.consume_initial_space_on_current_line()
    if source.is_at_eol:
        return None
    part_of_current_line = source.remaining_part_of_current_line
    source_io = io.StringIO(part_of_current_line)
    lexer = shlex.shlex(source_io, posix=True)
    lexer.whitespace_split = True
    token_type = _derive_token_type(lexer,
                                    source.remaining_part_of_current_line[0])
    try:
        token_string = lexer.get_token()
    except ValueError as ex:
        msg = 'Invalid {}: {}'.format(argument_description, str(ex))
        raise SingleInstructionInvalidArgumentException(msg)
    source_string = _get_source_string_and_consume_token_characters(
        source, source_io)
    return Token(token_type, token_string, source_string)
コード例 #5
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_only_newline2(self):
     source = ParseSource('\n\n')
     source.consume_current_line()
     self.assertFalse(source.is_at_eof)
     self.assertTrue(source.has_current_line, 'has_current_line')
     self._assert_is_at_eol(source)
     self._assert_current_line_is(2, '', source)
コード例 #6
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_catch_up_with(self):
     test_cases = [
         ('consume part of current line',
          ['abc'],
          lambda parse_source: parse_source.consume(1),
          lambda parse_source: parse_source.consume(2)
          ),
         ('copy consumes current line/with existing following line',
          ['abc', 'def'],
          lambda parse_source: None,
          lambda parse_source: parse_source.consume_current_line()
          ),
         ('copy consumes current line/which is the last line',
          ['abc'],
          lambda parse_source: None,
          lambda parse_source: parse_source.consume_current_line()
          ),
         ('copy consumes num characters that stretches to the following line',
          ['123', '456'],
          lambda parse_source: None,
          lambda parse_source: parse_source.consume(5)
          ),
         ('copy consumes all remaining characters',
          ['123', '456'],
          lambda parse_source: None,
          lambda parse_source: parse_source.consume(7)
          ),
     ]
     for test_name, original_source_lines, original_setup, copy_modifier in test_cases:
         with self.subTest(test_name):
             # ARRANGE #
             original = ParseSource('\n'.join(original_source_lines))
             original_setup(original)
             # ACT #
             copy = original.copy
             copy_modifier(copy)
             original.catch_up_with(copy)
             # ASSERT #
             self.assertEqual(copy.is_at_eof,
                              original.is_at_eof,
                              'is_at_eof')
             self.assertEqual(copy.remaining_source,
                              original.remaining_source,
                              'remaining_source')
             self.assertEqual(copy.has_current_line,
                              original.has_current_line,
                              'has_current_line')
             if original.has_current_line:
                 self.assertEqual(copy.current_line_number,
                                  original.current_line_number,
                                  'current_line_number')
                 self.assertEqual(copy.remaining_part_of_current_line,
                                  original.remaining_part_of_current_line,
                                  'remaining_part_of_current_line')
                 self.assertEqual(copy.column_index,
                                  original.column_index,
                                  'column_index')
                 self.assertEqual(copy.is_at_eol,
                                  original.is_at_eol,
                                  'is_at_eol')
コード例 #7
0
 def parse_from_source(self, source: ParseSource) -> SetupPhaseInstruction:
     args = source.remaining_part_of_current_line
     source.consume_current_line()
     components = args.split()
     if len(components) != self.num_args:
         raise ValueError('Expecting {} args. Found {} args'.format(self.num_args, len(components)))
     return self._parse(components)
コード例 #8
0
 def _advance_source(source: ParseSource):
     if source.has_current_line:
         if not source.is_at_eol__except_for_space:
             source.consume(len(source.remaining_part_of_current_line))
             misc_utils.raise_superfluous_arguments(
                 source.remaining_part_of_current_line.strip())
         source.consume_current_line()
コード例 #9
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_single_line_source(self):
     source = ParseSource('single line')
     self._assert_current_line_and_remaining_part_of_it_is(1, 'single line', source)
     self.assertEqual('single line', source.remaining_source,
                      'remaining source')
     source.consume_current_line()
     self._assert_is_at_eof(source)
コード例 #10
0
ファイル: act.py プロジェクト: emilkarlen/exactly
 def parse(self, fs_location_info: FileSystemLocationInfo,
           source: ParseSource) -> ParsedInstruction:
     current_line = source.current_line
     source.consume_current_line()
     instruction = ActPhaseInstructionThatRecords(
         fs_location_info.current_source_file, current_line.text)
     return ParsedInstruction(line_sequence_from_line(current_line),
                              InstructionInfo(instruction, None))
コード例 #11
0
ファイル: token_parse.py プロジェクト: emilkarlen/exactly
def _get_source_string_and_consume_token_characters(
        source: ParseSource, source_io: io.StringIO) -> str:
    num_chars_consumed = source_io.tell()
    if source.remaining_part_of_current_line[num_chars_consumed - 1].isspace():
        num_chars_consumed -= 1
    ret_val = source.remaining_source[:num_chars_consumed]
    source.consume_part_of_current_line(num_chars_consumed)
    return ret_val
コード例 #12
0
ファイル: token_parse.py プロジェクト: emilkarlen/exactly
def _get_source_string_and_consume_token_characters(source: ParseSource,
                                                    source_io: io.StringIO) -> str:
    num_chars_consumed = source_io.tell()
    if source.remaining_part_of_current_line[num_chars_consumed - 1].isspace():
        num_chars_consumed -= 1
    ret_val = source.remaining_source[:num_chars_consumed]
    source.consume_part_of_current_line(num_chars_consumed)
    return ret_val
コード例 #13
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_first_line_is_empty(self):
     source = ParseSource('\n' + 'second line')
     self._assert_current_line_and_remaining_part_of_it_is(1, '', source)
     source.consume_current_line()
     self._assert_current_line_and_remaining_part_of_it_is(2, 'second line', source)
     self.assertEqual('second line', source.remaining_source,
                      'remaining source')
     source.consume_current_line()
     self._assert_is_at_eof(source)
コード例 #14
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_consume_current_line(self):
     test_cases = [
         ('single line',
          assert_source(is_at_eof=asrt.is_true,
                        has_current_line=asrt.is_false,
                        remaining_source=asrt.equals(''))
          ),
         ('',
          assert_source(is_at_eof=asrt.is_true,
                        has_current_line=asrt.is_false)
          ),
         ('first line\nsecond line',
          assert_source(is_at_eof=asrt.is_false,
                        has_current_line=asrt.is_true,
                        is_at_eol=asrt.is_false,
                        is_at_eol__except_for_space=asrt.is_false,
                        current_line_number=asrt.equals(2),
                        current_line_text=asrt.equals('second line'),
                        column_index=asrt.equals(0),
                        remaining_source=asrt.equals('second line'))
          ),
         ('single line\n',
          assert_source(is_at_eof=asrt.is_true,
                        has_current_line=asrt.is_true,
                        is_at_eol=asrt.is_true,
                        is_at_eol__except_for_space=asrt.is_true,
                        current_line_number=asrt.equals(2),
                        current_line_text=asrt.equals(''),
                        column_index=asrt.equals(0),
                        remaining_source=asrt.equals(''))
          ),
         ('\n',
          assert_source(is_at_eof=asrt.is_true,
                        has_current_line=asrt.is_true,
                        is_at_eol=asrt.is_true,
                        is_at_eol__except_for_space=asrt.is_true,
                        current_line_number=asrt.equals(2),
                        current_line_text=asrt.equals(''),
                        column_index=asrt.equals(0),
                        remaining_source=asrt.equals(''))
          ),
         ('\nsecond line',
          assert_source(is_at_eof=asrt.is_false,
                        has_current_line=asrt.is_true,
                        is_at_eol=asrt.is_false,
                        is_at_eol__except_for_space=asrt.is_false,
                        current_line_number=asrt.equals(2),
                        current_line_text=asrt.equals('second line'),
                        column_index=asrt.equals(0),
                        remaining_source=asrt.equals('second line'))
          ),
     ]
     for source_string, expectation in test_cases:
         with self.subTest(msg='consume current line: ' + repr(source_string)):
             source = ParseSource(source_string)
             source.consume_current_line()
             expectation.apply_with_message(self, source, 'consume_current_line:{}'.format(repr(source_string)))
コード例 #15
0
ファイル: source_utils.py プロジェクト: emilkarlen/exactly
def token_stream_from_parse_source(parse_source: ParseSource):
    """
    Gives a :class:`TokenStream` backed by the given :class:`ParseSource`.

    The source of the :class:`TokenStream` is the remaining sources of the :class:`ParseSource`
    """
    ts = new_token_stream(parse_source.remaining_source)
    yield ts
    parse_source.consume(ts.position)
コード例 #16
0
 def parse(self,
           fs_location_info: FileSystemLocationInfo,
           source: ParseSource) -> model.Instruction:
     first_line = source.current_line
     name = self._extract_name(source)
     parser = self._lookup_parser(first_line, name)
     source.consume_part_of_current_line(len(name))
     source.consume_initial_space_on_current_line()
     return self._parse(fs_location_info, source, parser, name)
コード例 #17
0
 def parse(self, fs_location_info: FileSystemLocationInfo,
           source: ParseSource) -> model.Instruction:
     err_msg_constructor = _ErrMsgSourceConstructor(source)
     name = self._extract_name(source)
     parser = self._lookup_parser(source.current_line, name)
     source.consume_part_of_current_line(len(name))
     source.consume_initial_space_on_current_line()
     return self._parse(fs_location_info, source, parser, name,
                        err_msg_constructor)
コード例 #18
0
def parse_from_parse_source(source: ParseSource,
                            conf: RelOptionArgumentConfiguration = CONFIGURATION) -> StringOrFileRefResolver:
    with from_parse_source(source,
                           consume_last_line_if_is_at_eol_after_parse=False) as token_parser:
        ret_val = parse_from_token_parser(token_parser, conf)
    if ret_val.source_type is SourceType.HERE_DOC:
        if source.is_at_eol:
            source.consume_current_line()
    return ret_val
コード例 #19
0
ファイル: act.py プロジェクト: emilkarlen/exactly
 def parse(self,
           fs_location_info: FileSystemLocationInfo,
           source: ParseSource) -> ParsedInstruction:
     current_line = source.current_line
     source.consume_current_line()
     instruction = ActPhaseInstructionThatRecords(fs_location_info.current_source_file,
                                                  current_line.text)
     return ParsedInstruction(line_sequence_from_line(current_line),
                              InstructionInfo(instruction,
                                              None))
コード例 #20
0
def from_remaining_part_of_current_line_of_parse_source(parse_source: ParseSource):
    """
    Gives a :class:`TokenParserPrime` backed by the given :class:`ParseSource`.

    The source of the :class:`TokenParserPrime` is the remaining part of the current line of the :class:`ParseSource`
    """
    tp = new_token_parser(parse_source.remaining_part_of_current_line,
                          first_line_number=parse_source.current_line_number)
    yield tp
    parse_source.consume(tp.token_stream.position)
コード例 #21
0
ファイル: parse_string.py プロジェクト: emilkarlen/exactly
def parse_string_sdv_from_parse_source(source: ParseSource,
                                       conf: Configuration = DEFAULT_CONFIGURATION) -> StringSdv:
    """
    :param source: Has a current line
    :raises SingleInstructionInvalidArgumentException: If cannot parse a PathDdv
    """

    ts = new_token_stream(source.remaining_part_of_current_line)
    ret_val = parse_string_sdv(ts, conf)
    source.consume(ts.position)
    return ret_val
コード例 #22
0
def _syntax_error_if_not_at_eof(source: parse_source.ParseSource):
    if source.is_at_eof:
        return
    if source.is_at_eol__except_for_space:
        source.consume_current_line()
        _syntax_error_if_not_at_eof(source)
    else:
        raise ParseException.of_str(
            'Superfluous arguments of {PROGRAM}: {src}'.format(
                PROGRAM=syntax_elements.PROGRAM_SYNTAX_ELEMENT.singular_name,
                src=source.remaining_part_of_current_line))
コード例 #23
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_consume_part_of_current_line(self):
     source = ParseSource('first line' + '\n' + 'second line')
     source.consume_part_of_current_line(len('first') + 1)
     self._assert_current_line_is(1, 'first line', source)
     self.assertEqual('line', source.remaining_part_of_current_line,
                      'Remaining part of current line')
     self.assertEqual('line' + '\n' + 'second line',
                      source.remaining_source,
                      'Remaining source')
     self.assertFalse(source.is_at_eof, 'is_at_eof')
     self.assertFalse(source.is_at_eol, 'is_at_eol')
コード例 #24
0
 def parse(self, fs_location_info: FileSystemLocationInfo,
           source: ParseSource) -> ParsedInstruction:
     first_line = source.current_line
     source_copy = source.copy
     description = _DescriptionExtractor(source_copy).apply()
     self._consume_space_and_comment_lines(source_copy, first_line)
     ret_val = parse_and_compute_source(self.instruction_parser,
                                        fs_location_info, source_copy,
                                        description)
     source.catch_up_with(source_copy)
     return ret_val
コード例 #25
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_consume_part_of_current_line__until_end_of_line_of_last_line(self):
     source = ParseSource('first line')
     source.consume_part_of_current_line(len('first line'))
     self._assert_current_line_is(1, 'first line', source)
     self.assertTrue(source.is_at_eol, 'is_at_eol')
     self.assertTrue(source.is_at_eof, 'is_at_eof')
     self.assertEqual('', source.remaining_part_of_current_line,
                      'Remaining part of current line')
     self.assertEqual('',
                      source.remaining_source,
                      'Remaining source')
コード例 #26
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
def remaining_source(remaining_contents_of_first_line: str,
                     following_lines: Sequence[str] = ()) -> ParseSource:
    """
    :param remaining_contents_of_first_line: Part of the first line that has not been consumed.
    :return: Source with some initial content of the first line that has been consumed.
    """
    previous_content = 'previous content '
    remaining_content = '\n'.join([remaining_contents_of_first_line] + list(following_lines))
    content = previous_content + remaining_content
    ret_val = ParseSource(content)
    ret_val.consume_part_of_current_line(len(previous_content))
    return ret_val
コード例 #27
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_two_line_source(self):
     original_source = 'first line' + '\n' + 'second line'
     source = ParseSource(original_source)
     self._assert_current_line_and_remaining_part_of_it_is(1, 'first line', source)
     self.assertEqual(original_source, source.remaining_source,
                      'remaining source')
     source.consume_current_line()
     self._assert_current_line_and_remaining_part_of_it_is(2, 'second line', source)
     self.assertEqual('second line', source.remaining_source,
                      'remaining source')
     source.consume_current_line()
     self._assert_is_at_eof(source)
コード例 #28
0
def from_remaining_part_of_current_line_of_parse_source(
        parse_source: ParseSource) -> ContextManager[TokenParser]:
    """
    Gives a :class:`TokenParser` backed by the given :class:`ParseSource`.

    The source of the :class:`TokenParser` is the remaining part of the current line of the :class:`ParseSource`
    """
    tp = new_token_parser(parse_source.remaining_part_of_current_line,
                          first_line_number=parse_source.current_line_number)
    try:
        yield tp
    finally:
        parse_source.consume(tp.token_stream.position)
コード例 #29
0
 def parse(self,
           fs_location_info: FileSystemLocationInfo,
           source: ParseSource) -> ParsedInstruction:
     first_line = source.current_line
     source_copy = source.copy
     description = _DescriptionExtractor(source_copy).apply()
     self._consume_space_and_comment_lines(source_copy, first_line)
     ret_val = parse_and_compute_source(self.instruction_parser,
                                        fs_location_info,
                                        source_copy,
                                        description)
     source.catch_up_with(source_copy)
     return ret_val
コード例 #30
0
 def parse(self,
           fs_location_info: FileSystemLocationInfo,
           source: ParseSource) -> sut.ParsedInstruction:
     first_line_number = source.current_line_number
     dummy_source = line_source.LineSequence(first_line_number, (source.current_line_text,))
     is_instruction = False
     while not source.is_at_eof and source.current_line_text.startswith(self.instruction_line_identifier):
         source.consume_current_line()
         is_instruction = True
     if not is_instruction:
         raise ValueError('Not an instruction')
     return sut.ParsedInstruction(dummy_source,
                                  InstructionInfo(Instruction(), None))
コード例 #31
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_consume_with_invalid_arguments(self):
     test_cases = [
         ('a', 0, 2),
         ('a', 1, 1),
         ('a\nb', 0, 4),
         ('a\nb', 1, 3),
     ]
     for source, num_chars_on_current_line_to_consume_before_check, num_chars in test_cases:
         with self.subTest(source=source, num_chars=num_chars):
             source = ParseSource(source)
             source.consume_part_of_current_line(num_chars_on_current_line_to_consume_before_check)
             with self.assertRaises(ValueError):
                 source.consume(num_chars)
コード例 #32
0
    def _consume_and_return_current_line(source: ParseSource,
                                         line_predicate_for_line_to_consume: Callable[[str], bool],
                                         ) -> line_source.LineSequence:
        current_line = source.current_line
        lines = [current_line.text]
        source.consume_current_line()

        while source.has_current_line and line_predicate_for_line_to_consume(source.current_line_text):
            lines.append(source.current_line_text)
            source.consume_current_line()

        return line_source.LineSequence(current_line.line_number,
                                        tuple(lines))
コード例 #33
0
 def parse(self, fs_location_info: FileSystemLocationInfo,
           source: ParseSource) -> sut.ParsedInstruction:
     first_line_number = source.current_line_number
     dummy_source = line_source.LineSequence(first_line_number,
                                             (source.current_line_text, ))
     is_instruction = False
     while not source.is_at_eof and source.current_line_text.startswith(
             self.instruction_line_identifier):
         source.consume_current_line()
         is_instruction = True
     if not is_instruction:
         raise ValueError('Not an instruction')
     return sut.ParsedInstruction(dummy_source,
                                  InstructionInfo(Instruction(), None))
コード例 #34
0
    def _consume_and_return_current_line(
        source: ParseSource,
        line_predicate_for_line_to_consume: Callable[[str], bool],
    ) -> line_source.LineSequence:
        current_line = source.current_line
        lines = [current_line.text]
        source.consume_current_line()

        while source.has_current_line and line_predicate_for_line_to_consume(
                source.current_line_text):
            lines.append(source.current_line_text)
            source.consume_current_line()

        return line_source.LineSequence(current_line.line_number, tuple(lines))
コード例 #35
0
 def __init__(self, instructions: Sequence[ActPhaseInstruction]):
     self.instructions = instructions
     single_line_parser = ParserForSingleLineUsingStandardSyntax()
     single_line = single_line_parser.apply(instructions)
     single_line = single_line.strip()
     self._source = ParseSource(single_line)
     self._path_parser = parse_path.PathParser(RELATIVITY_CONFIGURATION)
コード例 #36
0
 def test_all_fail_unrecognized_element_SHOULD_be_raised_WHEN_all_parsers_fail_and_last_parser_raises_UE(
         self):
     # ARRANGE #
     source_text = 'first line'
     err_msg = 'error message in exception'
     cases = [
         NameAndValue('one parser', [
             SectionElementParserThatRaisesUnrecognizedSectionElementSourceError(
                 err_msg)
         ]),
         NameAndValue('more than one parser - first parser returns None', [
             SectionElementParserThatReturnsNone(),
             SectionElementParserThatRaisesUnrecognizedSectionElementSourceError(
                 err_msg)
         ]),
     ]
     for case in cases:
         with self.subTest(case.name):
             source = ParseSource(source_text)
             parser = sut.ParserFromSequenceOfParsers(case.value)
             # ACT #
             with self.assertRaises(
                     UnrecognizedSectionElementSourceError) as cm:
                 parser.parse(ARBITRARY_FS_LOCATION_INFO, source)
             self.assertEqual(err_msg, cm.exception.message,
                              'error message in exception')
コード例 #37
0
ファイル: misc.py プロジェクト: emilkarlen/exactly
 def _consume_instruction_source(source: ParseSource) -> line_source.LineSequence:
     current_line = source.current_line_text
     if is_multi_line_instruction_line(current_line):
         first_line_number = source.current_line_number
         lines = [current_line]
         source.consume_current_line()
         # Eat additional lines
         while source.has_current_line:
             current_line = source.current_line_text
             if is_multi_line_instruction_line(current_line):
                 lines.append(current_line)
                 source.consume_current_line()
             else:
                 break
         return line_source.LineSequence(first_line_number, tuple(lines))
     else:
         return consume_current_line_and_return_it_as_line_sequence(source)
コード例 #38
0
 def apply(self, test_case: TestCaseFileReference,
           test_case_plain_source: str) -> test_case_doc.TestCase:
     file_parser = test_case_parser.new_parser(
         self._test_case_parsing_setup)
     source = ParseSource(test_case_plain_source)
     try:
         return file_parser.apply(test_case, source)
     except exceptions.ParseError as ex:
         ex.accept(_ParseErrorHandler())
コード例 #39
0
    def parse(self,
              fs_location_info: FileSystemLocationInfo,
              source: ParseSource) -> ConfigurationPhaseInstruction:
        rest_of_line = source.remaining_part_of_current_line
        source.consume_current_line()
        argument = extract_single_eq_argument_string(_DIR_ARG.name, rest_of_line)
        path_arguments = split_arguments_list_string(argument)
        if len(path_arguments) > 1:
            raise SingleInstructionInvalidArgumentException('Too many arguments: ' + argument)

        try:
            path_argument = pathlib.Path(pathlib.PurePosixPath(path_arguments[0]))
        except ValueError as ex:
            raise SingleInstructionInvalidArgumentException('Invalid path syntax:\n' + str(ex))

        return _Instruction(self.dir_to_set,
                            fs_location_info.current_source_file.abs_path_of_dir_containing_last_file_base_name,
                            path_argument)
コード例 #40
0
 def _consume_instruction_source(
         source: ParseSource) -> line_source.LineSequence:
     current_line = source.current_line_text
     if is_multi_line_instruction_line(current_line):
         first_line_number = source.current_line_number
         lines = [current_line]
         source.consume_current_line()
         # Eat additional lines
         while source.has_current_line:
             current_line = source.current_line_text
             if is_multi_line_instruction_line(current_line):
                 lines.append(current_line)
                 source.consume_current_line()
             else:
                 break
         return line_source.LineSequence(first_line_number, tuple(lines))
     else:
         return consume_current_line_and_return_it_as_line_sequence(source)
コード例 #41
0
    def parse(self, fs_location_info: FileSystemLocationInfo,
              source: ParseSource) -> ParsedInstruction:
        first_line_number = source.current_line_number
        current_line = source.current_line_text
        lines_read = [_un_escape(current_line)]
        source.consume_current_line()
        while not source.is_at_eof:
            current_line = source.current_line_text
            if syntax.is_section_header_line(current_line):
                break
            else:
                lines_read.append(_un_escape(current_line))
                source.consume_current_line()

        line_sequence = LineSequence(first_line_number, tuple(lines_read))
        return ParsedInstruction(
            line_sequence,
            InstructionInfo(SourceCodeInstruction(line_sequence), None))
コード例 #42
0
 def cases_wo_parentheses(expected_int: int) -> List[NSourceCase]:
     return [
         NSourceCase(
             'plain int',
             ParseSource(str(expected_int)),
             asrt_source.is_at_end_of_line(1),
         ),
         NSourceCase(
             'plain int followed by other plain int',
             ParseSource(str(expected_int) + ' 77'),
             asrt_source.is_at_line(1, '77'),
         ),
         NSourceCase(
             'plain int followed by end parenthesis',
             ParseSource(str(expected_int) + ' )'),
             asrt_source.is_at_line(1, ')'),
         ),
     ]
コード例 #43
0
    def parse(self,
              fs_location_info: FileSystemLocationInfo,
              source: ParseSource) -> Optional[ParsedFileInclusionDirective]:
        parts = source.current_line_text.strip().split()
        if len(parts) == 0 or parts[0] != self._directive_token:
            return None
        directive_source = line_sequence_from_line(source.current_line)
        source.consume_current_line()
        if len(parts) == 1:
            raise RecognizedSectionElementSourceError(directive_source,
                                                      'Missing {} argument'.format(FILE_ARGUMENT_NAME))

        if len(parts) != 2:
            raise RecognizedSectionElementSourceError(directive_source,
                                                      'Superfluous arguments: ' + ' '.join(parts[2:]))

        path = pathlib.Path(pathlib.PurePosixPath(parts[1]))
        return ParsedFileInclusionDirective(directive_source,
                                            [path])
コード例 #44
0
    def parse(self,
              fs_location_info: FileSystemLocationInfo,
              source: ParseSource) -> ParsedInstruction:
        first_line_number = source.current_line_number
        current_line = source.current_line_text
        lines_read = [_un_escape(current_line)]
        source.consume_current_line()
        while not source.is_at_eof:
            current_line = source.current_line_text
            if syntax.is_section_header_line(current_line):
                break
            else:
                lines_read.append(_un_escape(current_line))
                source.consume_current_line()

        line_sequence = LineSequence(first_line_number,
                                     tuple(lines_read))
        return ParsedInstruction(line_sequence,
                                 InstructionInfo(SourceCodeInstruction(line_sequence), None))
コード例 #45
0
 def runTest(self):
     # ARRANGE #
     conf = self.configuration
     arguments_str = _exe_file_syntax_str(conf, 'file.exe',
                                          'remaining args')
     source = ParseSource(arguments_str)
     # ACT #
     exe_file = parse_executable_file_path.parser().parse(source)
     # ASSERT #
     with self._tcds_and_test_as_curr_dir(
             File.empty('file.exe')) as environment:
         self._assert_does_not_pass_validation(exe_file, environment)
コード例 #46
0
 def check_invalid_syntax__abs_stx(
         self,
         put: unittest.TestCase,
         invalid_source: AbstractSyntax,
         sub_test_identifiers: Mapping[str, Any] = MappingProxyType({}),
 ):
     for layout_case in STANDARD_LAYOUT_SPECS:
         parse_source = ParseSource(invalid_source.tokenization().layout(
             layout_case.value))
         with put.subTest(zz_layout=layout_case.name,
                          **sub_test_identifiers):
             self.check_invalid_arguments(put, parse_source)
コード例 #47
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_last_line_is_empty(self):
     source = ParseSource('first line' + '\n')
     self._assert_current_line_and_remaining_part_of_it_is(1, 'first line', source)
     source.consume_current_line()
     self._assert_current_line_and_remaining_part_of_it_is(2, '', source)
     source.consume_current_line()
     self._assert_is_at_eof(source)
コード例 #48
0
ファイル: parse_source.py プロジェクト: emilkarlen/exactly
 def test_consume_initial_space(self):
     test_cases = [
         (['', 'second line'], '', True),
         (['non-space', 'second line'], 'non-space', False),
         (['   ', 'second line'], '', True),
         (['   non-space', 'second line'], 'non-space', False),
     ]
     for lines, remaining_part, is_at_eol in test_cases:
         with self.subTest():
             first_line = lines[0]
             source_lines = '\n'.join(lines)
             # ACT #
             source = ParseSource(source_lines)
             # ASSERT #
             source.consume_initial_space_on_current_line()
             assertion = assert_source(is_at_eol=asrt.equals(is_at_eol),
                                       remaining_part_of_current_line=asrt.equals(remaining_part),
                                       current_line_number=asrt.equals(1),
                                       current_line_text=asrt.equals(lines[0]),
                                       column_index=asrt.equals(len(first_line) - len(first_line.lstrip()))
                                       )
             assertion.apply(self, source)
コード例 #49
0
 def _consume_space_and_comment_lines(source: ParseSource, first_line: Line):
     error_message = 'End-of-file reached without finding an instruction (following a description)'
     if source.is_at_eof:
         raise new_unrecognized_section_element_error_of_single_line(first_line, error_message)
     line_in_error_message = first_line
     source.consume_initial_space_on_current_line()
     if not source.is_at_eol:
         return
     source.consume_current_line()
     while not source.is_at_eof:
         if syntax.is_empty_or_comment_line(source.current_line_text):
             line_in_error_message = source.current_line
             source.consume_current_line()
         else:
             source.consume_initial_space_on_current_line()
             return
     raise new_unrecognized_section_element_error_of_single_line(line_in_error_message, error_message)
コード例 #50
0
def from_parse_source(source: ParseSource,
                      consume_last_line_if_is_at_eol_after_parse: bool = False,
                      consume_last_line_if_is_at_eof_after_parse: bool = False):
    """
    Gives a :class:`TokenParserPrime` backed by the given :class:`ParseSource`.

    The source of the :class:`TokenParserPrime` is the remaining sources of the :class:`ParseSource`
    """
    tp = new_token_parser(source.remaining_source,
                          first_line_number=source.current_line_number)
    yield tp
    source.consume(tp.token_stream.position)
    if consume_last_line_if_is_at_eol_after_parse and source.is_at_eol:
        source.consume_current_line()
    elif consume_last_line_if_is_at_eof_after_parse and source.is_at_eof:
        source.consume_current_line()
コード例 #51
0
ファイル: element_parser.py プロジェクト: emilkarlen/exactly
def consume_current_line_and_return_it_as_line_sequence(source: ParseSource) -> line_source.LineSequence:
    ret_val = line_source.LineSequence(source.current_line_number,
                                       (source.current_line_text,))
    source.consume_current_line()
    return ret_val