indexing
	description: "Interface with the Lexical Library classes"
	status: "See notice at end of class"
	date: "$Date$"
	revision: "$Revision$"

deferred class interface
	L_INTERFACE

feature -- Initialization

	build (doc: INPUT)
			-- Create lexical analyzer and set doc
			-- to be the input document.
		require
			document_exists: doc /= void

	initialize
			-- Set up attributes of analyzer.
			-- (from LEX_BUILDER)
		ensure -- from LEX_BUILDER
			initialized

	metalex_make
			-- Set up the analyzer.
			-- (from LEX_BUILDER)
		ensure -- from LEX_BUILDER
			last_character_set: last_character_code = last_ascii

	pdfa_make (n, i: INTEGER)
			-- Make a PDFA with n states, and i + 1 inputs.
			-- (from PDFA)

	array_make (min_index, max_index: INTEGER)
			-- Allocate array; set index interval to
			-- min_index .. max_index; set all values to default.
			-- (Make array empty if min_index = max_index + 1).
			-- (from ARRAY)
		require -- from ARRAY
			valid_bounds: min_index <= max_index + 1
		ensure -- from ARRAY
			lower_set: lower = min_index
			upper_set: upper = max_index
			items_set: all_default

	make_analyzer
			-- Create analyzer (if Void) and initialize it.
			-- (from METALEX)
		require -- from METALEX
			not_initialized: not initialized
		ensure -- from METALEX
			initialized
			analyzer_created: analyzer /= void
			lexical_frozen

	make_extended (char_code: INTEGER)
			-- Set up the analyzer with char_code as 'last_character_code'.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			valid_char_code: char_code > 0
		ensure -- from LEX_BUILDER
			last_character_set: last_character_code = char_code

	make_from_array (a: ARRAY [LINKED_LIST [INTEGER]])
			-- Initialize from the items of a.
			-- (Useful in proper descendants of class ARRAY,
			-- to initialize an array-like object from a manifest array.)
			-- (from ARRAY)
		require -- from ARRAY
			array_exists: a /= void

	obtain_analyzer
			-- Build lexical analyzer.
		ensure
			analyzer /= void
	
feature -- Access

	Ack: INTEGER is 6
			-- (from ASCII)

	Ampersand: INTEGER is 38
			-- (from ASCII)

	analyzer: LEXICAL
			-- The lexical analyzer built so far
			-- (from LEX_BUILDER)

	area: SPECIAL [LINKED_LIST [INTEGER]]
			-- Special data zone
			-- (from TO_SPECIAL)

	Back_space: INTEGER is 8
			-- (from ASCII)

	Backslash: INTEGER is 92
			-- (from ASCII)

	Bar: INTEGER is 124
			-- (from ASCII)

	Bel: INTEGER is 7
			-- (from ASCII)

	Blank: INTEGER is 32
			-- (from ASCII)

	Break: INTEGER is -7
			-- (from ASCII)

	Bs: INTEGER is 8
			-- (from ASCII)

	Buf_overflow: INTEGER is -9
			-- (from ASCII)

	Can: INTEGER is 24
			-- (from ASCII)

	Carriage_return: INTEGER is 13
			-- (from ASCII)

	Case_diff: INTEGER is 32
			-- Lower_a - Upper_a
			-- (from ASCII)

	case_sensitive: BOOLEAN
			-- Will future tools be case-sensitive?
			-- (from LEX_BUILDER)

	categories_table: ARRAY [INTEGER]
			-- Table of category numbers for each input
			-- (from LEX_BUILDER)

	Character_set_size: INTEGER is 128
			-- (from ASCII)

	Circumflex: INTEGER is 94
			-- (from ASCII)

	Closing_brace: INTEGER is 125
			-- (from ASCII)

	Colon: INTEGER is 58
			-- (from ASCII)

	Comma: INTEGER is 44
			-- (from ASCII)

	Commercial_at: INTEGER is 64
			-- (from ASCII)

	Cr: INTEGER is 13
			-- (from ASCII)

	Ctrl_a: INTEGER is 1
			-- (from ASCII)

	Ctrl_b: INTEGER is 2
			-- (from ASCII)

	Ctrl_backslash: INTEGER is 28
			-- (from ASCII)

	Ctrl_c: INTEGER is 3
			-- (from ASCII)

	Ctrl_circumflex: INTEGER is 30
			-- (from ASCII)

	Ctrl_d: INTEGER is 4
			-- (from ASCII)

	Ctrl_e: INTEGER is 5
			-- (from ASCII)

	Ctrl_f: INTEGER is 6
			-- (from ASCII)

	Ctrl_g: INTEGER is 7
			-- (from ASCII)

	Ctrl_h: INTEGER is 8
			-- (from ASCII)

	Ctrl_i: INTEGER is 9
			-- (from ASCII)

	Ctrl_j: INTEGER is 10
			-- (from ASCII)

	Ctrl_k: INTEGER is 11
			-- (from ASCII)

	Ctrl_l: INTEGER is 12
			-- (from ASCII)

	Ctrl_lbracket: INTEGER is 27
			-- (from ASCII)

	Ctrl_m: INTEGER is 13
			-- (from ASCII)

	Ctrl_n: INTEGER is 14
			-- (from ASCII)

	Ctrl_o: INTEGER is 15
			-- (from ASCII)

	Ctrl_p: INTEGER is 16
			-- (from ASCII)

	Ctrl_q: INTEGER is 17
			-- (from ASCII)

	Ctrl_questmark: INTEGER is 127
			-- (from ASCII)

	Ctrl_r: INTEGER is 18
			-- (from ASCII)

	Ctrl_rbracket: INTEGER is 29
			-- (from ASCII)

	Ctrl_s: INTEGER is 19
			-- (from ASCII)

	Ctrl_t: INTEGER is 20
			-- (from ASCII)

	Ctrl_u: INTEGER is 21
			-- (from ASCII)

	Ctrl_underlined: INTEGER is 31
			-- (from ASCII)

	Ctrl_v: INTEGER is 22
			-- (from ASCII)

	Ctrl_w: INTEGER is 23
			-- (from ASCII)

	Ctrl_x: INTEGER is 24
			-- (from ASCII)

	Ctrl_y: INTEGER is 25
			-- (from ASCII)

	Ctrl_z: INTEGER is 26
			-- (from ASCII)

	Dc1: INTEGER is 17
			-- (from ASCII)

	Dc2: INTEGER is 18
			-- (from ASCII)

	Dc3: INTEGER is 19
			-- (from ASCII)

	Dc4: INTEGER is 20
			-- (from ASCII)

	Del: INTEGER is 127
			-- (from ASCII)

	dfa: FIXED_DFA
			-- DFA built by routine construct_dfa,
			-- which recognizes the same language.
			-- (from NDFA)

	Dle: INTEGER is 16
			-- (from ASCII)

	Dollar: INTEGER is 36
			-- (from ASCII)

	Dot: INTEGER is 46
			-- (from ASCII)

	Doublequote: INTEGER is 34
			-- (from ASCII)

	Down_arrow: INTEGER is -3
			-- (from ASCII)

	Eight: INTEGER is 56
			-- (from ASCII)

	Em: INTEGER is 25
			-- (from ASCII)

	Enq: INTEGER is 5
			-- (from ASCII)

	entry (i: INTEGER): LINKED_LIST [INTEGER]
			-- Entry at index i, if in index interval
			-- (from ARRAY)
		require -- from ARRAY
			valid_key: valid_index (i)

	Eot: INTEGER is 4
			-- (from ASCII)

	Equal_sign: INTEGER is 61
			-- (from ASCII)

	error_list: ERROR_LIST
			-- List of error messages
			-- (from LEX_BUILDER)

	Esc: INTEGER is 27
			-- (from ASCII)

	Etb: INTEGER is 23
			-- (from ASCII)

	Etx: INTEGER is 3
			-- (from ASCII)

	Exclamation: INTEGER is 33
			-- (from ASCII)

	final_array: ARRAY [INTEGER]
			-- The final value for each state
			-- (regular expression, if any, for which it is final).
			-- (from PDFA)

	First_printable: INTEGER is 32
			-- (from ASCII)

	Five: INTEGER is 53
			-- (from ASCII)

	Four: INTEGER is 52
			-- (from ASCII)

	Fs: INTEGER is 28
			-- (from ASCII)

	Grave_accent: INTEGER is 96
			-- (from ASCII)

	Greaterthan: INTEGER is 62
			-- (from ASCII)

	greatest_input: INTEGER
			-- Greatest input used for the transitions from state
			-- to state (the smallest one is zero)
			-- (from AUTOMATON)

	Gs: INTEGER is 29
			-- (from ASCII)

	has (v: LINKED_LIST [INTEGER]): BOOLEAN
			-- Does v appear in array?
			-- (Reference or object equality,
			-- based on object_comparison.)
			-- (from ARRAY)
		ensure -- from CONTAINER
			not_found_in_empty: Result implies not is_empty

	has_letters: BOOLEAN
			-- Are there any letters among the active transitions?
			-- (from PDFA)

	Home_arrow: INTEGER is -6
			-- (from ASCII)

	Ht: INTEGER is 9
			-- (from ASCII)

	input_array: ARRAY [FIXED_INTEGER_SET]
			-- For each input, set of the states which have
			-- a transition on this input to the following state
			-- (from PDFA)

	pdfa_item (i: INTEGER): LINKED_LIST [INTEGER]
			-- Entry at index i, if in index interval
			-- Was declared in ARRAY as synonym of @.
			-- (from ARRAY)
		require -- from TABLE
			valid_key: valid_index (k)

	keyword_h_table: HASH_TABLE [INTEGER, STRING]
			-- Keyword table
			-- (from LEX_BUILDER)

	keywords_case_sensitive: BOOLEAN
			-- Will future tools be case-sensitive for keywords?
			-- (from LEX_BUILDER)

	keywords_list: LINKED_LIST [STRING]
			-- Keywords associated with current automaton.
			-- (from PDFA)

	Last_ascii: INTEGER is 127
			-- (from ASCII)

	last_character_code: INTEGER
			-- Last character code recognized by the language
			-- (from LEX_BUILDER)

	last_created_tool: INTEGER
			-- Identification number of the last
			-- regular expression put in tool_list
			-- (from LEX_BUILDER)

	Last_printable: INTEGER is 126
			-- (from ASCII)

	Lbracket: INTEGER is 91
			-- (from ASCII)

	Lcurly: INTEGER is 40
			-- (from ASCII)

	Left_arrow: INTEGER is -4
			-- (from ASCII)

	Lessthan: INTEGER is 60
			-- (from ASCII)

	Letter_layout: INTEGER is 70
			-- (from ASCII)

	lexical_frozen: BOOLEAN
			-- Has the lexical grammar been finalized?
			-- | (in other words: has the DFA been built?)
			-- (from LEX_BUILDER)

	Line_feed: INTEGER is 10
			-- (from ASCII)

	Lower_a: INTEGER is 97
			-- (from ASCII)

	Lower_b: INTEGER is 98
			-- (from ASCII)

	Lower_c: INTEGER is 99
			-- (from ASCII)

	Lower_d: INTEGER is 100
			-- (from ASCII)

	Lower_e: INTEGER is 101
			-- (from ASCII)

	Lower_f: INTEGER is 102
			-- (from ASCII)

	Lower_g: INTEGER is 103
			-- (from ASCII)

	Lower_h: INTEGER is 104
			-- (from ASCII)

	Lower_i: INTEGER is 105
			-- (from ASCII)

	Lower_j: INTEGER is 106
			-- (from ASCII)

	Lower_k: INTEGER is 107
			-- (from ASCII)

	Lower_l: INTEGER is 108
			-- (from ASCII)

	Lower_m: INTEGER is 109
			-- (from ASCII)

	Lower_n: INTEGER is 110
			-- (from ASCII)

	Lower_o: INTEGER is 111
			-- (from ASCII)

	Lower_p: INTEGER is 112
			-- (from ASCII)

	Lower_q: INTEGER is 113
			-- (from ASCII)

	Lower_r: INTEGER is 114
			-- (from ASCII)

	Lower_s: INTEGER is 115
			-- (from ASCII)

	Lower_t: INTEGER is 116
			-- (from ASCII)

	Lower_u: INTEGER is 117
			-- (from ASCII)

	Lower_v: INTEGER is 118
			-- (from ASCII)

	Lower_w: INTEGER is 119
			-- (from ASCII)

	Lower_x: INTEGER is 120
			-- (from ASCII)

	Lower_y: INTEGER is 121
			-- (from ASCII)

	Lower_z: INTEGER is 122
			-- (from ASCII)

	Minus: INTEGER is 45
			-- (from ASCII)

	Nak: INTEGER is 21
			-- (from ASCII)

	Nine: INTEGER is 57
			-- (from ASCII)

	Nl: INTEGER is 10
			-- (from ASCII)

	Np: INTEGER is 12
			-- (from ASCII)

	Nul: INTEGER is 0
			-- (from ASCII)

	Number_sign: INTEGER is 35
			-- (from ASCII)

	One: INTEGER is 49
			-- (from ASCII)

	Opening_brace: INTEGER is 123
			-- (from ASCII)

	Overflow: INTEGER is -8
			-- (from ASCII)

	Percent: INTEGER is 37
			-- (from ASCII)

	Plus: INTEGER is 43
			-- (from ASCII)

	Questmark: INTEGER is 63
			-- (from ASCII)

	Rbracket: INTEGER is 93
			-- (from ASCII)

	Rcurly: INTEGER is 41
			-- (from ASCII)

	Right_arrow: INTEGER is -5
			-- (from ASCII)

	Rs: INTEGER is 30
			-- (from ASCII)

	selected_tools: LINKED_LIST [INTEGER]
			-- Regular expressions included in the main one
			-- (from LEX_BUILDER)

	Semicolon: INTEGER is 59
			-- (from ASCII)

	Seven: INTEGER is 55
			-- (from ASCII)

	Si: INTEGER is 15
			-- (from ASCII)

	Singlequote: INTEGER is 39
			-- (from ASCII)

	Six: INTEGER is 54
			-- (from ASCII)

	Slash: INTEGER is 47
			-- (from ASCII)

	So: INTEGER is 14
			-- (from ASCII)

	Soh: INTEGER is 1
			-- (from ASCII)

	Sp: INTEGER is 32
			-- (from ASCII)

	Star: INTEGER is 42
			-- (from ASCII)

	start_number: INTEGER
			-- Unique start state used for the beginning of
			-- the automaton's operation
			-- (from AUTOMATON)

	Stx: INTEGER is 2
			-- (from ASCII)

	Sub: INTEGER is 26
			-- (from ASCII)

	Syn: INTEGER is 22
			-- (from ASCII)

	Tabulation: INTEGER is 9
			-- (from ASCII)

	Three: INTEGER is 51
			-- (from ASCII)

	Tilde: INTEGER is 126
			-- (from ASCII)

	token_type_list: LINKED_LIST [INTEGER]
			-- Token types of the selected tools.
			-- Indexed by tool numbers.
			-- (from LEX_BUILDER)

	tool_list: LINKED_LIST [PDFA]
			-- Regular expressions used as auxiliary tools
			-- (from LEX_BUILDER)

	tool_names: LINKED_LIST [STRING]
			-- Names of regular expressions in tool list
			-- (from LEX_BUILDER)

	Two: INTEGER is 50
			-- (from ASCII)

	Underlined: INTEGER is 95
			-- (from ASCII)

	Up_arrow: INTEGER is -2
			-- (from ASCII)

	Upper_a: INTEGER is 65
			-- (from ASCII)

	Upper_b: INTEGER is 66
			-- (from ASCII)

	Upper_c: INTEGER is 67
			-- (from ASCII)

	Upper_d: INTEGER is 68
			-- (from ASCII)

	Upper_e: INTEGER is 69
			-- (from ASCII)

	Upper_f: INTEGER is 70
			-- (from ASCII)

	Upper_g: INTEGER is 71
			-- (from ASCII)

	Upper_h: INTEGER is 72
			-- (from ASCII)

	Upper_i: INTEGER is 73
			-- (from ASCII)

	Upper_j: INTEGER is 74
			-- (from ASCII)

	Upper_k: INTEGER is 75
			-- (from ASCII)

	Upper_l: INTEGER is 76
			-- (from ASCII)

	Upper_m: INTEGER is 77
			-- (from ASCII)

	Upper_n: INTEGER is 78
			-- (from ASCII)

	Upper_o: INTEGER is 79
			-- (from ASCII)

	Upper_p: INTEGER is 80
			-- (from ASCII)

	Upper_q: INTEGER is 81
			-- (from ASCII)

	Upper_r: INTEGER is 82
			-- (from ASCII)

	Upper_s: INTEGER is 83
			-- (from ASCII)

	Upper_t: INTEGER is 84
			-- (from ASCII)

	Upper_u: INTEGER is 85
			-- (from ASCII)

	Upper_v: INTEGER is 86
			-- (from ASCII)

	Upper_w: INTEGER is 87
			-- (from ASCII)

	Upper_x: INTEGER is 88
			-- (from ASCII)

	Upper_y: INTEGER is 89
			-- (from ASCII)

	Upper_z: INTEGER is 90
			-- (from ASCII)

	Us: INTEGER is 31
			-- (from ASCII)

	Vt: INTEGER is 11
			-- (from ASCII)

	Zero: INTEGER is 48
			-- (from ASCII)

	infix "@" (i: INTEGER): LINKED_LIST [INTEGER]
			-- Entry at index i, if in index interval
			-- Was declared in ARRAY as synonym of item.
			-- (from ARRAY)
		require -- from TABLE
			valid_key: valid_index (k)
	
