/**************************************************************************
* PROJECT: DEMETER
* MODULE:
* FILE: gen_lex.c
* SYSTEM: C++ AT&T version 2.0 on sun, UNIX 4.3 BSD
*--------------------------------------------------------------------------
* COPYRIGHT (c) 1990 Northeastern University
* Prof. Karl J. Lieberherr
*--------------------------------------------------------------------------
* AUTHOR: Walter Hursch
*
* DATE: December 11, 1990
* REVISED:
*--------------------------------------------------------------------------
* DESCRIPTION:
* Gen_lex.c creates the file Lex_DEM in directory with name path.
* Lex_DEM serves as input file for the UNIX program lex.
* Lex_DEM consists of the following parts:
* - lex-definitions
* - lex-comment
* - lex-syntax
* - lex-class-terminals
* - lex-white-space
* of which lex-syntax is generated here, since it is the only data-
* dictionary dependent part.
* Later all files are concatenated.
*
**************************************************************************/
/**************************************************************************
Data-dictionary used:
;
;;; produced by extract-cd 'O-P1'
; P1 : I-P1: cd
; : O-P1: intermediate notation
;;; O-P1=I-P2
Demeter_in = Input.
Input :
Cd_graph
*common*.
Cd_graph = < adjacencies > Nlist(Adjacency)
["*terminal_sets*" Comma_list(Vertex) "."]
.
Adjacency =
< source > Vertex
< ns > Neighbors
["*inherits_from*" Comma_list(Term)]
"." .
Neighbors_wc :
Construct_ns |
Alternat_ns
*common* < construct_ns > List(Any_vertex).
Neighbors :
Neighbors_wc |
Repetit_n
*common*.
Construct_ns = "=".
Alternat_ns = ":"
< alternat_ns > Bar_list(Term) [ Common].
Common = "*common*".
Repetit_n = "~" Sandwich(Kernel).
Kernel = [ Term ]
"{" Sandwich(Term) "}".
Any_vertex :
Opt_labeled_term
| Optional_term
| Syntax_vertex
| Inherit_term
*common*.
Vertex = < vertex_name > Ident .
Syntax_vertex :
Regular_syntax
| Print_command
*common*.
Regular_syntax = < string > String .
Print_command :
Print_indent | Print_unindent | Print_skip | Print_space *common*.
Print_indent = "+" .
Print_unindent = "-" .
Print_skip = "*l" .
Print_space = "*s" .
Opt_labeled_term :
Labeled
| Regular
*common* Term.
Regular = .
Labeled = "<" < label_name > Ident ">" .
Inherit_term = "*inherit*" Comma_list(Term).
Term :
Normal
*common* Vertex.
Normal = .
Optional_term = "[" Sandwich(Opt_labeled_term) "]".
List(S) ~ {S}.
Nlist(S) ~ S {S}.
Bar_list(S) ~ S {"|" S}.
Comma_list(S) ~ S {"," S}.
Sandwich(S) =
List(Syntax_vertex) S
List(Syntax_vertex).
**************************************************************************/
#include "generate.h"
#include
#include
#include
/*-------------------------------------------------------------------------
* demeter_in = < input > input .
*/
void Demeter_in::gen_lex( char* path )
{
const int MAXPATH = 256;
ofstream outFile;
char lexfile_name[MAXPATH];
strcpy( lexfile_name, path );
strcat( lexfile_name, "/lex-syntax" );
// open lexfile for output, check opening and write file
outFile.open( lexfile_name, ios::out );
if ( !outFile ) {
cerr << "\nGenerate error: cannot open " << lexfile_name
<< " for output.\n";
exit( -1 );
}
// extract the "strings" from user-grammar
input -> gen_lex( outFile );
outFile.close();
}
/*-------------------------------------------------------------------------
* input : cd_graph *common* .
*/
void Input::gen_lex( ofstream & ) { }
/*-------------------------------------------------------------------------
* cd_graph = < adjacencies > adjacency-Nlist
* [ "*terminal_sets*" < terminal_sets > vertex-comma_list "." ] .
*/
void Cd_graph::gen_lex( ofstream& outFile )
{
adjacencies -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* adjacency-Nlist ~ adjacency { adjacency } .
*/
void Adjacency_Nlist::gen_lex( ofstream& outFile )
{
Adjacency_list_iterator next_arg( *this );
Adjacency_ each_arg;
while ( each_arg = next_arg() )
each_arg -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* adjacency = < source > vertex < ns > neighbors
* [ "*inherits_from*" < inherits_from > term-comma_list ] "." .
*/
void Adjacency::gen_lex( ofstream& outFile )
{
ns -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* neighbors : neighbors_wc | repetit_n | intermediate_ns *common* .
*/
void Neighbors::gen_lex( ofstream & ) { }
/*-------------------------------------------------------------------------
* neighbors_wc : construct_ns | alternat_ns
* *common* < construct_ns > any_vertex-list .
*/
void Neighbors_wc::gen_lex( ofstream& outFile )
{
construct_ns -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* repetit_n = "~" < sandwiched > kernel-Sandwich .
*/
void Repetit_n::gen_lex( ofstream& outFile )
{
sandwiched -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* kernel-Sandwich = < first > syntax_vertex-list < inner > kernel
* < second > syntax_vertex-list .
*/
void Kernel_Sandwich::gen_lex( ofstream& outFile )
{
first -> gen_lex( outFile );
// more strings in: Kernel.
inner -> gen_lex( outFile );
second -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* kernel = [ < nonempty > term ] "{" < repeated > term-Sandwich "}" .
*/
void Kernel::gen_lex( ofstream& outFile )
{
repeated -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* term-Sandwich = < first > syntax_vertex-list < inner > term
* < second > syntax_vertex-list .
*/
void Term_Sandwich::gen_lex( ofstream& outFile )
{
first -> gen_lex( outFile );
// no strings in: Term.
second -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* syntax_vertex-List ~ { syntax_vertex } .
*/
void Syntax_vertex_List::gen_lex( ofstream& outFile )
{
Syntax_vertex_list_iterator next_arg( *this );
Syntax_vertex_ each_arg;
while ( each_arg = next_arg() )
each_arg -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* any_vertex-List ~ { any_vertex } .
*/
void Any_vertex_List::gen_lex( ofstream& outFile )
{
Any_vertex_list_iterator next_arg( *this );
Any_vertex_ each_arg;
while ( each_arg = next_arg() )
each_arg -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* any_vertex : opt_labeled_term | optional_term | syntax_vertex |
* inherit_term *common* .
*/
void Any_vertex::gen_lex( ofstream& ) { }
/*-------------------------------------------------------------------------
* optional_term = "[" < opt > opt_labeled_term-Sandwich "]" .
*/
void Optional_term::gen_lex( ofstream& outFile )
{
opt -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* opt_labeled_term-Sandwich = < first > syntax_vertex-list
* < inner > opt_labeled_term
* < second > syntax_vertex-List .
*/
void Opt_labeled_term_Sandwich::gen_lex( ofstream& outFile )
{
first -> gen_lex( outFile );
// no strings in: opt_labeled_term.
second -> gen_lex( outFile );
}
/*-------------------------------------------------------------------------
* syntax_vertex : regular_syntax | print_command *common* .
*/
void Syntax_vertex::gen_lex( ofstream& ) { }
/*-------------------------------------------------------------------------
* regular_syntax = < string > string .
*/
int regular_syntax_memberfunc(Universal* reg_syntax1, Universal* reg_syntax2)
/* Comparing function used by the repetition::member() function to see
whether a given reg_syntax2 is equal to one of the reg_syntax1 in a list.
*/
{
return( ((Universal*)reg_syntax1)->g_equal((Universal *)reg_syntax2) == 1 );
}
char* Regular_syntax::get_syntax()
{
return ( string -> get_val() );
}
void Regular_syntax::gen_lex( ofstream &outFile )
/* This is the actual core of the program. Pull out the string and the scanner
will recognize it as a special pattern. To store the strings of the reg-
syntax's that are already generated an Any_vertex_list is used. This avoids
creating a new class List(String). */
{
static Any_vertex_List* already_generated = new Any_vertex_List();
if ( !already_generated -> member( this, regular_syntax_memberfunc ) ) {
outFile << "\"" << string -> get_val() << "\"\t\treturn(PATTERN);\n";
already_generated -> append( this );
}
}