/************************************************************************** * 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 ); } }