PageRenderTime 14ms CodeModel.GetById 10ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lib/regular_expression/low_level/python_regular_expression_builder.e

http://github.com/tybor/Liberty
Specman e | 202 lines | 67 code | 3 blank | 132 comment | 6 complexity | 77320287c16b2d5949c8fd273c8f0544 MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4class PYTHON_REGULAR_EXPRESSION_BUILDER
  5
  6inherit
  7   PERL5_REGULAR_EXPRESSION_BUILDER
  8      redefine parse_extended_pattern
  9      end
 10
 11create {ANY}
 12   make
 13
 14feature {} -- parsing
 15   parse_extended_pattern
 16      local
 17         dont_restore, saved_is_case_insensitive, saved_does_match_line_boundary, saved_does_any_match_newline,
 18         saved_has_extended_legibility: BOOLEAN
 19      do
 20         -- skip known characters
 21         read_character
 22         read_character
 23         -- save the state of the flags
 24         saved_is_case_insensitive := is_case_insensitive
 25         saved_does_match_line_boundary := does_match_line_boundary
 26         saved_does_any_match_newline := does_any_match_newline
 27         saved_has_extended_legibility := has_extended_legibility
 28         -- read the flags
 29         read_modifiers(True)
 30         if not end_of_input and then last_character = '-' then
 31            read_character
 32            read_modifiers(False)
 33         end
 34         if not end_of_input then
 35            inspect
 36               last_character
 37            when ')' then
 38               -- flag alteration only
 39               emit(the_true_node)
 40               dont_restore := True
 41            when '#' then
 42               -- comment
 43               emit(the_true_node)
 44               from
 45               until
 46                  end_of_input or else last_character = ')'
 47               loop
 48                  read_character
 49               end
 50            when ':' then
 51               -- not capturing
 52               read_character
 53               if not end_of_input then
 54                  parse_alternative
 55               end
 56            when '=' then
 57               -- zero width positive look-ahead
 58               parse_looking(True)
 59            when '!' then
 60               -- zero width negative look-ahead
 61               parse_looking(True)
 62            when '<' then
 63               -- zero width look-behind
 64               read_character
 65               if not end_of_input then
 66                  inspect
 67                     last_character
 68                  when '=' then
 69                     -- zero width positive look-behind
 70                     parse_looking(False)
 71                  when '!' then
 72                     -- zero width negative look-behind
 73                     parse_looking(False)
 74                  else
 75                     set_error(once "bad zero width look-behind")
 76                  end
 77               end
 78            when '{', '?', '(', '>' then
 79               -- unsupported
 80               set_error(once "unsupported experimental extended pattern")
 81            when 'P' then
 82               parse_named_group
 83            else
 84               set_error(once "unknown extended pattern")
 85            end
 86         end
 87         if not has_error then
 88            if end_of_input or else last_character /= ')' then
 89               set_error(once "extended pattern not finished")
 90            else
 91               if dont_restore then
 92               else
 93                  -- restore the flags
 94                  is_case_insensitive := saved_is_case_insensitive
 95                  does_match_line_boundary := saved_does_match_line_boundary
 96                  does_any_match_newline := saved_does_any_match_newline
 97                  has_extended_legibility := saved_has_extended_legibility
 98               end
 99               read_character
100            end
101         end
102      end
103
104   parse_named_group
105      local
106         group_name: FIXED_STRING; group_id: INTEGER
107      do
108         read_character
109         if not end_of_input then
110            inspect
111               last_character
112            when '=' then
113               -- backtrack match by name
114               from
115                  last_string.clear_count
116                  read_character
117               until
118                  end_of_input or else last_character = ')'
119               loop
120                  last_string.add_last(last_character)
121                  read_character
122               end
123               if end_of_input or else last_string.is_empty then
124                  set_error(once "premature end of group name")
125               else
126                  group_name := last_string.intern
127                  if last_substrings_names.fast_has(group_name) then
128                     group_id := last_substrings_names.fast_at(group_name)
129                     check
130                        group_id.in_range(1, last_group_count)
131                     end
132                     if group_stack.has(group_id) then
133                        set_error(once "unsupported forward group number")
134                     else
135                        emit_match_previous_group(group_id)
136                     end
137                  else
138                     set_error(once "undefined named group")
139                  end
140               end
141            when '<' then
142               -- new named group
143               from
144                  last_string.clear_count
145                  read_character
146               until
147                  end_of_input or else last_character = '>' or else last_character = ')'
148               loop
149                  last_string.add_last(last_character)
150                  read_character
151               end
152               if end_of_input or else last_character = ')' or else last_string.is_empty then
153                  set_error(once "unfinished group name")
154               else
155                  group_name := last_string.intern
156                  if last_substrings_names.fast_has(group_name) then
157                     set_error(once "duplicate group name")
158                  else
159                     check
160                        last_character = '>'
161                     end
162                     read_character
163                     prepare_group
164                     group_id := last_group_count
165                     parse_alternative
166                     if not has_error then
167                        emit_group
168                        if not has_error then
169                           last_substrings_names.add(group_id, group_name)
170                        end
171                     end
172                  end
173               end
174            else
175               set_error(once "unknown character following a ?P grouping")
176            end
177         end
178      ensure
179         error_or_stack_incremented_by_one: has_error or else stack.count = old stack.count + 1
180      end
181
182end -- class PYTHON_REGULAR_EXPRESSION_BUILDER
183--
184-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
185--
186-- Permission is hereby granted, free of charge, to any person obtaining a copy
187-- of this software and associated documentation files (the "Software"), to deal
188-- in the Software without restriction, including without limitation the rights
189-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
190-- copies of the Software, and to permit persons to whom the Software is
191-- furnished to do so, subject to the following conditions:
192--
193-- The above copyright notice and this permission notice shall be included in
194-- all copies or substantial portions of the Software.
195--
196-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
197-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
199-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
200-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
201-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
202-- THE SOFTWARE.