feature -- Measurement

	additional_space: INTEGER
			-- Proposed number of additional items
			-- (from RESIZABLE)
		ensure -- from RESIZABLE
			at_least_one: Result >= 1

	capacity: INTEGER
			-- Number of available indices
			-- Was declared in ARRAY as synonym of count.
			-- (from ARRAY)
		ensure then -- from ARRAY
			consistent_with_bounds: Result = upper - lower + 1

	count: INTEGER
			-- Number of available indices
			-- Was declared in ARRAY as synonym of capacity.
			-- (from ARRAY)
		ensure then -- from ARRAY
			consistent_with_bounds: Result = upper - lower + 1

	Growth_percentage: INTEGER is 50
			-- Percentage by which structure will grow automatically
			-- (from RESIZABLE)

	index_set: INTEGER_INTERVAL
			-- Range of acceptable indexes
			-- (from ARRAY)
		ensure -- from INDEXABLE
			not_void: Result /= void
		ensure then -- from ARRAY
			same_count: Result.count = count
			same_bounds: ((Result.lower = lower) and (Result.upper = upper))

	lower: INTEGER
			-- Minimum index
			-- (from ARRAY)

	Minimal_increase: INTEGER is 5
			-- Minimal number of additional items
			-- (from RESIZABLE)

	nb_states: INTEGER
			-- Number of states in the automaton
			-- (from AUTOMATON)

	occurrences (v: LINKED_LIST [INTEGER]): INTEGER
			-- Number of times v appears in structure
			-- (from ARRAY)
		ensure -- from BAG
			non_negative_occurrences: Result >= 0

	upper: INTEGER
			-- Maximum index
			-- (from ARRAY)
	
