initial
[prop.git] / prop-src / metasyntax.pcc
blob7effc1cbf317f7109d2aa29b991709b42e414f25
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 //  This file implements the meta-syntax compiler. 
4 //
5 ///////////////////////////////////////////////////////////////////////////////
6 #include <iostream.h>
7 #include "metasyntax.ph"
8 #include "ir.ph"
9 #include "ast.ph"
10 #include "hashtab.h"
11 #include "options.h"
13 ///////////////////////////////////////////////////////////////////////////////
15 //  Implementation of the meta syntax compiler
17 ///////////////////////////////////////////////////////////////////////////////
18 class MetaSyntaxCompilerImpl {
19     MetaSyntaxCompilerImpl(const MetaSyntaxCompilerImpl&);
20     void operator = (const MetaSyntaxCompilerImpl&);
21 public:
23     size_t    memory_used;   // total memory used for the parsers and lexers
24     HashTable grammar_map;   // mapping from name to grammar
25     int       timer;         // use count timer
27     MetaSyntaxCompilerImpl() 
28        : memory_used(0),
29          grammar_map(string_hash,string_equal)
30          {}
33 ///////////////////////////////////////////////////////////////////////////////
35 //  Definition of a grammar record
37 ///////////////////////////////////////////////////////////////////////////////
38 struct GrammarRecord {
39    Id      grammar_name;   // grammar name
40    GramExp grammar_exp;    // grammar expression   
41    size_t  memory_used;    // memory used for this grammar
42    int     last_used;      // time of last use
43    int     use_count;      // number of uses
46 ///////////////////////////////////////////////////////////////////////////////
48 //  Constructor and destructor
50 ///////////////////////////////////////////////////////////////////////////////
51 MetaSyntaxCompiler:: MetaSyntaxCompiler()
52    : impl(new MetaSyntaxCompilerImpl)
53      {}
54 MetaSyntaxCompiler::~MetaSyntaxCompiler() 
55      { delete impl; }
57 ///////////////////////////////////////////////////////////////////////////////
59 //  Method to compile a grammar give it an unique name.
60 //  We'll invoke the parser generator subclass to create a new parser.
61 //  Then the parser table is stored inside internal tables. 
63 ///////////////////////////////////////////////////////////////////////////////
64 void MetaSyntaxCompiler::install_grammar(Id grammar_name, GramExp grammar)
65 {  gen_parser(grammar_name, grammar); 
68 ///////////////////////////////////////////////////////////////////////////////
70 //  Method to parse the text as an expression.  
72 ///////////////////////////////////////////////////////////////////////////////
73 Exp MetaSyntaxCompiler::parse_exp (Id           grammar_name,
74                                    const char * text
75                                   )
76 {  error ("%Lunrecognized quoted expression `%s`\n",text);
77    return NOexp;
80 ///////////////////////////////////////////////////////////////////////////////
82 //  Method to parse the text as a pattern.
84 ///////////////////////////////////////////////////////////////////////////////
85 Pat MetaSyntaxCompiler::parse_pat (Id           grammar_name,
86                                    const char * text
87                                   )
88 {  error ("%Lunrecognized quoted pattern `%s`\n",text);
89    return NOpat;
92 ///////////////////////////////////////////////////////////////////////////////
94 //  Method to flush out a grammar when memory is low.
95 //  This is invoked whenever a new grammar is to be compiled
96 //  and the total memory used has reached a limit.   The least
97 //  recently used grammars are flushed in this process. 
99 ///////////////////////////////////////////////////////////////////////////////
100 void MetaSyntaxCompiler::flush_grammar (size_t memory_needed)
101 {  long memory_to_free = memory_needed;
102    while (memory_to_free > 0 && impl->grammar_map.size() > 0)
103    {  GrammarRecord * kill_candidate = 0; // the candidate to invalidate.
104       HashTable& grammar_map = impl->grammar_map; 
106       // Locate the least frequently used entry
107       foreach_entry(e,grammar_map)
108       {  if (kill_candidate == 0 || 
109              ((GrammarRecord *)(e->v))->use_count < kill_candidate->use_count)
110             kill_candidate = (GrammarRecord *)(e->v);
111       }
112       // Locate the oldest used entry
113       foreach_entry(e,grammar_map)
114       {  if (kill_candidate == 0 || 
115              ((GrammarRecord *)(e->v))->last_used < kill_candidate->last_used)
116             kill_candidate = (GrammarRecord *)(e->v);
117       }
118       // Kill entry and update the available memory
119       if (kill_candidate)
120       {  if (options.generate_report)
121              open_logfile() << "[Invalidating meta-language '" 
122                             << kill_candidate->grammar_name << "']\n";
123          impl->memory_used -= kill_candidate->memory_used;
124          memory_to_free    -= kill_candidate->memory_used;
125       }
126    }
129 ///////////////////////////////////////////////////////////////////////////////
131 //  Method to generate a report of all the grammars generated.
133 ///////////////////////////////////////////////////////////////////////////////
134 ostream& MetaSyntaxCompiler::print_report(ostream& f)
135 {   
136     return f;