📄 codegen.cpp
字号:
fprintf(a, "-1, 0, ");
else
{
assert(exc_data.size()==1);
fprintf(a, "%d, %d, ", exc_location, exc_data[0]);
}
int l2_line=data.tables.layer1_to_layer2[l1_line];
offset=data.tables.line_to_offset_in_table_of_lines[l2_line];
}
fprintf(a, "table_of_lines%s", printable_increment(offset));
}
else
{
fprintf(a, "{ ");
for(int j=0; j<data.number_of_symbol_classes; j++)
{
if(j) fprintf(a, ", ");
// all state numbers are incremented by one.
fprintf(a, "%d", data.final_automaton[i].transitions[j]+1);
}
fprintf(a, " }");
}
// all action numbers are also incremented by one.
fprintf(a, ", %d", data.final_automaton[i].action_accepted_here+1);
if(data.variables.generate_arbitrary_lookahead_support)
fprintf(a, ", %s", (data.final_automaton[i].actions_that_need_lookahead_here.size()>0 ? "true" : "false"));
fprintf(a, " }");
}
fprintf(a, "\n};\n");
}
void generate_table_of_lines(FILE *a)
{
fprintf(a, "\nconst %s %s::table_of_lines[%s::size_of_table_of_lines]={\n",
data.variables.analyzer_state_type,
data.variables.dolphin_class_name,
data.variables.dolphin_class_name);
TablePrinter tp(a, "\t", "%3d", 12);
tp.print(data.tables.compressed_table_of_lines);
fprintf(a, "\n};\n");
}
void generate_table_of_symbol_classes(FILE *a)
{
fprintf(a, "\nconst int %s::symbol_to_symbol_class[%s::alphabet_cardinality]={\n",
data.variables.dolphin_class_name,
data.variables.dolphin_class_name);
TablePrinter tp(a, "\t", "%3d", 12);
tp.print(data.symbol_to_symbol_class);
fprintf(a, "\n};\n");
}
void generate_table_of_lookahead_states(FILE *a)
{
fprintf(a, "\nconst %s %s::lookahead_states[%s::size_of_table_of_lookahead_states]={\n",
data.variables.analyzer_state_type,
data.variables.dolphin_class_name,
data.variables.dolphin_class_name);
TablePrinter tp(a, "\t", "%3d", 12);
tp.print(data.tables.compressed_table_of_lookahead_states);
fprintf(a, "\n};\n");
}
// the table of actions is used to implement lookahead
void generate_table_of_actions(FILE *a)
{
#if 0
fprintf(a, "\nconst int %s::action_to_recognized_expression[%s::number_of_actions+1]={\n",
data.variables.dolphin_class_name,
data.variables.dolphin_class_name);
TablePrinter tp(a, "\t", "%3d", 12);
tp.print(data.tables.action_to_recognized_expression);
fprintf(a, "\n};\n");
#endif
const int actions_per_line=2;
fprintf(a, "\nconst %s::ActionData %s::actions[%s::number_of_actions+1]={\n\t",
data.variables.dolphin_class_name,
data.variables.dolphin_class_name,
data.variables.dolphin_class_name);
fprintf(a, "{ ");
if(data.variables.generate_arbitrary_lookahead_support &&
data.variables.generate_fixed_length_lookahead_support)
{
fprintf(a, "0, NULL, 0");
}
else if(data.variables.generate_fixed_length_lookahead_support)
{
assert(!data.variables.generate_arbitrary_lookahead_support);
fprintf(a, "0");
}
else if(data.variables.generate_arbitrary_lookahead_support)
{
assert(!data.variables.generate_fixed_length_lookahead_support);
fprintf(a, "NULL, 0");
}
if(data.variables.generate_eof_lookahead_support)
{
if(data.variables.generate_fixed_length_lookahead_support ||
data.variables.generate_arbitrary_lookahead_support)
{
fprintf(a, ", ");
}
fprintf(a, "0");
}
fprintf(a, " }");
for(int i=0; i<data.actions.size(); i++)
{
fprintf(a, ((i+1)%actions_per_line==0 ? ",\n\t" : ", "));
int re_number=data.actions[i].recognized_expression_number;
RecognizedExpressionData &re=data.recognized_expressions[re_number];
fprintf(a, "{ ");
bool comma_needed=false;
if(data.variables.generate_fixed_length_lookahead_support)
{
fprintf(a, "%d", re.lookahead_length);
comma_needed=true;
}
if(data.variables.generate_arbitrary_lookahead_support)
{
if(comma_needed)
fprintf(a, ", ");
else
comma_needed=true;
if(re.lookahead_length==-1)
{
int offset=data.tables.offset_in_table_of_lookahead_states[re_number];
int number=data.tables.number_of_lookahead_states[re_number];
fprintf(a, "lookahead_states%s, %d", printable_increment(offset), number);
}
else
fprintf(a, "NULL, 0");
}
if(data.variables.generate_eof_lookahead_support)
{
if(comma_needed)
fprintf(a, ", ");
else
comma_needed=true;
fprintf(a, "%d", re.lookahead_eof);
}
comma_needed;
fprintf(a, " }");
}
fprintf(a, "\n};\n");
}
void generate_table_of_initial_states(FILE *a)
{
fprintf(a, "\nconst %s %s::initial_dfa_states_for_start_conditions[%s::number_of_start_conditions]={\n",
data.variables.analyzer_state_type,
data.variables.dolphin_class_name,
data.variables.dolphin_class_name);
TablePrinter tp(a, "\t", "%3d", 12);
tp.print(data.tables.start_condition_to_dfa_state_table);
fprintf(a, "\n};\n");
}
// this function must be run twice: before DolphinLexicalAnalyzer class with
// mode==1 and after DolphinLexicalAnalyzerClass with mode==2
void generate_whale_emulator(FILE *a, int mode)
{
assert(data.variables.using_whale && data.variables.whale_emulation_mode);
assert(mode==1 || mode==2);
if(mode==1)
{
fprintf(a, "\n"
"/******************************/\n"
"/* Whale emulation mode */\n"
"/******************************/\n");
}
else
fprintf(a, "\n"
"/* Whale emulator (continued) */\n");
fprintf(a, "namespace %s\n", data.variables.whale_namespace);
fprintf(a, "{\n");
if(mode==1)
{
fprintf(a, "\tstruct Symbol\n"
"\t{\n"
"\t};\n");
fprintf(a, "\tstruct Terminal : Symbol\n"
"\t{\n"
"\t\tvirtual int number()=0;\n"
"\t\t\n"
"\t\tint line, column;\n"
"\t\t%s *text;\n"
"\t};\n", data.variables.internal_char_type);
fprintf(a, "\tstruct Nonterminal : Symbol\n"
"\t{\n"
"\t};\n");
fprintf(a, "\tstruct TerminalEOF;\n");
fprintf(a, "\tstruct TerminalError;\n");
}
if(mode==2)
{
// generating all terminal classes referenced from the file.
set<char *, NullTerminatedStringCompare> terminal_classes;
for(int i=0; i<data.actions.size(); i++)
{
if(typeid(*data.actions[i].declaration->action)==typeid(NonterminalActionReturn))
terminal_classes.insert(dynamic_cast<NonterminalActionReturn *>(data.actions[i].declaration->action)->return_value->text);
}
terminal_classes.insert("TerminalEOF");
terminal_classes.insert("TerminalError");
int counter=0;
for(set<char *, NullTerminatedStringCompare>::iterator p=terminal_classes.begin(); p!=terminal_classes.end(); p++)
fprintf(a, "\tstruct %s : Terminal\n"
"\t{\n"
"\t\tvirtual int number() { return %u; }\n"
"\t};\n", *p, counter++);
// generating a single nonterminal
fprintf(a, "\tstruct NonterminalS : Nonterminal\n"
"\t{\n"
"\t\tstd::vector<Terminal *> terminals;\n"
"\t};\n");
// generating a dummy parser
fprintf(a, "\n\tclass DummyParser\n");
fprintf(a, "\t{\n");
fprintf(a, "\t\t%s &dolphin;\n", data.variables.dolphin_class_name);
fprintf(a, "\t\t\n");
fprintf(a, "\tpublic:\n");
fprintf(a, "\t\tDummyParser(%s &lexical_analyzer) : dolphin(lexical_analyzer)\n", data.variables.dolphin_class_name);
fprintf(a, "\t\t{\n");
fprintf(a, "\t\t}\n");
fprintf(a, "\t\tNonterminalS *parse()\n");
fprintf(a, "\t\t{\n");
fprintf(a, "\t\t\tNonterminalS *S=new NonterminalS;\n");
fprintf(a, "\t\t\t\n");
fprintf(a, "\t\t\tfor(;;)\n");
fprintf(a, "\t\t\t{\n");
fprintf(a, "\t\t\t\tTerminal *t=dolphin.get_token();\n");
fprintf(a, "\t\t\t\tif(typeid(*t)==typeid(TerminalEOF))\n");
fprintf(a, "\t\t\t\t\treturn S;\n");
fprintf(a, "\t\t\t\tS->terminals.push_back(t);\n");
fprintf(a, "\t\t\t}\n");
fprintf(a, "\t\t}\n");
fprintf(a, "\t};\n");
}
fprintf(a, "\n} // namespace %s\n", data.variables.whale_namespace);
if(mode==2)
fprintf(a, "\ntypedef %s::DummyParser %sParser;\n", data.variables.whale_namespace, data.variables.whale_namespace);
}
void print_parametrized_string(FILE *a, char *s, char *parameters, char *values[])
{
bool after_dollar=false;
for(int i=0; s[i]; i++)
{
char c=s[i];
if(after_dollar)
{
if(c=='$')
fputc('$', a);
else if(c<=' ' || c>=128)
fprintf(a, "$%c", c);
else
{
bool local_flag=false;
for(int j=0; j<parameters[j]; j++)
if(parameters[j]==c)
{
fprintf(a, "%s", values[j]);
local_flag=true;
break;
}
assert(local_flag);
}
after_dollar=false;
}
else if(c=='$' && s[i+1])
after_dollar=true;
else
fputc(c, a);
}
}
void generate_action(FILE *a, const char *indent, ActionData &action, bool break_after)
{
if(typeid(*action.declaration->action)==typeid(NonterminalActionReturn))
{
NonterminalActionReturn &a_ret=*dynamic_cast<NonterminalActionReturn *>(action.declaration->action);
fprintf(a, "%s", indent);
char *parameter_values[]={a_ret.return_value->text};
print_parametrized_string(a, data.variables.how_to_return_token, "t", parameter_values);
fprintf(a, "\n");
}
else if(typeid(*action.declaration->action)==typeid(NonterminalActionSkip))
{
if(data.variables.generate_verbose_prints)
fprintf(a, "%scout << \x22skipping\\n\x22;\n", indent);
if(break_after)
fprintf(a, "%sbreak;\n", indent);
}
else if(typeid(*action.declaration->action)==typeid(NonterminalActionCodeII))
{
NonterminalActionCodeII &a_code2=*dynamic_cast<NonterminalActionCodeII *>(action.declaration->action);
fprintf(a, "%s", indent);
fprintf(a, "%s", a_code2.s.c_str());
fprintf(a, "\n");
if(break_after)
fprintf(a, "%sbreak;\n", indent);
}
}
void generate_actions_for_special_expression(FILE *a, const char *indent, RecognizedExpressionData &re, bool break_after)
{
assert(re.start_condition_to_action_number.size());
int an0=re.start_condition_to_action_number[0];
bool one_action=true;
for(int i=1; i<re.start_condition_to_action_number.size(); i++)
if(re.start_condition_to_action_number[i]!=an0)
{
one_action=false;
break;
}
if(one_action)
generate_action(a, indent, data.actions[an0], break_after);
else
{
fprintf(a, "%sswitch(start_condition)\n", indent);
fprintf(a, "%s{\n", indent);
set<int> action_numbers;
for(int i=0; i<re.start_condition_to_action_number.size(); i++)
action_numbers.insert(re.start_condition_to_action_number[i]);
action_numbers.erase(-1);
string further_indent=string(indent)+string("\t");
for(set<int>::iterator p=action_numbers.begin(); p!=action_numbers.end(); p++)
{
for(int i=0; i<re.start_condition_to_action_number.size(); i++)
if(re.start_condition_to_action_number[i]==*p)
fprintf(a, "%scase %s:\n", indent, data.start_conditions[i].name);
generate_action(a, further_indent.c_str(), data.actions[*p], true);
}
fprintf(a, "%s}\n", indent);
if(break_after)
fprintf(a, "%sbreak;\n", indent);
}
}
string expression_for_initial_state()
{
if(data.variables.start_conditions_enabled)
return string("initial_dfa_states_for_start_conditions[start_condition]");
else
return string("initial_dfa_state");
}
bool type_is_a_pointer(char *s)
{
for(int i=strlen(s)-1; i>=0; i++)
if(s[i]=='*')
return true;
else if(s[i]>' ')
return false;
return false;
}
bool type_should_be_printed_without_space(char *s)
{
int l=strlen(s);
if(l<3) return false;
return s[l-1]=='*' && s[l-2]==' ';
}
//void insert_cpp_code_in_file(FILE *a, const char *indent, Terminal *code)
//{
//}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -