Coverage for trlc/nested.py: 100%

26 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-03-27 00:52 +0000

1#!/usr/bin/env python3 

2# 

3# TRLC - Treat Requirements Like Code 

4# Copyright (C) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) 

5# 

6# This file is part of the TRLC Python Reference Implementation. 

7# 

8# TRLC is free software: you can redistribute it and/or modify it 

9# under the terms of the GNU General Public License as published by 

10# the Free Software Foundation, either version 3 of the License, or 

11# (at your option) any later version. 

12# 

13# TRLC is distributed in the hope that it will be useful, but WITHOUT 

14# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 

15# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 

16# License for more details. 

17# 

18# You should have received a copy of the GNU General Public License 

19# along with TRLC. If not, see <https://www.gnu.org/licenses/>. 

20 

21from abc import abstractmethod 

22 

23from trlc.ast import String_Literal 

24from trlc.lexer import Lexer_Base, Source_Reference 

25 

26 

27class Nested_Lexer(Lexer_Base): 

28 def __init__(self, mh, literal): 

29 assert isinstance(literal, String_Literal) 

30 

31 origin_full_text = literal.location.text() 

32 self.origin_multi_string = origin_full_text.startswith(('"""', "'''")) 

33 if self.origin_multi_string: 

34 self.base_offset = 3 

35 text = origin_full_text[3:-3] 

36 else: 

37 self.base_offset = 1 

38 text = origin_full_text[1:-1].replace('\\"', '"') 

39 

40 self.origin_location = literal.location 

41 

42 super().__init__(mh, text) 

43 

44 def source_location(self, start_line, start_col, begin, end): 

45 assert 0 <= begin <= end < self.length 

46 assert start_line >= 1 

47 assert start_col >= 1 

48 

49 if self.origin_multi_string: 

50 loc = Source_Reference( 

51 lexer = self.origin_location.lexer, 

52 start_line = self.origin_location.line_no + (start_line - 1), 

53 start_col = (self.origin_location.col_no + self.base_offset 

54 if start_line == 1 

55 else start_col), 

56 start_pos = (self.origin_location.start_pos + 

57 self.base_offset + 

58 begin), 

59 end_pos = (self.origin_location.start_pos + 

60 self.base_offset + 

61 end)) 

62 

63 else: 

64 escapes_to_start = self.content[0:begin].count('"') 

65 escapes_to_end = escapes_to_start + \ 

66 self.content[begin:end + 1].count('"') 

67 assert start_line == 1 

68 loc = Source_Reference( 

69 lexer = self.origin_location.lexer, 

70 start_line = self.origin_location.line_no, 

71 start_col = (self.origin_location.col_no + 

72 self.base_offset + 

73 begin + escapes_to_start), 

74 start_pos = (self.origin_location.start_pos + 

75 self.base_offset + 

76 begin + escapes_to_start), 

77 end_pos = (self.origin_location.start_pos + 

78 self.base_offset + 

79 end + escapes_to_end)) 

80 

81 return loc 

82 

83 @abstractmethod 

84 def file_location(self): 

85 pass 

86 

87 @abstractmethod 

88 def token(self): 

89 pass