-- -- Author: Robert C. Shock, Dept of CS & CEG Wright State University -- In cooperation with: WRDC/ELED WPAFB Dayton, OH -- -- source: vhdl_lexicon_.a -- -- -- OVERVIEW: package vhdl_lexicon -- -- << Background on vhdl lexicon >> -- A vhdl source code is defined to be a text file that conforms to the specifications of the IEEE-VHDL-LRM ( it compiles ). Its logical data structure is a linear ordered set ( sequence ) of lexical elements. -- << Purpose >> -- The main objective is to provide several iterators each of which will iterate over the logical sequential data structure of a vhdl source code. Hence, each lexical element can be accessed separately and in order. -- << Lexicon Hierarchy >> -- The vhdl Reference Manual lists the lexicon elements as enumerated in type "element_type". The type "element_subtype" further decomposes each "element_type". The type "element_name" assigns a unique name to each constant lexical value; these values represent each separator, each delimiter and each reserved word. -- << Content >> -- Five sections make up the package vhdl_lexicon. -- Hierarchy Of Types: element_type, element_subtype, element_name -- Output Mechanism: -- Passive Iterator: "iterate_vhdl_code" -- Passive Iterator With Parameters: "iterate_vhdl_code_with_parameters" -- Active Iterator: selectors are "value_is" "type_is", "subtype_is", "name_is". -- << Assumptions >> -- Input: device = text_io.standard_input; -- data = vhdl (syntax) source code -- Note: there is no restriction on the size ( string length ) of a lexical element. The current environment may have a buffer constraint. -- Limited Robustness. When the source file violates vhdl syntax by having the first character of an element type to be unrecognizable such as '#','%; , the line ( from the incompatible character.. to the end of line ) is outputted as a comment line. -- << Design decisions and organizations >> -- The decision to have one package house all the information about the lexical elements forces this package to be lengthly. The rationale is that this high level self containment provides an easy of use; the user needs only to consult one package. -- Design strategy. The source code is a sequence of lexicon elements, some are identified uniquely by their first character ( identifier, abstract_literal, string_literal, delimiters ), the others require at most the first three characters for identification. -- STEP 1. Identify the current lexicon element. Assume the input cursor points to the first character and the process ends with the input cursor pointing to this first character. -- STEP 2. Build the lexicon element and pass the information to these selectors: "value_is" "type_is", "subtype_is", "name_is". Assume the input cursor points to the first character and the process ends with the input cursor pointing to the first character of the next lexical element. -- NOTE, the call to "value_is" activates step 1 and step 2. with text_io; with io_unit; package vhdl_lexicon is type element_type is ( separator, delimiter, identifier, abstract_literal, character_literal, string_literal, bit_string_literal, comment ); type element_subtype is ( separator_end_of_file, separator_end_of_page, separator_end_of_line, separator_format_effector, -- delimiters delimiter_single, delimiter_double, -- identifiers identifier_reserved, identifier_not_reserved, -- abstract literal literal_abstract_decimal, literal_abstract_based, -- literal_character, literal_string, literal_bit_string, comment ); type element_name is ( -- RESERVE WORDS abs_id, access_id, after_id, alias_id, all_id, and_id, architecture_id, array_id, assert_id, attribute_id, begin_id, block_id, body_id, buffer_id, bus_id, case_id, component_id, configuration_id, constant_id, disconnect_id, downto_id, else_id, elsif_id, end_id, entity_id, exit_id, file_id, for_id, function_id, generate_id, generic_id, guarded_id, if_id, in_id, inout_id, is_id, label_id, library_id, linkage_id, loop_id, map_id, mod_id, name_id, new_id, next_id, nor_id, not_id, null_id, of_id, on_id, open_id, or_id, others_id, out_id, package_id, port_id, procedure_id, process_id, range_id, record_id, register_id, rem_id, report_id, return_id, select_id, severity_id, signal_id, subtype_id, then_id, to_id, transport_id, type_id, units_id, until_id, use_id, variable_id, wait_id, when_id, while_id, with_id, xor_id, -- SINGLE DELIMITER ampersand, apostrophe, left_parenthesis, right_parenthesis, star, plus, comma, hyphen, dot, slash, colon, semicolon, less_than, equal, greater_than, vertical_bar, -- COMPOUND DELIMITER arrow, double_star, assignment_variable, inequality, greater_than_equal, less_than_equal, box, -- QUOT quotation, -- SEPARATORS = format effectors, space_character, end_file horizontal_tab, vertical_tab, carriage_return, line_feed, form_feed, space_character, end_file, -- SPECIAL CHARACTERS sharp, underline, dollar, percent, question_mark, commercial_at, left_bracket, right_bracket, back_slash, circumflex, grave_accent, right_brace, left_brace, tilde, -- IDENTIFIER NOT A RESERVE WORD identifier_not_rw_id, -- ABSTRACT LITERAL integer_literal, integer_exponent_literal, real_literal, based_literal, -- CHARACTER LITERAL character_literal, -- STRING LITERAL string_literal, -- BIT_STRING_LITERAL bit_string_B, bit_string_O, bit_string_X, -- COMMENT comment ); -- SECTION: OUTPUT MECHANISM -- -- logical file terminators -- the_end_file_character: character renames io_unit.the_end_file_character; the_end_page_character: character renames io_unit.the_end_page_character; the_end_line_character: character renames io_unit.the_end_line_character; procedure put ( the_string: in string ); -- Effect: puts each ( non_terminator ) character to the standard output and executes the associated function of each terminator character. The terminator character names are end_file, end_page, end_line. procedure put ( the_element_type: in element_type; the_field_width: in text_io.field := 18; -- 18 characters in largest type the_type_set: in text_io.type_set := text_io.lower_case ); -- Effect: puts the enumerated type to standard output procedure put ( the_element_subtype: in element_subtype; the_field_width: in text_io.field := 25; -- 25 characters in largest type the_type_set: in text_io.type_set := text_io.lower_case ); -- Effect: puts the enumerated type to standard output procedure put ( the_element_name: in element_name; the_field_width: in text_io.field := 28; -- 28 characters in largest type the_type_set: in text_io.type_set := text_io.lower_case ); -- Effect: puts the enumerated type to standard output -- SECTION: PASSIVE ITERATOR -- -- pass the attributes ( value, type, subtype, name ) of each lexical element of a vhdl source code generic with procedure process ( the_value: in string; the_type: in element_type; the_subtype: in element_subtype; the_name: in element_name; continue: out boolean ); procedure iterate_vhdl_code; -- SECTION: PASSIVE ITERATOR WITH PARAMETERS -- generic type external_type_in is limited private; type external_type_in_out is limited private; with procedure process ( -- the external data -- the_external_data_in: in external_type_in; the_external_data_in_out: in out external_type_in_out; -- the iterative data -- the_value: in string; the_type: in element_type; the_subtype: in element_subtype; the_name: in element_name; continue: out boolean ); procedure iterate_vhdl_code_with_parameters ( the_external_data_in: in external_type_in; the_external_data_in_out: in out external_type_in_out ); -- SECTION: ACTIVE ITERATOR -- function value_is return string; -- Effect: defines the current lexical element and returns its character value function type_is return element_type; -- Effect: returns the "element_type" of the current lexical element function subtype_is return element_subtype; -- Effect: returns the "element_subtype" of the current lexical element function name_is return element_name; -- Effect: returns the "element_name" of the current lexical element -- INTENDED USAGE for active iterator -- iterate: -- loop -- process ( value_is ); -- -- use if needed type_is, subtype_is, name_is ); -- exit iterate when subtype_is = separator_end_of_file; -- end loop -- iterate; end vhdl_lexicon;