Re: [Xtcc-developer] Chat with pompon.pompon@gmail.com
Market Research Data Processing Suite
Status: Alpha
Brought to you by:
neilxdsouza
|
From: Neil D'S. <nei...@gm...> - 2010-06-05 06:23:28
|
Hi Pompon,
After the call to yyparse() in main.cpp, if we output "input
successfully parse", it means that the the abstract syntax tree is built by
the parser.
At this point "qscript_parser::tree_root" is a pointer to the root of
the tree.
You will notice that the function GenerateCode in qscript_parser.cpp is
the one which initiates the code generation. The correct virtual function
will be called automatically and generate the code for each statement.
For generating the map, you are only interested in "question
statements".
You could write a function something like this
VisitStatementsAndPrintMap(AbstractStatement * stmt_ptr)
{
if(AbstractQuestion * q =
dynamic_cast<AbstractQuestion*>(stmt_ptr)){
PrintMap(q);
// or ostringstream map (defined elsewhere as a
global variable)
// q->PrintMap(map);
} else if (IfStatement * if_stmt =
dynamic_cast<IfStatement*>(stmt_ptr)){
VisitStatementsAndPrintMap( if_stmt->ifBody_);
if(if_stmt->elseBody_){
PrintMap( if_stmt->ifBody_);
}
} else if (CompoundStatement * cmpd_stmt =
dynamic_cast<CompoundStatement*>(stmt_ptr)){
VisitStatementsAndPrintMap(cmpd_stmt->compoundBody_);
} else if (ForStatement * ...){
.
.
.
}
}
The call would be after GenerateCode
if( !yyparse() && !no_errors){
cout << "Input parsed sucessfully: generating code" << endl;
//data_entry_loop();
qscript_parser::GenerateCode();
VisitStatementsAndPrintMap (qscript_parser::tree_root); //
} else {
cerr << "There were : " << no_errors << " errors in parse" << endl;
}
I know that the dynamic casts are ugly. However we are not interested in
cases like ExpressionStatement - which have no effect on the map.
If you want to avoid the dynamic casts - have a look at my implementation
of GetQuestionNames
I have implemented the base class version of this function i.e. it is not
purely virtual because I want the default implementation for most
statements.
However in question.h, I have overridden this function to print out the
question names when it reaches a question statement.
The work done by this function is essential in implementing the navigation
through the questionnaire. Its main output is in marking, questions in other
branches of the if statement as not visited.
run the compiler on the inputs "inp_if_else_branches" and
"inp_if_else_branches_2"
the code in the ouptut like below - is built with the help of
GetQuestionNames.
q7->isAnswered_=false;
q8->isAnswered_=false;
q9->isAnswered_=false;
q10->isAnswered_=false;
q11->isAnswered_=false;
The reason I am pointing you to this is to use the same technique to
generate the map if you want to avoid the dynamic casts - a default base
implementation for most statements, and overriding that function where you
need a different behaviour(when you hit question statements for example you
want to output to the map file)
About the memory leaks, ignore them. I used valgrind the other day just for
a hygiene check and have identified most cases and fixed them, and one case
am aware of the problem and set an appropriate output which can be tackled
later.
Regards,
Neil
On Sat, Jun 5, 2010 at 1:04 AM, pom...@gm... <
pom...@gm...> wrote:
>
> These messages were sent while you were offline.
>
> 1:04 AM pom...@gm...: I've tried to modify the
> simple_compiler/src/main.cpp to make it only parsing the script and then
> eventually generating the record map. However, I don't know qscript's
> internal dependencies. For example reduction of main.cpp:
> #include "qscript_parser.h"
> #include <iostream>
> #include <fstream>
>
> void yyrestart(FILE *);
> int yyparse();
>
> void InitStatement();
>
> int main(int argc, char* argv[])
> {
> std::cout << "---InitStatement" << std::endl;
>
> InitStatement();
> qscript_parser::active_scope = new Scope();
> qscript_parser::active_scope_list.push_back(qscript_parser::active_scope);
>
> std::cout << "---yyrestart" << std::endl;
> yyrestart(stdin);
> std::cout << "--yyparse" << std::endl;
> if(!yyparse() && !qscript_parser::no_errors) std::cout << "Input parsed
> sucessfully" << std::endl;
> else std::cout << "There were : " << qscript_parser::no_errors << " errors
> in parse" << std::endl;
>
> ////////////////////////////////
> try
> {
> std::ofstream conf;
> conf.exceptions(std::ios::failbit | std::ios::badbit);
> conf.open("a.cfg");
>
> std::vector<AbstractQuestion*> &qv = qscript_parser::question_list;
> conf << qv.size() << '\n';
> for(int i=0; i<qv.size(); ++i)
> {
> conf << qv[i]->questionName_ << ' ';
> switch(qv[i]->dt)
> {
> case INT8_TYPE : conf << "int8" ; break;
> case INT16_TYPE : conf << "int16" ; break;
> case INT32_TYPE : conf << "int32" ; break;
> case FLOAT_TYPE : conf << "float" ; break;
> case DOUBLE_TYPE: conf << "double"; break;
> default: conf << "Unrecognised type";
> }
> conf << ' ';
> NamedStubQuestion *nsq = dynamic_cast<NamedStubQuestion*>(qv[i]); if(nsq)
> conf << nsq->nr_ptr->name;
> conf << '\n';
> }
>
> std::vector<named_range*> &nsl = qscript_parser::named_stubs_list;
> for(int i=0; i<nsl.size(); ++i)
> {
> conf << nsl[i]->name;
> std::vector<stub_pair> &sv = nsl[i]->stubs;
> for(int i=0; i<sv.size(); ++i) conf << ' ' << sv[i].code << " \"" <<
> sv[i].stub_text << '\"';
> conf << '\n';
> }
> }
> catch(...){ std::cout << "error while generating configuration file\n"; }
> ////////////////////////////////
>
> return qscript_parser::no_errors;
> }
> ------------------------------
> 33 minutes
> 1:38 AM pom...@gm...: getting this for ./qscript <
> simple_compiler/inputs/inp:
> --InitStatement
> ---yyrestart
> --yyparse
> question_list: questions are
> q1
> here i am not catching the DeclarationStatement returned below: so its a
> memory leak: 945q.ypp
> parsed range question : q1
> - why am i not freeing this?: FILE: q.ypp, line:264
> -- why am i not freeing this?: FILE: q.ypp, line:264
> -- why am i not freeing this?: FILE: q.ypp, line:264
> question_list: questions are
> q1
> q2
> here i am not catching the DeclarationStatement returned below: so its a
> memory leak: 945q.ypp
> parsed range question : q2
> parsed named question : q3
> parsed named question : q4
> parsed named question : q4_2
> parsed named question : q4_3
> parsed named question : q4_5
> -- why am i not freeing this?: FILE: q.ypp, line:264
> -- why am i not freeing this?: FILE: q.ypp, line:264
> -- why am i not freeing this?: FILE: q.ypp, line:264
> -- why am i not freeing this?: FILE: q.ypp, line:264
> flagIsAForBody_: 3
> parsed named question : q17
> flagIsAForBody_: 1
> question_list: questions are
> q1
> q2
> q3
> q4
> q4_2
> q4_3
> q4_5
> q17
> q15
> here i am not catching the DeclarationStatement returned below: so its a
> memory leak: 945q.ypp
> parsed range question : q15
> Input parsed sucessfully
> ------------------------------
> 5 minutes
> 1:43 AM pom...@gm...: I'm afraid with these 'memory leaks' -
> actually I hardly know what I'm doing. Can you point me out, how should I
> use the q.ypp to get the info required for record map? Sorry, but I still
> have no experience in yacc and I don't know what to start with.
>
|