diff --git a/json/json_array.e b/json/json_array.e index 7ca3c4fc..77b4aa72 100644 --- a/json/json_array.e +++ b/json/json_array.e @@ -51,9 +51,7 @@ feature -- Status report feature -- Change Element add(value:JSON_VALUE) is require - not_null:value /= void - local - l_json_value:JSON_VALUE + not_null:value /= void do values.extend(value) ensure @@ -87,16 +85,16 @@ feature -- Report hash_code:INTEGER is -- do - from - values.start - Result:=values.item.hash_code - until - values.off - loop - Result:= ((Result \\ 8388593) |<< 8) + values.item.hash_code - values.forth - end - Result := Result \\ values.count + from + values.start + Result:=values.item.hash_code + until + values.off + loop + Result:= ((Result \\ 8388593) |<< 8) + values.item.hash_code + values.forth + end + Result := Result \\ values.count end feature {NONE} --Implementation diff --git a/json/json_boolean.e b/json/json_boolean.e index ad3ea0bf..9bf1b9be 100644 --- a/json/json_boolean.e +++ b/json/json_boolean.e @@ -5,36 +5,40 @@ indexing revision: "$Revision$" class + JSON_BOOLEAN - inherit - JSON_VALUE + +inherit + JSON_VALUE create + make_boolean + feature -- Initialization - make_boolean(a_value:BOOLEAN) is + make_boolean (an_item: BOOLEAN) is -- - do - value:=a_value - end + do + item := an_item + end feature -- Access - to_json:STRING is + item: BOOLEAN + + to_json: STRING is -- - do - Result:=value.out - end + do + Result := item.out + end - hash_code:INTEGER is + hash_code: INTEGER is -- - do - Result:=value.hash_code - end + do + Result := item.hash_code + end - value:BOOLEAN - end diff --git a/json/json_number.e b/json/json_number.e index 17013e25..32185586 100644 --- a/json/json_number.e +++ b/json/json_number.e @@ -1,4 +1,5 @@ indexing + description: "JSON Numbers, octal and hexadecimal formats are not used." author: "Javier Velilla" date: "$Date$" @@ -7,54 +8,73 @@ indexing class JSON_NUMBER - inherit - JSON_VALUE - rename is_equal as is_equal_json_value - end + +inherit + + JSON_VALUE + rename + is_equal as is_equal_json_value + end create + make_integer, make_real feature -- initialization - make_integer(argument:INTEGER) is - do - value:= argument.out - internal_hash_code:=argument.hash_code - numeric_type:="INTEGER" - end - make_real(argument:REAL) is - do - value:= argument.out - internal_hash_code:=argument.hash_code - numeric_type:="REAL" - end + make_integer (argument: INTEGER) is + do + item:= argument.out + internal_hash_code:=argument.hash_code + numeric_type:= "INTEGER" + end + + make_real (argument: REAL) is + do + item:= argument.out + internal_hash_code:=argument.hash_code + numeric_type:= "REAL" + end feature -- Access - to_json:STRING is - -- - do - Result:=value - end - hash_code:INTEGER is + item: STRING + + hash_code: INTEGER is -- do Result:=internal_hash_code end +feature -- Status + is_equal (other: like Current): BOOLEAN is -- Is `other' attached to an object of the same type -- as current object and identical to it? do - Result:=value.is_equal(other.to_json) + Result:=item.is_equal (other.to_json) + end + +feature -- Conversion + + to_json: STRING is + -- + do + Result := item end feature -- Implementation - value:STRING - internal_hash_code:INTEGER - numeric_type:STRING -- REAL or INTEGER + + internal_hash_code: INTEGER + + numeric_type: STRING -- REAL or INTEGER + + +invariant + + item_not_void: item /= Void + end diff --git a/json/json_object.e b/json/json_object.e index a5faa59f..40531f99 100644 --- a/json/json_object.e +++ b/json/json_object.e @@ -1,79 +1,85 @@ indexing + description: "[ - An JSON_OBJECT represent an object in JSON. - An object is an unordered set of name/value pairs - +An JSON_OBJECT represent an object in JSON. +An object is an unordered set of name/value pairs + Examples: - + object {} {"key","value"} - ]" - author: "Javier Velilla" - date: "$Date$" - revision: "$Revision$" - license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" +]" + author: "Javier Velilla" + date: "$Date$" + revision: "$Revision$" + license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" class + JSON_OBJECT inherit + JSON_VALUE create + make feature -- Initialization + make is -- - do - create object.make (10) - end + do + create object.make (10) + end feature -- Change Element - put(value:JSON_VALUE ; key:JSON_STRING) is + put (value: JSON_VALUE ; key: JSON_STRING) is -- Assuming there is no item of key `key', -- insert `value' with `key'. - require - not_present: not has_key (key) - local - l_json_null:JSON_NULL - l_value:JSON_VALUE - do - l_value:=value - if value = void then - create l_json_null - l_value:=l_json_null - end - object.extend(l_value,key) + require + not_present: not has_key (key) + local + l_json_null: JSON_NULL + l_value: JSON_VALUE + do + l_value:=value + if value = void then + create l_json_null + l_value:=l_json_null end + object.extend (l_value,key) + end feature -- Access - has_key(key:JSON_STRING):BOOLEAN is - -- has the JSON_OBJECT contains a specific key 'key'. + + has_key (key: JSON_STRING):BOOLEAN is + -- has the JSON_OBJECT contains a specific key 'key'. do Result := object.has (key) end - has_item(value:JSON_VALUE):BOOLEAN is - -- has the JSON_OBJECT contain a specfic item 'value' + has_item (value: JSON_VALUE):BOOLEAN is + -- has the JSON_OBJECT contain a specfic item 'value' do Result := object.has_item (value) end - item(key:JSON_STRING):JSON_VALUE is - -- the json_value associated with a key. + item (key: JSON_STRING):JSON_VALUE is + -- the json_value associated with a key. do Result:= object.item (key) end - current_keys:ARRAY[JSON_STRING] is + current_keys: ARRAY [JSON_STRING] is -- array containing actually used keys do Result:=object.current_keys @@ -81,32 +87,31 @@ feature -- Access feature -- Report - to_json:STRING is + + to_json: STRING is -- Printable json representation -- {} or {member} -- see documentation - do - create Result.make_empty - Result.append ("{") - from - object.start - until - object.off - loop - Result.append (object.item_for_iteration.to_json) - Result.append (":") - Result.append (object.key_for_iteration.to_json) - object.forth - if not object.after then - Result.append (",") - end + do + create Result.make_empty + Result.append ("{") + from + object.start + until + object.off + loop + Result.append (object.item_for_iteration.to_json) + Result.append (":") + Result.append (object.key_for_iteration.to_json) + object.forth + if not object.after then + Result.append (",") end - Result.append ("}") end + Result.append ("}") + end - - - hash_code: INTEGER is + hash_code: INTEGER is -- Hash code value local do @@ -119,11 +124,13 @@ feature -- Report Result := ((Result \\ 8388593) |<< 8) + object.item_for_iteration.hash_code object.forth end - -- Ensure it is a positive value. + -- Ensure it is a positive value. Result := Result.hash_code end feature {NONE} -- Implementation - object:HASH_TABLE[JSON_VALUE,JSON_STRING] + + object: HASH_TABLE[JSON_VALUE,JSON_STRING] + end diff --git a/json/json_string.e b/json/json_string.e index a1e9399f..eab0da27 100644 --- a/json/json_string.e +++ b/json/json_string.e @@ -1,68 +1,86 @@ indexing + description:"[ - A JSON_STRING represent a string in JSON. - A string is a collection of zero or more Unicodes characters, wrapped in double - quotes, using blackslash espaces. - ]" + A JSON_STRING represent a string in JSON. + A string is a collection of zero or more Unicodes characters, wrapped in double + quotes, using blackslash espaces. + ]" author: "Javier Velilla" date: "$Date$" revision: "$Revision$" license:"MIT (see http://www.opensource.org/licenses/mit-license.php)" -class - JSON_STRING - inherit - JSON_VALUE - redefine - is_equal - end - create - make_json +class + + JSON_STRING + +inherit + + JSON_VALUE + redefine + is_equal + end + +create + + make_json + feature -- Initialization - make_json(value:STRING) is - -- - do - create buffer.make(256) - buffer.append (value) - end + + make_json (an_item: STRING) is + -- Initialize. + require + item_not_void: an_item /= Void + do + item := an_item + end feature -- Access + item: STRING + -- Contents + + feature -- Comparison + is_equal (other: like Current): BOOLEAN is -- Is JSON_STRING made of same character sequence as `other' -- (possibly with a different capacity)? do - Result:= Current.to_json.is_equal (other.to_json) + Result := Current.to_json.is_equal (other.to_json) end feature -- Change Element - append(value:STRING)is + + append (an_item: STRING)is -- - do - buffer.append (value) - end + do + item.append_string (an_item) + end feature -- Status report - to_json:STRING is - -- - do - create Result.make_empty - Result.append ("%"") - Result.append (buffer) - Result.append ("%"") - end - hash_code:INTEGER is + to_json: STRING is -- - do - Result:= buffer.hash_code + buffer.count - end + do + create Result.make_empty + Result.append ("%"") + Result.append (item) + Result.append ("%"") + end + + hash_code: INTEGER is + -- + do + Result := item.hash_code + end + +invariant + + value_not_void: item /= Void -feature {NONE} -- Implementation - buffer:STRING end diff --git a/json/scanner/json_parser.e b/json/scanner/json_parser.e index c1c69840..200dc5ae 100644 --- a/json/scanner/json_parser.e +++ b/json/scanner/json_parser.e @@ -1,392 +1,397 @@ indexing - description: "Objects that ..." + + description: "Parse serialized JSON data" author: "" date: "$Date$" revision: "$Revision$" class + JSON_PARSER - inherit - JSON_READER - JSON_TOKENS +inherit + JSON_READER + JSON_TOKENS create + make_parser + +feature {NONE} -- Initialize + + make_parser (a_json: STRING) is + -- Initialize. + require + json_not_empty: a_json /= Void and then not a_json.is_empty + do + make (a_json) + is_parsed := True + create current_errors.make_empty + end + + feature -- Access - is_parsed:BOOLEAN - current_errors:STRING + is_parsed: BOOLEAN - make_parser(a_json:STRING) is + current_errors: STRING + + +feature -- Commands + + parse_json: JSON_VALUE is -- - do - make(a_json) - is_parsed:=true - create current_errors.make_empty + do + Result := parse + if extra_elements then + is_parsed := false end + end - parse_json:JSON_VALUE is - -- - do - Result:=parse - if extra_elements then - is_parsed:=false - end - end - - parse:JSON_VALUE is + parse: JSON_VALUE is -- - local - c:CHARACTER - do - if is_parsed then - skip_withe_spaces - c:=actual - if c.is_equal (j_object_open) then - Result:=parse_object - elseif c.is_equal (j_string) then - Result:=parse_string - elseif c.is_equal (j_array_open) then - Result:=parse_array - elseif c.is_digit or c.is_equal (j_minus) then - Result:=parse_number - elseif is_null then - -- - Result:=create {JSON_NULL} - next;next;next; - elseif is_true then - Result:=create {JSON_BOOLEAN}.make_boolean (true) - next;next;next; - elseif is_false then - Result:=create {JSON_BOOLEAN}.make_boolean (false) - next;next;next;next; - else - is_parsed:=false - current_errors.append("JSON is not well formed in parse") - Result:=void - end + local + c: CHARACTER + do + if is_parsed then + skip_withe_spaces + c := actual + if c.is_equal (j_object_open) then + Result := parse_object + elseif c.is_equal (j_string) then + Result := parse_string + elseif c.is_equal (j_array_open) then + Result := parse_array + elseif c.is_digit or c.is_equal (j_minus) then + Result := parse_number + elseif is_null then + -- + Result := create {JSON_NULL} + next;next;next + elseif is_true then + Result := create {JSON_BOOLEAN}.make_boolean (true) + next;next;next + elseif is_false then + Result := create {JSON_BOOLEAN}.make_boolean (false) + next;next;next;next + else + is_parsed := false + current_errors.append ("JSON is not well formed in parse") + Result := void end - end + end + end - parse_object:JSON_OBJECT is + parse_object: JSON_OBJECT is -- object -- {} -- {"key" : "value" [,]} - local - has_more:BOOLEAN - l_json_string:JSON_STRING - l_value:JSON_VALUE - do - create Result.make - -- check if is an empty object {} - next - skip_withe_spaces - if actual.is_equal (j_object_close) then - --is an empty object - else - -- a complex object {"key" : "value"} - previous - from has_more:=true until not has_more - loop + local + has_more: BOOLEAN + l_json_string: JSON_STRING + l_value: JSON_VALUE + do + create Result.make + -- check if is an empty object {} + next + skip_withe_spaces + if actual.is_equal (j_object_close) then + --is an empty object + else + -- a complex object {"key" : "value"} + previous + from has_more := true until not has_more + loop + next + skip_withe_spaces + l_json_string := parse_string + next + skip_withe_spaces + if actual.is_equal (':') then next skip_withe_spaces - l_json_string:=parse_string - next - skip_withe_spaces - if actual.is_equal (':') then - next - skip_withe_spaces - else - is_parsed:=false - current_errors.append("%N Input string is a not well formed JSON, expected: : found:" + actual.out +"%N") - has_more:=false - end + else + is_parsed := false + current_errors.append ("%N Input string is a not well formed JSON, expected: : found: " + actual.out +"%N") + has_more := false + end - l_value:=parse - if is_parsed then - Result.put (l_value,l_json_string) - next - skip_withe_spaces - if actual.is_equal (j_object_close) then - has_more:=false - elseif not actual.is_equal (',') then - has_more:=false - is_parsed:=false - current_errors.append("JSON Object sintactically malformed expected , found:[" + actual.out + "] %N") - end - else - has_more:=false - -- explain the error - end + l_value := parse + if is_parsed then + Result.put (l_value,l_json_string) + next + skip_withe_spaces + if actual.is_equal (j_object_close) then + has_more := false + elseif not actual.is_equal (',') then + has_more := false + is_parsed := false + current_errors.append ("JSON Object sintactically malformed expected , found: [" + actual.out + "] %N") + end + else + has_more := false + -- explain the error end end end + end - parse_string:JSON_STRING is + parse_string: JSON_STRING is -- - local - has_more:BOOLEAN - l_json_string:STRING - l_unicode:STRING - do - create l_json_string.make_empty - if actual.is_equal (j_string) then - from - has_more:=true - until not has_more + local + has_more: BOOLEAN + l_json_string: STRING + l_unicode: STRING + do + create l_json_string.make_empty + if actual.is_equal (j_string) then + from + has_more := true + until not has_more - loop + loop + next + if actual.is_equal (j_string) then + has_more := false + elseif actual.is_equal ('%H') then next - if actual.is_equal (j_string) then - has_more:=false - elseif actual.is_equal ('%H') then - next - if actual.is_equal ('u') then - create l_unicode.make_from_string ("\u") - l_unicode.append (read_unicode) - if is_a_valid_unicode(l_unicode) then - l_json_string.append (l_unicode) - else - has_more:=false - is_parsed:=false - current_errors.append("Input String is not well formed JSON, expected a Unicode value, found [" + actual.out + " ] %N") - end - elseif (not special_characters.has (actual) and not special_controls.has (actual)) or actual.is_equal ('%N') then - has_more:=false - is_parsed:=false - current_errors.append("Input String is not well formed JSON, found [" + actual.out + " ] %N") - + if actual.is_equal ('u') then + create l_unicode.make_from_string ("\u") + l_unicode.append (read_unicode) + if is_a_valid_unicode (l_unicode) then + l_json_string.append (l_unicode) else - l_json_string.append ("\") - l_json_string.append (actual.out) - + has_more := false + is_parsed := false + current_errors.append ("Input String is not well formed JSON, expected a Unicode value, found [" + actual.out + " ] %N") end + elseif (not special_characters.has (actual) and not special_controls.has (actual)) or actual.is_equal ('%N') then + has_more := false + is_parsed := false + current_errors.append ("Input String is not well formed JSON, found [" + actual.out + " ] %N") else - if special_characters.has (actual) and not actual.is_equal ('/') then - has_more:=false - is_parsed:=false - current_errors.append("Input String is not well formed JSON, found [" + actual.out + " ] %N") - else - l_json_string.append (actual.out) - end + l_json_string.append ("\") + l_json_string.append (actual.out) + + end + + else + if special_characters.has (actual) and not actual.is_equal ('/') then + has_more := false + is_parsed := false + current_errors.append ("Input String is not well formed JSON, found [" + actual.out + " ] %N") + else + l_json_string.append (actual.out) end end - create Result.make_json (l_json_string) - else - Result := void - end + end + create Result.make_json (l_json_string) + else + Result := void end + end - parse_array:JSON_ARRAY is + parse_array: JSON_ARRAY is -- array -- [] -- [elements [,]] - local - flag:BOOLEAN - l_value:JSON_VALUE - do - create Result.make_array - --check if is an empty array [] - next - skip_withe_spaces - if actual.is_equal (j_array_close) then - --is an empty array - else - previous - from - flag:=true - until - not flag - loop - next - skip_withe_spaces - l_value := parse - if is_parsed then - Result.add (l_value) - next - skip_withe_spaces - if not actual.is_equal (j_array_close) and not actual.is_equal (',')then - flag:=false - is_parsed:=false - current_errors.append("Array is not well formed JSON, found [" + actual.out + " ] %N") - elseif actual.is_equal (j_array_close) then - flag:= false - end - else - flag:=false - current_errors.append("Array is not well formed JSON, found [" + actual.out + " ] %N") - end - end - end - end - - parse_number:JSON_NUMBER is - -- - local - sb:STRING - flag:BOOLEAN - is_integer:BOOLEAN - do - create sb.make_empty - sb.append (actual.out) - - from - flag:=true - until not flag + local + flag: BOOLEAN + l_value: JSON_VALUE + do + create Result.make_array + --check if is an empty array [] + next + skip_withe_spaces + if actual.is_equal (j_array_close) then + --is an empty array + else + previous + from + flag := true + until + not flag loop next - if not has_next or close_tokens.has (actual) or actual.is_equal (',') - or actual.is_equal ('%N') or actual.is_equal ('%R') then - flag:=false - previous - else - sb.append (actual.out) - end - end - - if is_a_valid_number(sb) then - if sb.is_integer then - create Result.make_integer (sb.to_integer) - is_integer:=true; - elseif sb.is_double and not is_integer then - create Result.make_real (sb.to_double) - end - else - is_parsed:=false - current_errors.append("Expected a number, found: [ " + sb + " ]") - end - end - - - - is_null:BOOLEAN is - -- - local - l_null:STRING - l_string:STRING - do - l_null:="null" - l_string:=json_substring (index,index + l_null.count - 1) - if l_string.is_equal (l_null) then - Result := true - end - end - - is_false:BOOLEAN is - -- - local - l_false:STRING - l_string:STRING - do - l_false:="false" - l_string:=json_substring (index,index + l_false.count - 1) - if l_string.is_equal (l_false) then - Result := true - end - end - - is_true:BOOLEAN is - -- - local - l_true:STRING - l_string:STRING - do - l_true:="true" - l_string:=json_substring (index,index + l_true.count - 1) - if l_string.is_equal (l_true) then - Result := true - end - end - - read_unicode:STRING is - -- - local - i:INTEGER - do - create Result.make_empty - from - i:=1 - until i > 4 or not has_next - - loop - next - Result.append(actual.out) - i:= i + 1 - end - end - -feature {NONE} - - is_a_valid_number(a_number:STRING):BOOLEAN is - -- is 'a_number' a valid number based on this regular expression - -- "-?(?:0|[1-9]\d+)(?:\.\d+)?(?:[eE][+-]?\d+)?\b"? - local - case_mapping: RX_CASE_MAPPING - word_set: RX_CHARACTER_SET - regexp: RX_PCRE_REGULAR_EXPRESSION - number_regex:STRING - l_number:STRING - do - create regexp.make - create word_set.make_empty - word_set.add_string ("0123456789.eE+-") - regexp.set_word_set (word_set) - number_regex:="-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?\b" - regexp.compile(number_regex) - if regexp.matches (a_number) then - a_number.right_adjust - if a_number.is_equal(regexp.captured_substring (0)) then - Result := true - end - end - end - - is_a_valid_unicode(a_unicode:STRING):BOOLEAN is - -- is 'a_unicode' a valid unicode based on this regular expression - -- "\\u[0-9a-fA-F]{4}" - local - case_mapping: RX_CASE_MAPPING - word_set: RX_CHARACTER_SET - regexp: RX_PCRE_REGULAR_EXPRESSION - unicode_regex:STRING - do - create regexp.make - unicode_regex:="\\u[0-9a-fA-F]{4}" - regexp.compile(unicode_regex) - if regexp.matches (a_unicode) then - Result := true - check - is_valid: a_unicode.is_equal(regexp.captured_substring (0)) - end - end - end - - - - extra_elements:BOOLEAN is - --has more elements? - local - l_string:STRING - do - - if has_next then - next - end - from - until not actual.is_space or not actual.is_equal ('%R') or - not actual.is_equal ('%U') or not actual.is_equal ('%T') - or not actual.is_equal ('%N') or not has_next - loop + skip_withe_spaces + l_value := parse + if is_parsed then + Result.add (l_value) next + skip_withe_spaces + if not actual.is_equal (j_array_close) and not actual.is_equal (',')then + flag := false + is_parsed := false + current_errors.append ("Array is not well formed JSON, found [" + actual.out + " ] %N") + elseif actual.is_equal (j_array_close) then + flag := false + end + else + flag := false + current_errors.append ("Array is not well formed JSON, found [" + actual.out + " ] %N") end - - if has_next then - Result:=True - end - end + end + end + + parse_number: JSON_NUMBER is + -- + local + sb: STRING + flag: BOOLEAN + is_integer: BOOLEAN + do + create sb.make_empty + sb.append (actual.out) + + from + flag := true + until not flag + loop + next + if not has_next or close_tokens.has (actual) or actual.is_equal (',') + or actual.is_equal ('%N') or actual.is_equal ('%R') then + flag := false + previous + else + sb.append (actual.out) + end + end + + if is_a_valid_number (sb) then + if sb.is_integer then + create Result.make_integer (sb.to_integer) + is_integer := true + elseif sb.is_double and not is_integer then + create Result.make_real (sb.to_double) + end + else + is_parsed := false + current_errors.append ("Expected a number, found: [ " + sb + " ]") + end + end + + is_null: BOOLEAN is + -- + local + l_null: STRING + l_string: STRING + do + l_null := "null" + l_string := json_substring (index,index + l_null.count - 1) + if l_string.is_equal (l_null) then + Result := true + end + end + + is_false: BOOLEAN is + -- + local + l_false: STRING + l_string: STRING + do + l_false := "false" + l_string := json_substring (index,index + l_false.count - 1) + if l_string.is_equal (l_false) then + Result := true + end + end + + is_true: BOOLEAN is + -- + local + l_true: STRING + l_string: STRING + do + l_true := "true" + l_string := json_substring (index,index + l_true.count - 1) + if l_string.is_equal (l_true) then + Result := true + end + end + + read_unicode: STRING is + -- + local + i: INTEGER + do + create Result.make_empty + from + i := 1 + until i > 4 or not has_next + + loop + next + Result.append (actual.out) + i := i + 1 + end + end + + +feature {NONE} -- Implementation + + is_a_valid_number (a_number: STRING): BOOLEAN is + -- is 'a_number' a valid number based on this regular expression + -- "-?(?: 0|[1-9]\d+)(?: \.\d+)?(?: [eE][+-]?\d+)?\b"? + local + word_set: RX_CHARACTER_SET + regexp: RX_PCRE_REGULAR_EXPRESSION + number_regex: STRING + do + create regexp.make + create word_set.make_empty + word_set.add_string ("0123456789.eE+-") + regexp.set_word_set (word_set) + number_regex := "-?(?: 0|[1-9]\d*)(?: \.\d+)?(?: [eE][+-]?\d+)?\b" + regexp.compile (number_regex) + if regexp.matches (a_number) then + a_number.right_adjust + if a_number.is_equal (regexp.captured_substring (0)) then + Result := true + end + end + end + + is_a_valid_unicode (a_unicode: STRING): BOOLEAN is + -- is 'a_unicode' a valid unicode based on this regular expression + -- "\\u[0-9a-fA-F]{4}" + local + regexp: RX_PCRE_REGULAR_EXPRESSION + unicode_regex: STRING + do + create regexp.make + unicode_regex := "\\u[0-9a-fA-F]{4}" + regexp.compile (unicode_regex) + if regexp.matches (a_unicode) then + Result := true + check + is_valid: a_unicode.is_equal (regexp.captured_substring (0)) + end + end + end + + extra_elements: BOOLEAN is + --has more elements? + do + + if has_next then + next + end + from + until + not actual.is_space or not actual.is_equal ('%R') or + not actual.is_equal ('%U') or not actual.is_equal ('%T') + or not actual.is_equal ('%N') or not has_next + loop + next + end + + if has_next then + Result := True + end + + end end