?? NOTE: IN PROGRESS ?? VHDL Issue Number: 1045 Classification: Language Definition Problem Language Version: VHDL-93 Summary: Qualified expressions lead to lexical ambiguity Related Issues: Supersedes 0225; 1114 Relevant LRM Sections: 7.3.4, 13.2, 13.5 Key Words and Phrases: Qualified Expressions Current Status: Submitted ?? being analyzed ?? 1076-1993 Disposition: N/A Disposition Rationale: N/A Superseded By: N/A ----------------------- Date Submitted: 1991/03/21 Author of Submission: Clive Charlwood Author's Affiliation: Synopsys Inc. Author's Post Address: 1098 Alta Ave. Mountain View, CA 94043 Author's Phone Number: (415) 962-5425 Author's Fax Number: Author's Net Address: crc@synopsys.com ----------------------- Date Analyzed: 1995/05/22 Author of Analysis: Daniel Barclay Revision Number: $Revision: 1.11 $ Date Last Revised: $Date: 1995/05/30 21:53:01 $ Description of Problem ---------------------- (This was Endot VHDL LRM Trouble Report #JM12 8/22/88) Consider the following VHDL statements: X := bit_vector'('1','0'); B := bit'('1'); Both are intended to be interpreted as qualified expressions. However, it is possible that the lexical scanner will tokenize these statements as: X := bit_vector '(' 1 ',' 0 ' ) ; B := bit '(' 1 ' ) ; Proposed Resolution ------------------- TBD VASG-ISAC Analysis & Rationale ------------------------------ ?? incorporate attribute-name example: xxxx'a'predef ?? The problem is that there is ambiguity in the lexical grammar and the language does not specify sufficient rules to remove it. The result is that VHDL does not specify how to interpret the above sequences of characters. In each sequence, the characters may be composed (tokenized) into at least two different sequences of lexical elements (tokens), and the LRM never specifies how to select among these two sequences or whether an ambiguous case is illegal. In other potential problem cases, the LRM does specify such rules, although indirectly. For example, consider the character sequence " xy ". Does this contain the one identifier "xy" or the two identifiers "x" and "y"? Obviously, "xy" is the intent. However, the LRM never says directly to assemble maximal tokens out of characters. The LRM achieves this indirectly. Section 13.2 paragraph two says generally: In some cases an explicit separator is required to separate adjacent lexical elements (namely when, without separation, interpretation as a single lexical element is possible). ... and paragraph five says specifically: ... At least one separator is required between an identifier or an abstract literal and an adjacent identifier or abstract literal. This last sentence says that if " xy " is the two identifiers "x" and "y", then the situation is illegal. Effectively, this means that " xy " is not "x" and "y", but is "xy". Therefore, " xy " contains the one identifier "xy". (The LRM should specify this more directly; this wording should be clearer. The LRM should say that lexical elements that don't follow such rules are not considered to be such lexical elements, or that sequences which otherwise appear to be lexical elements but don't follow such rules are not actually the lexical elements they appear to be. (No, I don't know how to say that clearly.)) Although the above rule applies only to identifiers and abstract literals and not to current example, it could be extended to remove the ambiguity. How- ever, this solution is not attractive. At least one space adjacent to the left parenthesis would be necessary to force interpretation as lexical elements appropriate for a qualified expression: b := bit'('1'); -- invalid syntax (tokens "'('" "1" "'" ")" ) b := bit' ('1'); -- qualified expr. (tokens "'" "(" "'1'" ")" ) b := bit'( '1'); -- " " b := bit' ( '1'); -- " " It would be possible to follow the principle of overloading and specify to tokenize the characters in all possible ways, and then select one using syntactic information. However, this is also a bad idea, breaking the normal separation between a lexer and a parser. The root of this problem of interaction between the lexical syntax of character literal and the higher-level syntax of qualified expressions (and attribute names) is the choice of terminals in that high-level syntax. However, changing that syntax is not possible now. Neither can the LRM leave it up to an implementation to decide how to resolve ambiguity if VHDL is to be a standard and VHDL models are to be as portable as possible. (Recall that the LRM defines what is and is not used for overload resolution, so we don't have "smarter" analyzers accepting VHDL that other analyzers can't accept. Well...supposedly.) It appears that the remaining solution is to define a local special-case rule for lexical processing. Because it is the lexer that must choose how to tokenize the characters, the decision rule should be based on information that the lexer will have. Let's start by considering which lexical elements can precede character literal lexical elements and single-quote delimiter lexical elements in the syntax: First of all, comments are not intended to have any effect, so they are not considered in the following. ?? (Recall that the main case is when the next characters could be a character literal lexical element. Another practical case (but one that probably doesn't have to be dealt with standardly) is when the next characters could be the start of an ill-formed character literal (e.g, "'d '" or "'d < 'e'") ) ?? I. Single-Quote Delimiters Single-quote delimiters appear in only two places: qualified expressions and attribute names. I.1 Qualified expressions: For a qualified expression, the syntax is: qualified_expression ::= type_mark ' ( expression ) | type_mark ' aggregate Therefore, a single quote symbol can be preceded by whatever can end (be the last lexical element in) a type mark. (I.1.1 Type Mark, Ending Lexical Element) For a type mark, the syntax is: type_mark ::= {\i type_}name | {\i subtype_}name where "{\i text}" means that the text is given in italics in the LRM, and where words in italics are ignored for syntactic purposes. Therefore, the last token of a type mark can be whatever can end a name. (I.1.2 Name, Ending Token) For a name, the syntax is: name ::= simple_name | operator_symbol | selected_name | indexed_name | slice_name | attribute_name Therefore, the ending lexical element of a name can be whatever can end a simple name, an operator symbol, a selected name, an indexed name, a slice name, or an attribute name. A simple name is simply an identifier, specifically, a non-reserved- word identifier. Therefore, the ending lexical element of a name can be a non-reserved- word identifier. A operator symbol is simply a string literal. Therefore, the ending lexical element of a name can be a string literal. For a selected name, the syntax is: selected_name ::= prefix . suffix Therefore, given that the suffix is never an empty set of lexical elements, the ending lexical element of a selected name is whatever can end a suffix. For a suffix, the syntax is: suffix ::= simple_name | character_literal | operator_symbol | {\b all} where "{\b text}" means that the text is given in boldface in the LRM, and where boldfaced words are reserved-word identifiers. For a simple name, the ending lexical element is a non-reserved-word identifier (from above). For a character literal, the ending lexical element is that character literal. For an operator symbol, the ending lexical element is a string literal (from above). For "all", the ending lexical element in the reserved-word identifier "all". Therefore, the ending lexical element of a selected name can be a non- reserved-word identifier, a character literal, a string literal, or the reserved-word identifier "all". For an indexed name, the syntax is: indexed_name ::= prefix ( expression { , expression } ) Therefore, the ending lexical element of an indexed name is ")". For a slice name, the syntax is: slice_name ::= prefix ( discrete_range ) Therefore, the ending lexical element of an slice name is ")". For an attribute name, the syntax is: attribute_name ::= prefix [ signature ] ' attribute_designator [ ( expression ) ] Therefore, the ending lexical element of an attribute name is "(" or whatever can end an attribute designator. For attribute designator, the syntax is: attribute_designator ::= {\i attribute_}simple_name Therefore, the ending lexical element of an attribute designator is whatever can be the ending lexical element of a simple name. From above, that is a non-reserved-word identifier. Therefore, the ending lexical element of an attribute name is "(" or a non-reserved-word identifier. Therefore, the ending lexical element of a name is ")", "all", a non- reserved word identifier, a string literal, or a character literal. (I.1.2 Name, Ending Lexical Element) Therefore, the ending lexical element of a type mark is one of those five lexical element types. (I.1.1 Type Mark, Ending Lexical Element) Therefore, a single-quote delimiter lexical element in a qualified expression can be preceded ")", "all", a non-reserved word identifier, a string literal, or a character literal. I.2 Attribute names: For an attribute name, the syntax is: attribute_name ::= prefix [ signature ] ' attribute_designator [ ( expression ) ] Therefore, a single-quote delimiter can be preceded by whatever lexical element ends a signature or by whatever ends a prefix. For a signature, the syntax is: signature ::= [ [ type_mark { , type_mark } ] [ {\b return} type_mark ] ] Therefore, the ending lexical element of a signature is a right bracket. For a prefix, the syntax is: prefix ::= name | function_call Therefore, the ending lexical element of a prefix is whatever can be the ending lexical element of a name or the ending lexical element of a function call. For a name, the ending lexical element (from above) is a non-reserved-word identifier, a reserved-word identifier "all", string literal, a character literal, or ")". For a function call, the syntax is: function_call ::= {\i function_}name [ ( actual_parameter_part ) ] Therefore, the ending lexical element of a function call is ")" or whatever can end a name. For a name, the ending lexical element (from above) is a non-reserved- word identifier, a reserved-word identifier "all", string literal, a character literal, or ")". Therefore, the ending lexical element of a function call is ")", a non- reserved-word identifiers, a reserved-word identifier "all", a string literal, or a character literal. Therefore, the ending lexical element of a prefix is ")", a non-reserved- word identifiers, a reserved-word identifier "all", a string literal, or a character literal. Therefore, a single-quote delimiter lexical element in an attribute name can be preceded by "]", ")", "all", a non-reserved-word identifier, a string literal, or a character literal. Recall that qualified expressions and attribute names are the only places that single-quote lexical elements can appear. Therefore, a lexically ambiguous single-quote character is a single-quote lexical element only after one of the following lexical elements: a non-reserved-word identifier, the reserved-word identifier "all", a string literal, a character literal, "]", or ")". This rule removes the ambiguity because character literal lexical elements can never appear after these five lexical element types. II. Character Literal Lexical Elements A character literal can appear: - as an enumeration literal - as an alias designator - as a group constituent - as an entity tag - as a suffix Therefore, a character literal can be preceded by whatever can precede an enumeration literal, whatever can precede an alias designator, whatever can precede a group constituent, whatever can precede an entity tag, or whatever can precede a suffix. (II.1 Suffix) For a suffix, the syntax is: suffix ::= simple_name | character_literal | operator_symbol | {\b all} A suffix can appear only in a selected name. For a selected name, the syntax is: selected_name ::= prefix . suffix Therefore, a suffix can be preceded by ".". Therefore, a character literal can be preceded by ".". (II.1 Suffix) (II.2 Entity tag) For an entity tag, the syntax is: entity_tag ::= simple_name | character_literal | operator_symbol An entity tag can appear only in an entity designator. For an entity designator, the syntax is: entity_designator ::= entity_tag [ signature ] Therefore, an entity designator can be preceded by whatever can precede an entity designator. An entity designator can appear only in an entity name list. For an entity name list, the syntax is: entity_name_list ::= entity_designator { , entity_designator } | {\b others} | {\b all} Therefore, a entity designator can be preceded by "," or by whatever can precede an entity name list. An entity name list can appear only in an entity specification. For an entity specification, the syntax is: entity_specification ::= entity_name_list : entity_class Therefore, an entity name list can be preceded by whatever can precede an entity specification. An entity specification can appear only in an attribute specification. For an attribute specification, the syntax is: attribute_specification ::= {\b attribute} attribute_designator {\b of} entity_specification {\b is} expression ; Therefore, an entity specification can be preceded by the reserved word "of". Therefore, an entity name list can be preceded by "of" Therefore, an entity name list can be preceded by "," or "of". Therefore, an entity tag can be preceded by "," or the reserved word "of". Therefore, a character literal can be preceded by "," or by the reserved- word identifier "of". (II.2 Entity tag) (II.3 Group constituent) For a group constituent, the syntax is: group_constituent ::= name | character_literal A group constituent can appear only in a group constituent list. For a group constituent list, the syntax is: group_constituent_list ::= group_constituent { , group_constituent } Therefore, group_constituent can be preceded by "," and by whatever can precede a group constituent list. A group constituent list can appear only in a group declaration. For a group declaration, the syntax is: group_declaration ::= {\b group} identifier : {\i group_template_}name ( group_constituent_list ) ; Therefore, a group constituent list can be preceded by "(". Therefore, a group constituent can be preceded by "," or "(". Therefore, a character literal be preceded by "," or a "(". (II.3 Group constituent) (II.4 Alias Designator) For an alias designator, the syntax is: alias_designator ::= identifier | character_literal | operator_symbol A alias designator can appear only in an alias declaration. For an alias declaration, the syntax is: alias_declaration ::= {\b alias} alias_designator [ : subtype_indication ] {\b is} name [ signature ] ; Therefore, an alias designator can be preceded by the reserved word "alias". Therefore, an character literal can be preceded by the reserved word "alias". (II.4 Alias Designator) (II.5 Enumeration Literal) For an enumeration literal, the syntax is: enumeration_literal ::= identifier | character_literal Therefore, a character literal can be preceded by whatever can precede an enumeration literal. An enumeration literal can appear: - in an enumeration type definition - as a literal (II.5.1 Enumeration Type Definition) For an enumeration type definition, the syntax is: enumeration_type_definition ::= ( enumeration_literal { , enumeration_literal } ) Therefore, an enumeration literal can be preceded by "," or "(". (II.5.1 Enumeration Type Definition) (II.5.2 Literal) For literal, the syntax is: literal ::= numeric_literal | enumeration_literal | string_literal | bit_string_literal | {\b null} Therefore, a enumeration literal can be preceded by whatever can precede a literal. A literal can appear only as a primary. Therefore, a literal can be preceded by whatever can precede a primary. (II.5.2.1 Primary) For a primary, the syntax is: primary ::= name | literal | aggregate | function_call | qualified_expression | type_conversion | allocator | ( expression ) A primary can appear only in a factor. Therefore, a primary can be preceded by whatever can precede it in a factor. (II.5.2.1.1a Factor) For factor, the syntax is: factor ::= primary [ ** primary ] | {\b abs} primary | {\b not} primary Therefore, a primary is preceded by "**", "abs", or "not", or by whatever can precede a factor. A factor can appear only in a term. Therefore, a factor can be preceded by whatever can precede it in a term. (II.5.2.1.1.1 Term) For term, the syntax is: term ::= factor { multiplying_operator factor } Therefore, factor can be preceded by whatever can end a multiplying operator and by whatever can precede a term. (A multiplying operation cannot have zero lexical elements.) (II.5.2.1.1.1.1 Multiplying Operator) For multiplying_operator, the syntax is: multiplying_operator ::= * | / | {\b mod} | {\b rem} Therefore, a factor can be preceded by "*", "/", "mod", "rem". (II.5.2.1.1.1.1 Multiplying Operator) A term can appear only in a simple expression. Therefore, a term can be preceded by whatever can precede it in a simple expression. (II.5.2.1.1.1.2 Simple Expression) For a simple expression, the syntax is: simple_expression ::= [ sign ] term { adding_operator term } Therefore term can be preceded by whatever can end a sign and an adding operator and by whatever can precede a simple expression. The syntax of adding_operator and sign are: adding_operator ::= + | - | & sign ::= + | - Therefore, term can be preceded by "+", "-", and "&". A simple expression can appear: - in a range - in a shift expression - as a choice. Therefore, a simple expression can be preceded by whatever can precede a range, a shift expression, or choice. (II.5.2.1.1.1.2.1 Choice) For a choice, the syntax is: choice ::= simple_expression | discrete_range | {\i element_}simple_name | {\b others} A choice can appear only in a set of choices. Therefore, a choice can be preceded by whatever can precede it in a set of choices. (II.5.2.1.1.1.2.1.1 Choices) For a set of choices, the syntax is: choices ::= choice { | choice } Therefore, a choice can be preceded by "|" or by whatever can precede a set of choices. A set of choices can appear: - in element_association - in case_statement_alternative - in selected_waveforms (II.5.2.1.1.1.2.1.1.1 Element Association) For an element association, the syntax is: element_association ::= [ choices => ] expression Therefore, a set of choices can be preceded by whatever can precede an element association. An element association can appear only in an aggregate. Therefore, an element association can be preceded by whatever can precede it in an aggregate. For an aggregate, the syntax is: aggregate ::= ( element_association { , element_association } ) Therefore, an element association may be preceded by "," or "(". Therefore, a set of choices appearing as an element association may be preceded by "," or "(". (II.5.2.1.1.1.2.1.1.1 Element Association) (II.5.2.1.1.1.2.1.1.2 Case Statement Alternative) For a case statement alternative, the syntax is: case_statement_alternative ::= {\b when} choices => sequence_of_statements Therefore, a set of choices appearing in a case statement alternative can be preceded by the reserved-word identifier "when". (II.5.2.1.1.1.2.1.1.2 Case Statement Alternative) (II.5.2.1.1.1.2.1.1.3 Selected Waveforms) For a set of selected waveforms, the syntax is: selected_waveforms ::= { waveform {\b when} choices , } waveform {\b when} choices Therefore, a set of choices appearing in a selected wave- forms can be preceded by the reserved-word identifier "when". (II.5.2.1.1.1.2.1.1.3 Selected Waveforms) Therefore, a set of choices can be preceded by "(", ",", or "when". (II.5.2.1.1.1.2.1.1 Choices) Therefore, a choice appearing in a set of choices can be preceded by "(", ",", or "when". Therefore, a simple expression appearing as a choice can be preceded by "when", ",", or "(". (II.5.2.1.1.1.2.1 Choice) (II.5.2.1.1.1.2.2 Range) For range, the syntax is: range ::= {\i range_}attribute_name | simple_expression direction simple_expression Therefore, a simple expression can be preceded by whatever ends a direction and by whatever precedes a range. For direction, the syntax is: direction ::= {\b to} | {\b downto} Therefore, the ending lexical element in a direction is "to" or "downto". Therefore, a simple expression can be preceded by "to" or "downto". A range can appear: - in a range constraint - as a discrete range For range constraint, the syntax is: range_constraint ::= {\b range} range Therefore, a simple expression can be preceded by the reserved- word identifier "range". For a discrete range, the syntax is: discrete_range ::= discrete_subtype_indication | range Therefore, a simple expression can be preceded by whatever can precede a discrete range. Discrete range can appear: - as in index specification - in an index constraint - in a slice name - as a choice - in a parameter specification For slice name, the syntax is: slice_name ::= prefix ( discrete_range ) Therefore, a discrete range appearing in a slice name can be preceded by "(". For index constraint, the syntax is: index_constraint ::= ( discrete_range { , discrete_range } ) Therefore, a discrete range appearing in an index constraint can be preceded by "," or "(". For a parameter specification, the syntax is: parameter_specification ::= identifier {\b in} discrete_range Therefore, a discrete range in a parameter specification can be preceded by the reserved-word identifier "in". For a choice (analyzed above), the preceding lexical elements can be "|", ",", "(", or "when". Therefore, a discrete range appearing as a choice can be preceded by "|", ",", "(", or "when". For a index specification, the syntax is: index_specification ::= discrete_range | {\i static_}expression Therefore, a discrete range appearing as an index specification can be preceded by whatever can precede an index specification. An index specification can appear only in a block specifica- tion. Therefore, an index specification can be preceded by whatever can precede it in a block specification. For block specification, the syntax is: block_specification ::= {\i architecture_}name | {\i block_statement_}label | {\i generate_statement_}label [ ( index_specification ) ] Therefore, an index specification can be preceded by "(". Therefore, a discrete range appearing as an index specification can be preceded by "(", ",", "in", "|", or "when". Therefore, a discrete range be preceded by "(", ",", "in", "|", "when", "to, "downto", or "range". Therefore, a range can be preceded by "(", ",", "in", "|", "when", "to, "downto", or "range". (II.5.2.1.1.1.2.2 Range) (II.5.2.1.1.1.2.3 Shift Expression) For shift expression, the syntax is: shift_expression ::= simple_expression [ shift_operator simple_expression ] Therefore, a character literal can be preceded by the whatever can end shift_operator and by whatever can precede a shift_expression. (II.5.2.1.1.1.2.3.1 Shift Operator) For shift_operator, the syntax is: shift_operator ::= {\b sll} | {\b srl} | {\b sla} | {\b sra} | {\b rol} | {\b ror} Therefore, a character literal can be preceded by the reserved- word identifiers "sll", "srl", "sla", "sra", "rol", and "ror". (II.5.2.1.1.1.2.3.1 Shift Operator) A shift expression can appear only in a relation. Therefore, a shift expression can be preceded by whatever can precede it in a relation. (II.5.2.1.1.1.2.3.2 Relation) For a relation, the syntax is: relation ::= shift_expression [ relational_operator shift_expression ] Therefore, a shift expression can be preceded by whatever can end relational_operator and by whatever can precede a relation. (II.5.2.1.1.1.2.3.2.1 Relational Operator) For relational_operator, the syntax is: relational_operator ::= = | /= | < | <= | > | >= Therefore, a shift expression can be preceded by "=", "/=", "<", "<=", ">", or ">=". (II.5.2.1.1.1.2.3.2.1 Relational Operator) A relation can appear only in an expression. Therefore, a relation can be preceded by whatever can precede it in an expression. (II.5.2.1.1.1.2.3.2.2 Expression) For an expression, the syntax is: expression ::= relation { {\b and} relation } | relation { {\b or} relation } | relation { {\b xor} relation } | relation [ {\b nand} relation ] | relation [ {\b nor} relation ] | relation { {\b xnor} relation } Therefore, a relation can be preceded by "and", "or", "xor", "nand", "nor", or "xnor", plus whatever can precede an expression. An expression can appear: - as an actual designator - in an assertion - in an attribute name - in an attribute specification - in a block_statement - in a case statement - as a choice - as a condition - in a constant declaration - in a delay mechanism - in a disconnection specification - in an element association - as a file logical name - in a file_open_information - as an index specification - in an indexed name - in an interface constant declaration - in an interface signal declaration - in an interface variable declaration - in a primary - in a qualified expression - in a report statement - in a return statement - in a selected signal assignment - in a signal declaration - in a timeout clause - in a type conversion - in a variable assignment statement - in a variable declaration - in a waveform element (II.5.2.1.1.1.2.3.2.2.1 Simple Cases) Simple cases first: For constant declaration, variable declaration, signal declaration, interface constant declaration, interface variable declaration, interface signal declaration, and variable assignment statement, an expression can appear only after ":=". Therefore, an expression appearing in these cases can be preceded by ":=". In a block statement, an attribute name, a primary, a type conversion, or a qualified expression, an expression can appear only after "(". Therefore, an expression appearing in these cases can be preceded by "(". In a report statement or an assertion, an expression can appear after "report" or "severity". In a delay mecha- nism, it can appear after "reject". In a disconnection specification, it can appear after "after". In a case statement, it can appear after "case". In a return state- ment, it can appear after "return". In a file open infor- mation, it can appear after "is". In an attribute specification, it can appear after "is". In a timeout clause, it can appear after "for". In a selected signal assignment, it can appear after "with". Therefore, an expression preceded by "report", "severity", "reject", "after", "case", "return", "is", "for", or "with". In an indexed name, an expression can appear after "," or "(". Therefore, an expression appearing in this cases can be preceded by "(" or ",". Therefore, an expression appearing in these simple cases can be preceded by "(", ",", ":=", "report", "severity", "reject", "after", "case", "return", "is", "for", or "with". (II.5.2.1.1.1.2.3.2.2.1 Simple Cases) (II.5.2.1.1.1.2.3.2.2.2 Remaining Cases) The remaining case are: actual designator, choice, condition, element association, file logical name, index specification, waveform element. (II.5.2.1.1.1.2.3.2.2.2.1 Choice) From above, a choice can be preceded by "when", ",", or "(". Therefore, an expression appearing as a choice can be preceded by "when", ",", or "(". (II.5.2.1.1.1.2.3.2.2.2.1 Choice) (II.5.2.1.1.1.2.3.2.2.2.2 Index Specification) From above, an index specification can be preceded by "(". Therefore, an expression appearing as an index specifica- tion can be preceded by "(". (II.5.2.1.1.1.2.3.2.2.2.2 Index Specification) (II.5.2.1.1.1.2.3.2.2.2.3 File Logical Name) A file logical name can appear only in a file open information. Therefore, a file logical name can be preceded by whatever can precede it in a file open information. For a file open information, the syntax is: file_open_information ::= [ {\b open} {\i file_open_kind_}expression ] {\b is} file_logical_name Therefore, a file logical name can be preceded by "is". Therefore, an expression appearing as a file logical name can be preceded by "is". (II.5.2.1.1.1.2.3.2.2.2.3 File Logical Name) (II.5.2.1.1.1.2.3.2.2.2.4 Element Association) For an element association, the syntax is: element_association ::= [ choices => ] expression Therefore, an expression appearing in or as an element association can be preceded by "=>" or by whatever can precede an element association. From above, an element association can be preceded by "," or "(". Therefore, an expression appearing in an element associ- ation can be preceded by "=>", ",", or "(". (II.5.2.1.1.1.2.3.2.2.2.4 Element Association) (II.5.2.1.1.1.2.3.2.2.2.5 Condition) A condition can appear: -in an assertion -in a condition clause -in a set of conditional waveforms -in an exit statement -in a next statement -in a generation scheme -in an iteration scheme -in an if statement In an assertion, it is preceded by "assert". In a condition clause, it is preceded by "until". In a set of conditional waveforms, a next statement, or an exit statement, it is preceded by "when". In an if statement, it is preceded by "if" or "elsif". In a generation scheme, it is preceded by "if". In a iteration scheme, it is preceded by "while". Therefore, a condition may be preceded by "assert", "until", "when", "if", "elsif", or "while". Therefore, an expression appearing as a condition may be preceded by "assert", "until", "when", "if", "elsif", or "while". (II.5.2.1.1.1.2.3.2.2.2.5 Condition) (II.5.2.1.1.1.2.3.2.2.2.6 Waveform Element) For waveform element, the syntax is: waveform_element ::= value_expression [ {\b after} {\i time}_expression ] | {\b null} [ {\b after} {\i time_}expression ] Therefore, an expression can be preceded by "after" or by whatever can precede a waveform element. Waveform element can appear only in a waveform. There- fore, a waveform element can be preceded by whatever can precede it in a waveform. (II.5.2.1.1.1.2.3.2.2.2.6.1 Waveform) For a waveform, the syntax is: waveform ::= waveform_element { , waveform_element } | {\b unaffected} Therefore, a waveform element can be preceded by "," or by whatever can precede a waveform. A waveform can appear: - in signal assignment statement - in a set of conditional waveforms - in a set of selected waveforms (II.5.2.1.1.1.2.3.2.2.2.6.1.1 Signal Assignment Statement) For a signal assignment statement, the syntax is: signal_assignment_statement ::= [ label : ] target <= [ delay_mechanism ] waveform ; Therefore, a waveform can be preceded by "<=" or by whatever ends a delay mechanism. From above, the ending lexical element of a delay mechanism is "transport" or "inertial". Therefore, a waveform appearing a signal assignment statement can be preceded by "<=", "transport", or "inertial". (II.5.2.1.1.1.2.3.2.2.2.6.1.1 Signal Assignment Statement) (II.5.2.1.1.1.2.3.2.2.2.6.1.2 Conditional Waveforms) The syntax of a set of conditional waveforms is conditional_waveforms ::= { waveform {\b when} condition {\b else} } waveform [ {\b when} condition ] Therefore, a waveform can be preceded by "else" or by whatever can precede a set of conditional waveforms. A set of conditional waveforms can appear only in a conditional signal assignment. Therefore, a waveform can be preceded by whatever can precede it in a set of conditional waveforms. (II.5.2.1.1.1.2.3.2.2.2.6.1.2.1 Conditional Signal Assignment) For a conditional signal assignment, the syntax is: conditional_signal_assignment ::= target <= options conditional_waveforms ; Therefore, a set of conditional waveforms can be preceded by "<=" (because an options can be null) or by whatever ends options. (II.5.2.1.1.1.2.3.2.2.2.6.1.2.2 Options) For options, the syntax is: options ::= [ {\b guarded} ] [ delay_mechanism ] Therefore, the ending lexical element can be "guarded" or whatever ends a delay mechanism. (II.5.2.1.1.1.2.3.2.2.2.6.1.2.2.1 Delay Mechanism) For a delay mechanism, the syntax is: delay_mechanism ::= {\b transport} | [ {\b reject} {\i time_}expression ] {\b inertial} Therefore, the ending lexical element of a delay mechanism is "transport" or "inertial". (II.5.2.1.1.1.2.3.2.2.2.6.1.2.2.1 Delay Mechanism) Therefore, the ending lexical element of an options is "guarded", "transport", or "inertial" (or nothing). (II.5.2.1.1.1.2.3.2.2.2.6.1.2.2 Options) Therefore, a set of conditional waveforms in a conditional signal assignment can be preceded by "<=", "guarded", "transport", or inertial". (II.5.2.1.1.1.2.3.2.2.2.6.1.2.1 Conditional Signal Assignment) Therefore, a set of conditional waveforms can be preceded by "<=", "guarded", "transport", or inertial". (II.5.2.1.1.1.2.3.2.2.2.6.1.2 Conditional Waveforms) (II.5.2.1.1.1.2.3.2.2.2.6.1.3 Selected Waveforms) The syntax of a set of selected waveforms is selected_waveforms ::= { waveform {\b when} choices , } waveform {\b when} choices Therefore, a waveform can be preceded by "," or by whatever can precede a set of selected waveforms. A set of selected waveforms can appear only in a selected signal assignment. Therefore, a set of selected waveforms can be preceded by whatever can precede it in a selected signal assignment (II.5.2.1.1.1.2.3.2.2.2.6.1.3.1 Selected Signal Assignment) For a selected signal assignment, the syntax is: selected_signal_assignment ::= {\b with} expression {\b select} target <= options selected_waveforms ; Therefore, a set of selected waveforms can be preceded by"<=" (because an options can be null) or by whatever ends options. From above, the ending lexical element of an options is "guarded", "transport", or "inertial" (or no- thing). Therefore, a set of selected waveforms appearing in a selected signal assignment can be preceded by "<=", "guarded", "transport", or inertial". (II.5.2.1.1.1.2.3.2.2.2.6.1.3.1 Selected Signal Assignment) Therefore, a set of selected waveforms can be preceded by "<=", "guarded", "transport", or inertial". (II.5.2.1.1.1.2.3.2.2.2.6.1.2 Selected Waveforms) Therefore, a waveform can be preceded by "<=", "guarded", "transport", or inertial". (II.5.2.1.1.1.2.3.2.2.2.6.1 Waveform) Therefore, a waveform element can be preceded by ",", "<=", "guarded", "transport", or inertial". (II.5.2.1.1.1.2.3.2.2.2.6 Waveform Element) (II.5.2.1.1.1.2.3.2.2.2.7 Actual Designator) An actual designator can appear only in an actual part. Therefore, an actual designator can be preceded by what- ever can precede it in an actual part. (II.5.2.1.1.1.2.3.2.2.2.7.1 Actual Part) For actual part, the syntax is: actual_part ::= actual_designator | {\i function_}name ( actual_designator ) | type_mark ( actual_designator ) Therefore, an actual designator can be preceded by "(" or by whatever can precede an actual part. An actual part can appear only in an association element. Therefore, an actual part can be preceded by whatever can precede it in an association element (II.5.2.1.1.1.2.3.2.2.2.7.1.1 Association Element) For association element, the syntax is: association_element ::= [ formal_part => ] actual_part Therefore, an actual part can be preceded by "=>" or by whatever can precede an association element. An association element can appear only in an association list. Therefore, an association element can be preceded by whatever can precede it in an association list. (II.5.2.1.1.1.2.3.2.2.2.7.1.1.1 Association List) For association list, the syntax is: association_list ::= association_element { , association_element } Therefore, an association element can be preceded by "," or by whatever can precede an association list. An association list can appear: - in a generic map aspect - in a port map aspect - as an actual_parameter_part (II.5.2.1.1.1.2.3.2.2.2.7.1.1.1.1 Generic and Port Map Aspects) For a generic map aspect of a port map aspect, the syntax is: generic_map_aspect ::= {\b generic} {\b map} ( {\i generic_}association_list ) port_map_aspect ::= {\b port} {\b map} ( {\i port_}association_list ) Therefore, an association list appearing in a port or generic map aspect can be preceded by "(". (II.5.2.1.1.1.2.3.2.2.2.7.1.1.1.1 Generic and Port Map Aspects) (II.5.2.1.1.1.2.3.2.2.2.7.1.1.1.2 Actual Parameter Parts) An actual parameter part can appear only in a function call. Therefore, an actual parameter part can be preceded by whatever can precede it in a function call. For a function call, the syntax is: function_call ::= {\i function_}name [ ( actual_parameter_part ) ] Clearly, an actual parameter part in a function call is preceded by "(". Therefore, an actual parameter part can be preceded by "(". (II.5.2.1.1.1.2.3.2.2.2.7.1.1.1.2 Actual Parameter Parts)v Therefore, an association list appearing as an actual parameter part can be preceded by "(". (II.5.2.1.1.1.2.3.2.2.2.7.1.1.1 Association List) Therefore, an association list can be preceded by "(". (II.5.2.1.1.1.2.3.2.2.2.7.1.1.1 Association List) Therefore, an association element can be preceded by "," or "(". (II.5.2.1.1.1.2.3.2.2.2.7.1.1 Association Element) Therefore, an actual part can be preceded by "=>", ",", or "(". (II.5.2.1.1.1.2.3.2.2.2.7.1 Actual Part) Therefore, an actual designator can be preceded by "=>", ",", or "(". (II.5.2.1.1.1.2.3.2.2.2.7 Actual Designator) Therefore, an expression appearing as actual designator can be preceded by "=>", ",", or "(". Therefore, an expression appearing in these remaining cases can be preceded by "(", ",", "<=", "=>", "assert", "elsif", "guarded", "if", "internal", "is", "transport", "until", "when", or "while". (II.5.2.1.1.1.2.3.2.2.2 Remaining Cases) Therefore, an expression can be preceded by "(", ",", ":=", "<=", "=>", "after", "assert", "case", "elsif", "for", "guarded", "if", "internal", "is", "reject", "report", "return", "severity", "transport", "until", "when", "while", or "with". (II.5.2.1.1.1.2.3.2.2 Expression) Therefore, a relation can be preceded by "(", ",", ":=", "<=", "=>", "after", "and", "assert", "case", "elsif", "for", "guarded", "if", "internal", "is", "nand", "nor", "or", "reject", "report", "return", "severity", "transport", "until", "when", "while", "with", "xnor", or "xor". (II.5.2.1.1.1.2.3.2 Relation) Therefore, a shift expression can be preceded by "(", ",", "/=", ":=", "<", "<=", "<=", "=", "=>", ">", ">=", "after", "and", "assert", "case", "elsif", "for", "guarded", "if", "internal", "is", "nand", "nor", "or", "reject", "report", "return", "severity", "transport", "until", "when", "while", "with", "xnor", or "xor". (II.5.2.1.1.1.2.3 Shift Expression) Therefore, a simple expression can be preceded by "&", "(", "+", ",", "-", "/=", ":=", "<", "<=", "<=", "=", "=>", ">", ">=", "after", "and", "assert", "case", "downto","elsif", "for", "guarded", "if", "in", "internal", "is", "nand", "nor", "or", "range", "reject", "report", "return", "severity", "to", "transport", "until", "when", "while", "with", "xnor", "xor", or "|". (II.5.2.1.1.1.2 Simple Expression) Therefore, a term... (II.5.2.1.1.1 Term) Therefore, a factor... (II.5.2.1.1 Factor) Therefore, a primary... (II.5.2.1 Primary) Therefore, a literal... (II.5.2 Literal) (II.5 Enumeration Literal) Therefore, a enumeration literal appearing as literal... FINALLY!: Therefore, a character literal can be preceded by: "&", "(", "*", "**", "+", ",", ",", "-", ".", "/", "/=", ":=", "<", "<=", "=", ">", ">=", "abs", "after", "alias", "and", "assert", "case", "downto", "else", "elsif", "for", "guarded", "if", "in", "inertial", "is", "mod", "nand", "nor", "not", "of", "or", "range", "reject", "rem", "report", "return", "rol", "ror", "severity", "sla", "sll", "sra", "srl", "to", "transport", "until", "when", "while", "with", "xnor", "xor", or "|". Recall that a single-quote delimiter can be preceded by: "]", ")", "all", a non-reserved-word identifier a string literal, or a character literal. These sets do not overlap, so a single-quote characters for a single-quote delimiter lexical element can be distinguished from a single-quote character that starts a character literal lexical elements by using only the previous lexical element, specifically, by considering the kind of lexical element, whether an identifier lexical element is a reserved word or not, and which reserved word it is. This is all information that a lexer would be expected to have already. So ... should the LRM define how the resolve the ambiguity, and should it be based on this rule: When, considering preceding lexical elements only, a single-quote character could be the beginning of a character literal (that is, when it is the ambiguous case), then it is considered to be a separate symbol (the single-quote delimiter lexical element) instead of the start of a character literal lexical element if of the preceding lexical elements other than comments (or separators, if they are added as lexical elements) there is a preceding lexical element and that preceding lexical element is one of the following lexical elements: - a right parenthesis (")") - a right bracket ("]") - the reserved-word identifier "all" - a non-reserved-word identifier - a string literal - a character literal ?? IN PROGRESS ?? VASG-ISAC Recommendation for IEEE Std 1076-1993 ----------------------------------------------- TBD VASG-ISAC Recommendation for Future Revisions --------------------------------------------- TBD