feature -- Comparison

	is_equal (other: like Current): BOOLEAN
			-- Is array made of the same items as other?
			-- (from ARRAY)
		require -- from ANY
			other_not_void: other /= void
		ensure -- from ANY
			symmetric: Result implies other.is_equal (Current)
			consistent: standard_is_equal (other) implies Result
	
feature -- Status report

	all_default: BOOLEAN
			-- Are all items set to default values?
			-- (from ARRAY)
		ensure -- from ARRAY
			definition: Result = (count = 0 or else ((pdfa_item (upper) = void or else pdfa_item (upper) = pdfa_item (upper).default) and subarray (lower, upper - 1).all_default))

	changeable_comparison_criterion: BOOLEAN
			-- May object_comparison be changed?
			-- (Answer: yes by default.)
			-- (from CONTAINER)

	extendible: BOOLEAN
			-- May items be added?
			-- (Answer: no, although array may be resized.)
			-- (from ARRAY)

	full: BOOLEAN
			-- Is structure filled to capacity? (Answer: yes)
			-- (from ARRAY)

	is_empty: BOOLEAN
			-- Is structure empty?
			-- (from FINITE)

	is_inserted (v: LINKED_LIST [INTEGER]): BOOLEAN
			-- Has v been inserted by the most recent insertion?
			-- (By default, the value returned is equivalent to calling
			-- `has (v)'. However, descendants might be able to provide more
			-- efficient implementations.)
			-- (from COLLECTION)

	object_comparison: BOOLEAN
			-- Must search operations use equal rather than =
			-- for comparing references? (Default: no, use =.)
			-- (from CONTAINER)

	prunable: BOOLEAN
			-- May items be removed? (Answer: no.)
			-- (from ARRAY)

	resizable: BOOLEAN
			-- May capacity be changed? (Answer: yes.)
			-- (from RESIZABLE)

	same_items (other: like Current): BOOLEAN
			-- Do other and Current have same items?
			-- (from ARRAY)
		require -- from ARRAY
			other_not_void: other /= void
		ensure -- from ARRAY
			definition: Result = ((count = other.count) and then (count = 0 or else (pdfa_item (upper) = other.pdfa_item (other.upper) and subarray (lower, upper - 1).same_items (other.subarray (other.lower, other.upper - 1)))))

	valid_index (i: INTEGER): BOOLEAN
			-- Is i within the bounds of the array?
			-- (from ARRAY)
		ensure then -- from INDEXABLE
			only_if_in_index_set: Result implies ((i >= index_set.lower) and (i <= index_set.upper))

	valid_index_set: BOOLEAN
			-- (from ARRAY)
	
feature -- Status setting

	compare_objects
			-- Ensure that future search operations will use equal
			-- rather than = for comparing references.
			-- (from CONTAINER)
		require -- from CONTAINER
			changeable_comparison_criterion
		ensure -- from CONTAINER
			object_comparison

	compare_references
			-- Ensure that future search operations will use =
			-- rather than equal for comparing references.
			-- (from CONTAINER)
		require -- from CONTAINER
			changeable_comparison_criterion
		ensure -- from CONTAINER
			reference_comparison: not object_comparison

	distinguish_case
			-- Make letter case significant in future tools.
			-- Default is ignore case.
			-- (from LEX_BUILDER)
		ensure -- from LEX_BUILDER
			case_sensitive

	ignore_case
			-- Make letter case not significant in future tools.
			-- This is the default.
			-- (from LEX_BUILDER)
		ensure -- from LEX_BUILDER
			not case_sensitive

	keywords_distinguish_case
			-- Make letter case not significant for keywords
			-- in future tools.
			-- Default is ignore case.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			no_tool_built: tool_list.is_empty
		ensure -- from LEX_BUILDER
			keywords_case_sensitive

	keywords_ignore_case
			-- Make letter case not significant for keywords
			-- in future tools.
			-- This is the default.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			no_tools_built: tool_list = void or else tool_list.is_empty
		ensure -- from LEX_BUILDER
			not keywords_case_sensitive

	set_e_transition (source, target: INTEGER)
			-- Set epsilon transition from source to target.
			-- (from PDFA)
		require -- from NDFA
			source_in_automaton: source >= 1 and source <= nb_states
			target_in_automaton: target >= 1 and target <= nb_states

	set_final (s, r: INTEGER)
			-- Make s the final state of regular expression r.
			-- (from PDFA)

	set_letters
			-- Direct the active transitions to include letters.
			-- (from PDFA)

	set_start (n: INTEGER)
			-- Select state n as the starting state.
			-- (from AUTOMATON)
		require -- from AUTOMATON
			no_other_start: start_number = 0 or start_number = n
			is_in_automaton: n <= nb_states and n >= 1

	set_transition (source, input_doc, target: INTEGER)
			-- Set transition from source to target on input_doc.
			-- (from PDFA)
		require -- from  AUTOMATON
			True
		require else -- from NDFA
			source_in_automaton: source >= 1 and source <= nb_states
			target_in_automaton: target >= 1 and target <= nb_states
			possible_input_doc: input_doc >= 0 and input_doc <= greatest_input
		require else -- from PDFA
			source_in_automaton: source >= 1 and source <= nb_states
			target_in_automaton: target >= 1 and target <= nb_states
			possible_input_doc: input_doc >= 0 and input_doc <= greatest_input
			good_successor: target = source + 1
	
feature -- Element change

	add_keyword (word: STRING)
			-- Insert word in the keyword list.
			-- (from PDFA)

	add_word (s: STRING; n: INTEGER)
			-- Record the word s and
			-- associate it with token type n.
			-- (from METALEX)
		require -- from METALEX
			s_not_void: s /= void
			s_not_empty: s.capacity >= 1

	any_character
			-- Create regular expression $. matching all characters.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen

	any_printable
			-- Create regular expression $P matching all
			-- printable characters.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen

	append (p, s: INTEGER)
			-- Create regular expression ps:
			-- s appended to p.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			p_in_tool: p >= 1 and p <= last_created_tool
			s_in_tool: s >= 1 and s <= last_created_tool

	append_optional (p, s: INTEGER)
			-- Create regular expression p[s]:
			-- s optionally appended to p.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			p_in_tool: p >= 1 and p <= last_created_tool
			s_in_tool: s >= 1 and s <= last_created_tool

	associate (t, n: INTEGER)
			-- Associate the t-th tool with token type n.
			-- If this routine is not used, the default value is t.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			t_selected: selected_tools.has (t)
			n_not_zero: n /= 0
			n_not_minus_one: n /= - 1

	build_dollar_any
			-- Build $., matching any character.
			-- (from HIGH_BUILDER)
		require -- from HIGH_BUILDER
			good_first_character: description.item (cursor) = '.'

	build_dollar_b
			-- Build $B, matching any number of break characters:
			-- blank, new-line, tabulation, carriage-return.
			-- (from HIGH_BUILDER)

	build_dollar_n
			-- Build $N, matching natural integer constants.
			-- +('0'..'9')
			-- (from HIGH_BUILDER)

	build_dollar_p
			-- Build $P, matching any printable character.
			-- (from HIGH_BUILDER)
		require -- from HIGH_BUILDER
			good_first_character: description.item (cursor) = 'P'

	build_dollar_r
			-- Build $R, matching floating point constants.
			-- ['+' | '-'] +('0'..'9') '.' *('0'..'9') ['e' | 'E' ['+' | '-']
			-- +('0'..'9')]
			-- (from HIGH_BUILDER)

	build_dollar_z
			-- Build $Z, matching possibly signed integer constants.
			-- ['+' | '-'] +('0'..'9')
			-- (from HIGH_BUILDER)

	case_insensitive (c: INTEGER)
			-- Create regular expression ~(c):
			-- like c, but case-insensitive.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			z_possible: last_character_code >= lower_z
			c_in_tool: c >= 1 and c <= last_created_tool

	difference (r: INTEGER; c: CHARACTER)
			-- Create regular expression representing
			-- the difference r - c.
			-- r must be a simple category, such as a..z,
			-- or a union of simple categories,
			-- such as a..z | 0..9.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			r_exists: r >= 1 and r <= last_created_tool
			r_simple_category: tool_list.i_th (r).nb_states = 2

	enter (v: like pdfa_item; i: INTEGER)
			-- Replace i-th entry, if in index interval, by v.
			-- (from ARRAY)
		require -- from ARRAY
			valid_key: valid_index (i)

	fill (other: CONTAINER [LINKED_LIST [INTEGER]])
			-- Fill with as many items of other as possible.
			-- The representations of other and current structure
			-- need not be the same.
			-- (from COLLECTION)
		require -- from COLLECTION
			other_not_void: other /= void
			extendible

	force (v: like pdfa_item; i: INTEGER)
			-- Assign item v to i-th entry.
			-- Always applicable: resize the array if i falls out of
			-- currently defined bounds; preserve existing items.
			-- (from ARRAY)
		ensure -- from ARRAY
			inserted: pdfa_item (i) = v
			higher_count: count >= old count

	include (fa: PDFA; shift: INTEGER)
			-- Copy fa with state numbers shifted
			-- by shift positions in the transitions.
			-- Do not preserve the final values.
			-- (from PDFA)
		require -- from PDFA
			same_inputs: greatest_input = fa.greatest_input
			nb_states_large_enough: nb_states >= fa.nb_states + shift

	interval (b, e: CHARACTER)
			-- Create regular expression b..e, or b if b = e.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_built: not lexical_frozen
			e_code_small_enough: e.code <= last_character_code
			b_code_large_enough: b.code >= 0
			b_before_e: b.code <= e.code

	iteration (c: INTEGER)
			-- Create regular expression *(c): zero or more
			-- consecutive occurrences of c.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			c_in_tool: c >= 1 and c <= last_created_tool

	iteration1 (c: INTEGER)
			-- Create regular expression +(c): one or more
			-- consecutive occurrences of c.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			c_in_tool: c >= 1 and c <= last_created_tool

	iteration_n (n, c: INTEGER)
			-- Create regular expression n(c):
			-- exactly n consecutive occurrences of c.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			n_large_enough: n > 0
			c_in_tool: c >= 1 and c <= last_created_tool

	optional (c: INTEGER)
			-- Create regular expression [c]:
			-- optional c.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			c_in_tool: c >= 1 and c <= last_created_tool

	prepend_optional (p, s: INTEGER)
			-- Create regular expression [p]s:
			-- s appended to optional p.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			p_in_tool: p >= 1 and p <= last_created_tool
			s_in_tool: s >= 1 and s <= last_created_tool

	pdfa_put (v: like pdfa_item; i: INTEGER)
			-- Replace i-th entry, if in index interval, by v.
			-- (from ARRAY)
		require -- from TABLE
			valid_key: valid_index (k)
		ensure then -- from INDEXABLE
			insertion_done: pdfa_item (k) = v

	put_expression (s: STRING; n: INTEGER; c: STRING)
			-- Record the regular expression described by s
			-- and associate it with token type n and name c.
			-- (from METALEX)
		require -- from METALEX
			source_long_enough: s.capacity > 0

	put_keyword (s: STRING; exp: INTEGER)
			-- Declare s as a keyword described by
			-- the regular expression of code exp.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			exp_selected: token_type_list /= void and then token_type_list.has (exp)

	put_nameless_expression (s: STRING; n: INTEGER)
			-- Record the regular expression described
			-- by s, and associate it with token type n.
			-- (from HIGH_BUILDER)
		require -- from HIGH_BUILDER
			source_long_enough: s.count > 0

	recognize (s: STRING): INTEGER
			-- Token_type of s; 0 if not recognized
			-- (from LEX_BUILDER)

	remove_case_sensitiveness
			-- Remove case sensitiveness.
			-- (from PDFA)
		require -- from PDFA
			z_possible: greatest_input >= lower_z

	select_tool (i: INTEGER)
			-- Select the i_th tool for inclusion in the main
			-- regular expression.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			i_exist: i > 0 and i <= last_created_tool
		ensure -- from LEX_BUILDER
			i_selected: selected_tools.has (i)

	set_word (word: STRING)
			-- Create regular expression for word:
			-- synonym for concatenation (w o r d).
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			word_not_empty: word.count >= 1

	subcopy (other: like Current; start_pos, end_pos, index_pos: INTEGER)
			-- Copy items of other within bounds start_pos and end_pos
			-- to current array starting at index index_pos.
			-- (from ARRAY)
		require -- from ARRAY
			other_not_void: other /= void
			valid_start_pos: other.valid_index (start_pos)
			valid_end_pos: other.valid_index (end_pos)
			valid_bounds: (start_pos <= end_pos) or (start_pos = end_pos + 1)
			valid_index_pos: valid_index (index_pos)
			enough_space: (upper - index_pos) >= (end_pos - start_pos)

	union (a, b: INTEGER)
			-- Create regular expression for the multiple union
			-- a | a+1 | .. | b: matches any occurrence of
			-- a, or a+1, .., or b.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			a_not_too_small: a >= 1
			b_not_too_large: b <= last_created_tool
			a_smaller_than_b: a <= b

	union2 (a, b: INTEGER)
			-- Create regular expression a | b: union of
			-- a and b (matches an occurrence of a or b)).
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			a_in_tool: a >= 1 and a <= last_created_tool
			b_in_tool: b >= 1 and b <= last_created_tool

	up_to (word: STRING)
			-- Create regular expression ->"word", which is a
			-- set of any number of any characters ended by "word".
			-- Example: "/* C comment */" matches (->"*/").
			-- The difference between (+$. '*' '/') and
			-- (->"*/") is that "*/..*/..*/" matches
			-- the first but not the second.
			-- The difference between
			-- ((($.-'*') | ('*'($.-'/'))) +('*' '/') )
			-- and "(->"*/")" is that "..**/" matches
			-- the second but not the first.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			word_not_empty: word.count > 0
			not_frozen: not lexical_frozen
	
feature -- Removal

	clear_all
			-- Reset all items to default values.
			-- (from ARRAY)
		ensure -- from ARRAY
			stable_lower: lower = old lower
			stable_upper: upper = old upper
			default_items: all_default

	delete_transition (source, input_doc, target: INTEGER)
			-- Delete transition from source to target on input_doc.
			-- (from PDFA)
		require -- from NDFA
			source_in_automaton: source >= 1 and source <= nb_states
			target_in_automaton: target >= 1 and target <= nb_states
			possible_input_doc: input_doc >= 0 and input_doc <= greatest_input
		require else -- from PDFA
			source_in_automaton: source >= 1 and source <= nb_states
			target_in_automaton: target >= 1 and target <= nb_states
			possible_input_doc: input_doc >= 0 and input_doc <= greatest_input
			good_successor: target = source + 1

	discard_items
			-- Reset all items to default values with reallocation.
			-- (from ARRAY)
		ensure -- from ARRAY
			default_items: all_default

	prune_all (v: LINKED_LIST [INTEGER])
			-- Remove all occurrences of v.
			-- (Reference or object equality,
			-- based on object_comparison.)
			-- (from COLLECTION)
		require -- from COLLECTION
			prunable
		ensure -- from COLLECTION
			no_more_occurrences: not has (v)

	remove
			-- Remove the last regular expression
			-- from the tool list.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			not_frozen: not lexical_frozen
			at_least_one_regular: last_created_tool >= 1
	
feature -- Resizing

	automatic_grow
			-- Change the capacity to accommodate at least
			-- Growth_percentage more items.
			-- (from RESIZABLE)
		ensure -- from RESIZABLE
			increased_capacity: capacity >= old capacity + old capacity * growth_percentage // 100

	grow (i: INTEGER)
			-- Change the capacity to at least i.
			-- (from ARRAY)
		ensure -- from RESIZABLE
			new_capacity: capacity >= i

	resize (min_index, max_index: INTEGER)
			-- Rearrange array so that it can accommodate
			-- indices down to min_index and up to max_index.
			-- Do not lose any previously entered item.
			-- (from ARRAY)
		require -- from ARRAY
			good_indices: min_index <= max_index
		ensure -- from ARRAY
			no_low_lost: lower = min_index or else lower = old lower
			no_high_lost: upper = max_index or else upper = old upper
	
feature -- Transformation

	construct_dfa
			-- Create an equivalent deterministic finite automaton.
			-- (from NDFA)
		require -- from NDFA
			start_number_designated: start_number > 0
	
feature -- Conversion

	linear_representation: LINEAR [LINKED_LIST [INTEGER]]
			-- Representation as a linear structure
			-- (from ARRAY)
	
feature -- Duplication

	copy (other: like Current)
			-- Reinitialize by copying all the items of other.
			-- (This is also used by clone.)
			-- (from ARRAY)
		require -- from ANY
			other_not_void: other /= void
			type_identity: same_type (other)
		ensure -- from ANY
			is_equal: is_equal (other)
		ensure then -- from ARRAY
			equal_areas: area.is_equal (other.area)

	subarray (start_pos, end_pos: INTEGER): like Current
			-- Array made of items of current array within
			-- bounds start_pos and end_pos.
			-- (from ARRAY)
		require -- from ARRAY
			valid_start_pos: valid_index (start_pos)
			valid_end_pos: valid_index (end_pos)
			valid_bounds: (start_pos <= end_pos) or (start_pos = end_pos + 1)
		ensure -- from ARRAY
			lower: Result.lower = start_pos
			upper: Result.upper = end_pos
	
feature -- Implementation

	description: STRING
			-- Description of the regular expression
			-- (from HIGH_BUILDER)

	initialized: BOOLEAN
			-- Is analyzer initialized?
			-- (from LEX_BUILDER)
	
feature -- Input

	No_token: INTEGER is 0
			-- (from METALEX)

	read_grammar (token_file_name: STRING)
			-- Create lexical analyzer for grammar in file of name
			-- token_file_name. File structure:
			-- One or more lines of the form
			-- name  regular_expression
			-- then a line beginning with two dashes --
			-- then zero or more lines containing one keyword each.
			-- (from METALEX)
		ensure -- from METALEX
			analyzer_exists: analyzer /= void
	
feature  -- Input

	retrieve_analyzer (file_name: STRING)
			-- Retrieve analyzer from file named file_name.
			-- (from LEX_BUILDER)
	
feature  -- Output

	store_analyzer (file_name: STRING)
			-- Store analyzer in file named file_name.
			-- (from LEX_BUILDER)
		require -- from LEX_BUILDER
			initialized: initialized
	
feature -- Output

	trace
			-- Output an internal representation
			-- of the current automaton.
			-- (from PDFA)
	
invariant

		-- from ANY
	reflexive_equality: standard_is_equal (Current)
	reflexive_conformance: conforms_to (Current)
		-- from HIGH_BUILDER
	cursor_not_too_far: cursor <= description_length
		-- from LEX_BUILDER
	last_created: tool_list = void or else last_created_tool = tool_list.count
		-- from ARRAY
	area_exists: area /= void
	consistent_size: capacity = upper - lower + 1
	non_negative_count: count >= 0
	index_set_has_same_count: valid_index_set
		-- from RESIZABLE
	increase_by_at_least_one: minimal_increase >= 1
		-- from BOUNDED
	valid_count: count <= capacity
	full_definition: full = (count = capacity)
		-- from FINITE
	empty_definition: is_empty = (count = 0)
	non_negative_count: count >= 0
		-- from INDEXABLE
	index_set_not_void: index_set /= void

end -- class L_INTERFACE