/** * (C) 2002 Peter Kehl * peterk (@) paneris.org * version 1.00 Pukavik/Arava from 28th April 2002 * Available at http://paneris.org/~peterk/vhdlams/ * * Free under GNU GPL license version 2. * For more relaxations, contact Christoph Grimm and me. * * Container class Trans is separate and free for any use (BSD like). * * Based on: * * VHDL-93, VHDL-AMS grammar for JavaCC * (c) 1997 Christoph Grimm * * Email: grimm@ti.informatik.uni-frankfurt.de * Address: * Christoph Grimm * J. W. Goethe-University Frankfurt * Robert-Mayer-Strasse 11-15 * 60054 Frankfurt * Germany */ /* Important notes for future development: 1. Whole approach is described in Thesis, at same url as noted above. 2. Read documentation of container class Trans. 3. Editor with syntax C++/Java highlighting is a must. 4. HTML BNF documentation fits for fast orientation in PDF/printed VHDL-AMS LRM. 5. BNF productions with descriptive value were transformed - merged/skipped. They are commented in way: // new_production() was original_production(). 6. Generated C++ code is case sensitive. All VHDL-AMS tokens are transformed to lowercase. Names of additional structures, not visible to VHDL-AMS user, as matlabInterface, consist of uppercase characters. */ options { DEBUG_PARSER = true; // CHOICE_AMBIGUITY_CHECK=3; IGNORE_CASE=false; STATIC = true; OPTIMIZE_TOKEN_MANAGER = true; CACHE_TOKENS = true; } // The parser is instanciated in the file Vhdl.java PARSER_BEGIN(VhdlParser) import java.util.*; import java.io.*; public class VhdlParser { static ErrorHandler errs = new ErrorHandler(); static final Trans noTrans= new Trans( " noTrans! "); static final String noTransStr= noTrans.toString(); static final Trans unfinished= new Trans( " UNFINISHED! "); static final Trans empty= new Trans(); static final Port noPort= new Port( "", "", new Trans(" NoPORT! ") ); static final ArrayList noList= new ArrayList(); //!= freeList !! // Those lists are reset in library_unit(). // They carry respective collected identifiers, used in architecture_body(). static HashSet dots= new HashSet(); static ArrayList generics= new ArrayList(), ports= new ArrayList(), quantities= new ArrayList(), components= new ArrayList(); // Parsed data and flag whether actual production is called [indirectly] // from subtype_indication(). Used by interface_quantity_declaration(To), // name(), name_extension() and subtype_indication(): static Trans typeParameters= noTrans; static boolean inSubtypeIndication= false; // Methods used for report and debugging only: static void ShowRes(String ent) { Entity entt= Entity.read( ent); System.out.println( "SHOWRES(): GENERICS OF ENTITY "+ent+":"); for( int t=0; t } // Section 13: Lexical elements with extensions from IEEE 1076.1 TOKEN [IGNORE_CASE] : { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | } TOKEN : { <#upper_case_letter: [ "A" - "Z" ] > | <#lower_case_letter: [ "a" - "z" ] > | <#digit: [ "0" - "9" ] > | <#extended_digit: [ "0" - "9" , "A" - "F" ] > | <#special_character: [ "#" , "&" , "'" , "(" , ")" , "*" , "+" , "," , "-" , "." , "/" , ":" , ";" , "<" , "=" , ">" , "[" , "]" , "_" , "|" ] > | <#other_special_character: [ "!" , "$" , "%" , "@" , "?" , "^" , "`" , "{" , "}" , "~" , "\\" ] > | <#format_effector: [ "\n" , "\t" ] > | <#base_specifier: [ "B" , "O" , "X" ] > | <#underline: "_" > | <#letter: [ "a" - "z" , "A" - "Z" ] > | <#letter_or_digit: [ "a" - "z" , "A" - "Z" , "0" - "9" ] > | <#integer: ( ("_")? )* > | <#base: > | <#based_integer: ( ("_")? )* > | "#" ( "." )? "#" ()? > | <#basic_character: ( | ) > | <#basic_graphic_character: ( ["A"-"Z"] | | | " " ) > | ( ("_")? )* > | "\"" "\"" > | <#bit_value: ( ("_")? )* > | "'" > | ( "." )? ( )? > | <#exponent: ("E" ("+")? ) | ("E" "-" ) > | ( )* "\\" > | <#graphic_character: ( | | ) > | | "\"\"" )* "\"" > | | | | | | | | =" > | " > | | } Trans abstract_literal() : {Token t;} { t= {return (new Trans( 0) ).conc( t ); } | t= {return (new Trans( 0) ).conc( t ); } } void access_type_definition() : {} { subtype_indication() } Trans actual_designator() : {Trans ret; } { LOOKAHEAD(expression()) ret=expression() {return ret; } | LOOKAHEAD(name()) ret=name() {return ret; } | {return new Trans(0).conc( "OPEN" ); } // OPEN is not implemented } Trans actual_part() : {Trans ret, add;} { LOOKAHEAD( name() "(" actual_designator() ")") ret=name() "(" add=actual_designator() ")" {return ret.conc( "(" ).conc( add ).conc( ")" ); } | LOOKAHEAD( name() "(" actual_designator() ")") // name() was type_mark() ret=name() "(" add=actual_designator() ")" // name() was type_mark() {return ret.conc( "(" ).conc( add ).conc( ")" ); } | ret=actual_designator() {return ret; } } Trans adding_operator() : {} { { return new Trans(0).conc( "+" ); } | { return new Trans(0).conc( "-" ); } | { return new Trans(0).conc( "+" ); } // For future String type. } // Implemented for vector literals only. See Thesis for more. Trans aggregate() : {Trans elem, ret= new Trans(0); int num=1; } { "(" elem= element_association() {ret.conc( elem ); } // First item. ( "," elem= element_association() { if( num==1) ret.conc( ")" ); // Closing parenthesis to "VeCt( num, first)". See down. ret.conc( "," ).conc( elem ); // C++ comma operator adds items to VeCtor. num++; } )* ")" { if( num>1) ret.preconc( "VeCt(" +num +"," ); // Opening parenthesis and vector size. // Outer enclosing () pair is used, because C++ operator comma has low precedence. return ret.preconc( "(" ).conc( ")" ); } } void alias_declaration() : {} { alias_designator() [ ":" subtype_indication() ] name() signature() ";" } void alias_designator() : {} { identifier() | | operator_symbol() } Trans allocator() : {Trans ret;} { ( LOOKAHEAD( name() "'") // name() was type_mark() qualified_expression() | subtype_indication() ) {return unfinished;} } // Reservated Trans containers are used there, see Trans doc for more. // quantities, dots are global lists of collecte identifiers, see beginning of this file. Trans architecture_body() : {Trans ret= new Trans(0), stat, entity, arch, end= noTrans;} { arch= identifier() entity= identifier() architecture_declarative_part() stat= architecture_statement_part() [ ] [ end= identifier() ] ";" { if( end!=noTrans && !arch.equals( end)) errs.Error( "ARCHITECTURE BEGIN & END IDENTIFIERS DON'T MATCH: "+ arch+ "/="+ end); try { Entity ent= Entity.read( entity.toString() +".ent" ); ports= ent.ports; ret.add( "#ifndef " +entity+arch +"_H" ); ret.add( "#define " +entity+arch +"_H" ); ret.newLine(); // Structure that represents architecture: ret.add( "struct " ).conc( entity ).conc( arch ).conc( " {" ); // Quantities and generics translated to member variables of C++ struct: ret.add( "// " ).conc( quantities.size() ).conc( " quantity(ies):" ); for( int i=0; ie.generics.size() ) System.err.println( "INSTANTIATED COMPONENT " +c.label.toString() + "HAS MORE GENERICS THAN IT SHOULD HAVE."); if( c.generics.size()0 ? ", " : "" ); for( int j=c.generics.size(); jj ? ", " : "" ); } //for j } //if } //for i ret.add( "// " ).conc( compo.size() ).conc( " component(s):" ); for( int i=0; i0 ) { System.err.println( "UNKNOWN QUANTITY(IES) USING DOT:"); for( Iterator it= dots.iterator(); it.hasNext(); ) System.err.println( it.next() ); } Architecture arch_file= new Architecture( deriv_ps); arch_file.write( entity.toString() +arch+ ".arc"); // Constructor of structure ret.newLine(); ret.add( "//Constructor of structure" ); ret.add( entity ).conc( arch ).conc( "(" ); for( int i=0; i0) { if( !used) { ret.conc( ": "); used= true; } else ret.conc( ", " ); ret.conc( co.component.label ).conc( "(" ).conc( co.generics ).conc( ")" ); } } // Entity constructor body ret.conc( "{" ); for( Iterator it=deriv_qs.iterator(); it.hasNext();) { ret.add( it.next() ); ret.conc( ".integrated();" ); // Register integrated quantities } ret.add( "} //end of " ).conc( entity ).conc( arch ).conc( "()" ); // Constructor end // go( ports... ) performs behaviour of architecture and components ret.newLine(); ret.add( "//structure's go(..) does all processing:" ); ret.add( "void go(" ); for( int i=0; i) // identifier() was block_label() block_statement() {return new Trans( "UNFINISHED BLOCK_STATEMENT!"); } | LOOKAHEAD([identifier() ":"] [] ) process_statement() {return new Trans( "UNFINISHED PROCESS_STATEMENT!"); } | LOOKAHEAD([identifier() ":"] [] procedure_call() ";") // identifier() was label() concurrent_procedure_call_statement() {return new Trans( "UNFINISHED CONCURRENT PROCEDURE_CALL!"); } | LOOKAHEAD([identifier() ":"] [] ) // identifier() was label() // assertion() was concurrent_assertion_statement(); 2nd identifier() was label() [ identifier() ":" ] [ ] assertion() ";" {return new Trans( "UNFINISHED ASSERTION") ;} | LOOKAHEAD([identifier() ":"] [] conditional_signal_assignment()| // identifier() was label() [identifier() ":"] [] selected_signal_assignment()) // identifier() was label() concurrent_signal_assignment_statement() {return new Trans( "UNFINISHED SIGNAL ASSIGNMENT STATEMENT"); } | LOOKAHEAD(identifier() ":" instantiated_unit() ) // Collects component info. Translated in architecture_body() component_instantiation_statement() {return empty;} | LOOKAHEAD(generate_statement()) ret= generate_statement() {return ret; } /** 1076.1 extensions: */ | LOOKAHEAD(concurrent_break_statement()) ret= concurrent_break_statement() {return ret;} | ret= simultaneous_statement() {return ret;} } /** Error handling: Skip until next semicolon */ catch(ParseException e) { error_skipto(SEMICOLON, "SYNTAX ERROR IN STATEMENT"); } } /** * 1076.1 extension: */ void array_nature_definition() : {} { LOOKAHEAD( "(" index_subtype_definition() ) unconstrained_nature_definition() | constrained_nature_definition() } /** * 1076.1 extension: */ void unconstrained_nature_definition() : {} { "(" index_subtype_definition() ("," index_subtype_definition())* ")" subnature_indication() } /** * 1076.1 extension: */ void constrained_nature_definition() : {} { index_constraint() subnature_indication() } void array_type_definition() : {} { LOOKAHEAD(unconstrained_array_definition()) unconstrained_array_definition() | constrained_array_definition() } void assertion() : {} { expression() // exp=condition [ expression() ] [ expression() ] } void assertion_statement() : {} { [ identifier() ":" ] assertion() ";" // ident=label } Port association_element() : {Trans formal=noTrans, actual;} { [ LOOKAHEAD( formal_part() "=>" ) formal=formal_part() "=>" ] actual=actual_part() {return new Port( formal.toString(), actual.toString(), noTrans); } } ArrayList association_list() : {ArrayList ret=new ArrayList(); Port elem; } { elem=association_element() {ret.add( elem); } ( "," elem=association_element() {ret.add( elem); } )* {return ret; } } void attribute_declaration() : {} { identifier() ":" identifier() ";" // 2nd identifier() was type() } void attribute_name() : {} { prefix() signature() "'" attribute_simple_name() [ "(" expression() ("," expression())* ")" ] // attribute_simp_name() was attribute_designator() } void attribute_specification() : {} { attribute_simple_name() // attribute_simp_name() was attribute_designator() entity_specification() expression() ";" } void binding_indication() : {} { [ entity_aspect() ] [ generic_map_aspect() ] [ port_map_aspect() ] } void block_configuration() : {} { block_specification() ( use_clause() )* ( configuration_item() )* ";" } void block_declarative_item() : {} { try { LOOKAHEAD(subprogram_declaration()) subprogram_declaration() | subprogram_body() | type_declaration() | subtype_declaration() | constant_declaration() | signal_declaration() | shared_variable_declaration() | file_declaration() | alias_declaration() | component_declaration() | LOOKAHEAD(attribute_declaration()) attribute_declaration() | attribute_specification() | configuration_specification() | disconnection_specification() | use_clause() | LOOKAHEAD( identifier() ) group_template_declaration() | group_declaration() /** 1076.1 - Extensions: */ | nature_declaration() | subnature_declaration() | quantity_declaration( quantities) | terminal_declaration() } // Error handling: skip until next semicolon catch (ParseException e) { error_skipto(SEMICOLON, "SYNTAX ERROR IN DECLARATIVE ITEM"); } } void block_declarative_part() : {} { ( block_declarative_item() )* } void block_header() : {} { [ generic_clause() [ generic_map_aspect() ";" ] ] [ port_clause() [ port_map_aspect() ";" ] ] } void block_specification() : {} { LOOKAHEAD(name()) name() | LOOKAHEAD(identifier()) // identifier() was block_statement_label() identifier() | LOOKAHEAD(identifier()) // identifier() was generate_statement_label() identifier() [ "(" index_specification() ")" ] } void block_statement() : {} { identifier() ":" // identifier() was block_label() [ "(" expression() ")" ] [ ] block_header() block_declarative_part() block_statement_part() [ identifier() ] ";" // identifier() was block_label() } void block_statement_part() : {} { (architecture_statement() )* } // Section 8.14: Break statement 1076.1 extension: void break_statement() : {} { [identifier() ":"] [break_list()] [ expression() ] ";" // identifier() was label(); expression() was condition() } // 1076.1 extension: Trans break_list() : {Trans ret= new Trans(), item;} { item=break_element() {ret.add( item );} // Sourrounding {} are added up, when go() function is generated ( "," item=break_element() {ret.add( item );} )* {return ret;} } // 1076.1 extension: Trans break_element() : {Trans target, value;} { [ name() ] // name() was selector_clause(), not used by us target=name() "=>" value=expression() {return target.conc( "= " ).conc( value ).conc( ";" );} // C++ assingment } // 1076.1 extension: void case_statement() : {} { [ identifier() ":" ] // identifier() was case_label() expression() ( choices() "=>" sequence_of_statements() )+ // choices() was case_statement_alternative() [ identifier() ] ";" // case_label } void choice() : {} { LOOKAHEAD(simple_expression()) simple_expression() | LOOKAHEAD(discrete_range()) discrete_range() | identifier() | } void choices() : {} { choice() ( "|" choice() )* } void component_configuration() : {} { instantiation_list() ":" identifier() // all was component_specification() [ binding_indication() ";" ] [ block_configuration() ] ";" } void component_declaration() : {} { identifier() [ ] [ generic_clause() ] [ port_clause() ] [ identifier() ] ";" } void component_instantiation_statement() : {Trans label; Port unit; ArrayList generic= noList, port= noList; } { label= identifier() ":" // label() was instantiation_label() unit= instantiated_unit() [ generic= generic_map_aspect() ] [ port= port_map_aspect() ] ";" { components.add( new Component( label, unit, generic, port) ); } } // 1076.1 - extension: void composite_nature_definition() : {} { array_nature_definition() | record_nature_definition() } void composite_type_definition(): {} { array_type_definition() | record_type_definition() } void concurrent_assertion_statement() : {} { [ identifier() ":" ] [ ] assertion() ";" // identifier() was label() } void concurrent_procedure_call_statement() : {} { [ LOOKAHEAD( identifier() ":") identifier() ":" ] // identifier() was label() [ ] procedure_call() ";" } void concurrent_signal_assignment_statement() : {} { [ LOOKAHEAD( identifier() ":") identifier() ":" ] // identifier() was label() [ ] ( LOOKAHEAD( target() "<=" options_() conditional_waveforms() ";") conditional_signal_assignment() | selected_signal_assignment() ) } void conditional_signal_assignment() : {} { target() "<=" options_() conditional_waveforms() ";" } void conditional_waveforms() : {} { //( waveform() condition() )* //waveform() [ condition() ] waveform() ( LOOKAHEAD( expression() ) // expression() was condition() expression() waveform() )* // expression() was condition() [ expression() ] // expression was condition() } void configuration_declaration() : {} { identifier() identifier() configuration_declarative_part() block_configuration() [ identifier() ] ";" } void configuration_declarative_item() : {} { try { use_clause() | attribute_specification() | group_declaration() } catch(ParseException e) { error_skipto(SEMICOLON, "SYNTAX ERROR IN DECLARATIVE ITEM"); } } void configuration_declarative_part() : {} { ( configuration_declarative_item() )* } void configuration_item() : {} { LOOKAHEAD(block_configuration()) block_configuration() | component_configuration() } void configuration_specification() : {} { instantiation_list() ":" identifier() binding_indication() ";" // was component_specification() } void constant_declaration() : {} { identifier_list() ":" subtype_indication() [ ":=" expression() ] ";" } void constrained_array_definition() : {} { index_constraint() subtype_indication() } void constraint() : {} { range_constraint() | index_constraint() } void context_clause() : {} { ( context_item() )* } void context_item() : {} { library_clause() | use_clause() } // Section 4: // Declarations // 1076.1 extension: void terminal_declaration() : {} { identifier_list() ":" subnature_indication() ";" } void delay_mechanism() : {} { | [ expression() ] } Trans design_file() : {Trans ret;} { ( ret= design_unit() )+ { return ret; } } Trans design_unit() : {Trans ret;} { context_clause() ret=library_unit() { return ret; } } void designator() : {} { identifier() | operator_symbol() } void disconnection_specification() : {} { guarded_signal_specification() expression() ";" } // Implemented for use in generate_statement() and loops only: Range discrete_range() : {Range ret, unfinishedRange= new Range(unfinished, unfinished); Trans from;} { LOOKAHEAD(simple_expression() ( | ) ) // TO | DOWNTO was direction() ret= range() {return ret;} //For use as Vector(Identifier) only: | LOOKAHEAD( subtype_indication() ) from= subtype_indication() {return new Range(from, new Trans("NOT TO BE USED - FROM discrete_range") ); } | range() {return unfinishedRange;} } Trans element_association() : {Trans ret;} { [ LOOKAHEAD(choices() "=>") choices() "=>" { System.err.println( "UNFINISHED CHOICES IN ELEMENT_ASSOCIATION"); } ] ret= expression() {return ret;} } void element_declaration() : {} { identifier_list() ":" subtype_indication() ";" // subtype_indication() was element_subtype_definition() } void entity_aspect() : {} { identifier() [ LOOKAHEAD("(" identifier() ")") "(" identifier() ")" ] | identifier() | } // Section 5: Specifications int entity_class() : {} { { return ENTITY; } | { return ARCHITECTURE; } | { return CONFIGURATION; } | { return PROCEDURE; } | { return FUNCTION; } | { return PACKAGE; } | { return TYPE; } | { return SUBTYPE; } | { return CONSTANT; } | { return SIGNAL; } | { return VARIABLE; } | { return COMPONENT; } |