1 ///////////////////////////////////////////////////////////////////////////////
3 // This file implements the meta-syntax compiler.
5 ///////////////////////////////////////////////////////////////////////////////
7 #include "metasyntax.ph"
13 ///////////////////////////////////////////////////////////////////////////////
15 // Implementation of the meta syntax compiler
17 ///////////////////////////////////////////////////////////////////////////////
18 class MetaSyntaxCompilerImpl {
19 MetaSyntaxCompilerImpl(const MetaSyntaxCompilerImpl&);
20 void operator = (const MetaSyntaxCompilerImpl&);
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()
29 grammar_map(string_hash,string_equal)
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)
54 MetaSyntaxCompiler::~MetaSyntaxCompiler()
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,
76 { error ("%Lunrecognized quoted expression `%s`\n",text);
80 ///////////////////////////////////////////////////////////////////////////////
82 // Method to parse the text as a pattern.
84 ///////////////////////////////////////////////////////////////////////////////
85 Pat MetaSyntaxCompiler::parse_pat (Id grammar_name,
88 { error ("%Lunrecognized quoted pattern `%s`\n",text);
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);
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);
118 // Kill entry and update the available memory
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;
129 ///////////////////////////////////////////////////////////////////////////////
131 // Method to generate a report of all the grammars generated.
133 ///////////////////////////////////////////////////////////////////////////////
134 ostream& MetaSyntaxCompiler::print_report(ostream& f)