xtcc-developer Mailing List for Xross Tab / QScript
Market Research Data Processing Suite
Status: Alpha
Brought to you by:
neilxdsouza
You can subscribe to this list here.
| 2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(3) |
Jun
(7) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Neil D'S. <nx...@ya...> - 2012-06-23 11:12:46
|
http://janneedle.com/.Trashes/google.html?rerpm=rc.mig&jmi=yug.ytf&snbebf=dewr |
|
From: Neil D'S. <nei...@gm...> - 2010-07-23 17:12:02
|
Excellent! Exactly what we want. The overall structure of what we want is now in place for the pdf export. Later we will need to add things like a company logo, encapsulated postscript etc, which I have no clue about. I have been working on the for loop error checks and much of the things you pointed out are in place. I have also setup a few cases of the test-suite using dejagnu (yes another package that needs to be gotten familiar with - but dont worry for now). There is a new rule in the CustomQscriptMakefile - "check" which runs the test suite. You need to install "dejagnu" to run the test suite. Regards, Neil On Thu, Jul 22, 2010 at 9:35 PM, pom...@gm... < pom...@gm...> wrote: > > These messages were sent while you were offline. > > 9:35 PM pompon: <pom...@gm...> hi there, look at > pdf_export/test/inp.pdf. Is it ok now? > |
|
From: Neil D'S. <nei...@gm...> - 2010-06-10 05:57:09
|
Hi Pompon,
I need to add a note about array questions in the format_specification
(DummyArrayQuestion), however what we have right now is excellent. I am
still continuing to work on the array question navigation.
Here are a few of the next steps.
1) Create an ncurses interface in the generated exe script - where the
questions are displayed in 1 window, the stubs are displayed in another
window and a 3 rd window is used for the data entry and navigation.
2) Generate a pdf out of the question script, which can be printed.
3) Extend the grammar so that the end user can input the questionnaire
in multiple languages. This requires the creation of a section in the
questionnaire, 1 for each language.
If you find anything interesting in these, let me know.
regards,
NxD
On Wed, Jun 9, 2010 at 9:41 PM, pom...@gm... <
pom...@gm...> wrote:
>
> These messages were sent while you were offline.
>
> 9:41 PM <pom...@gm...>pompon:
> integrated_parsing/format_specification
>
|
|
From: Neil D'S. <nei...@gm...> - 2010-06-09 04:40:35
|
On Tue, Jun 8, 2010 at 5:29 PM, pom...@gm... <
pom...@gm...> wrote:
>
> These messages were sent while you were offline.
>
> 5:29 PM pompon: 'make -f CustomQScript local_install' fails because
> simple_compiler/make-build-dir/compiletime_lib is not being created.
>
NxD: I have added "compiletime_lib" to the subversion
repository
> ------------------------------
> 55 minutes
> 6:24 PM pompon: "I cannot eliminate the readline dependency right now" - I
> didn't mean to eliminate the dependency, but add dependency to the
> qscript_compiletime, so as to make it require the libreadline.so
> 6:29 PM as you can see in data_conv/branches/integrated_parsing/main.cpp I
> wrote a specification for the binary output file for now
> 6:30 PM I need a specification for input data files - do you have it
> somewhere, or shall I write it too?
>
" <question> = <question name> ' ' <type> ' '
<first byte> ' ' <last byte> '\n' "
I have looked at the map, in main.cpp. Implied is
single coded/ multi coded can be determined by ( "last byte" - "first
byte")/sizeof(type), so we do not need to mention this in the map.
The input for the data file is the "1.dat", "2.dat"
files which are generated by the qscript generated exe. You can go ahead and
write a specification. I am currently concentrating on the navigation for
array questions and will shift my focus to the data part once we have the
array navigation working at a basic level of functionality. Please send me a
draft spec.
Thanks,
NxD
|
|
From: Neil D'S. <nei...@gm...> - 2010-06-08 06:23:28
|
Hi Pompon,
I have made a new library libqscript_compiletime which contains the
parser. I cannot eliminate the readline dependency right now - the
AbstractQuestion::GetDataFromUser() functions in question.cpp make calls to
it ( through read_data)
run an "svn update" and have a look at my changes to
simple_compile/CustomQScriptMakefile and note the change in
integrated_parsing/Makefile
Regards,
Neil
On Tue, Jun 8, 2010 at 12:36 AM, pom...@gm... <
pom...@gm...> wrote:
> 12:16 AM pom...@gm...: are you there?
> me: hi - yes very much.
> 12:17 AM in fact I was just going to mesg you
> pom...@gm...: update svn
> and look at data_conv/branches/integrated_parsing/Makefile
> 12:18 AM I hoped that I'll find all parsing functions in the
> libqscript_runtime.so
> 12:19 AM namely InitStatement(),yyrestart() and yyparse()
> what do you think about it?
> 12:20 AM me: i dont think all the parsing functions are there - let me
> have a look at the makefile which generates the runtime library
> pom...@gm...: can you add them?
> 12:21 AM and libreadline.so
> 12:22 AM me: the include and lib directories - can you set them as a
> relative symbolic link
> 12:23 AM i.e. using ../../../qscript/stubs/simple_compiler/include/
> pom...@gm...: whoops
> 12:28 AM done
> 12:29 AM works now?
> 12:30 AM me: I already updated the link here. I have modified the runtime
> Makefile to include q.cpp into the runtime library - this is the one which
> will add yyparse() into the library
> 12:32 AM pom...@gm...: what about lreadline?
> me: readline should be installed in your /usr/lib
> 12:33 AM just working on the boot -lfilesystem
> 12:34 AM pom...@gm...: ./lib//libqscript_runtime.so: undefined
> reference to `readline'
> 12:35 AM I'd like not compiling with -lreadline, since it is used only by
> parsing functions
> me: try dropping it
> pom...@gm...: so qscript_runtine should have a dependency on
> readline
> 12:36 AM already tried
> if not compiled with -lreadline, I've got: ./lib//libqscript_runtime.so:
> undefined reference to `readline'
> 12:38 AM me: I need to read my boost filesystem documentation for 1.43 to
> figure out why it doesnt compile. Can I get back to you tomorrow?
> pom...@gm...: ok
> 12:39 AM me: thanks - I will drop you a mail if I figure it out
>
|
|
From: Neil D'S. <nei...@gm...> - 2010-06-08 06:08:28
|
Hi Pompon, These functions are excluded from the runtime as they are not needed when we are running the generated executable. i.e. qscript -f inp -> test_script.C Compile test_script.C -> final executable - this needs the runtime environment but yyparse() etc are not needed here. Regards, Neil On Tue, Jun 8, 2010 at 12:10 AM, pom...@gm... < pom...@gm...> wrote: > > These messages were sent while you were offline. > > 12:10 AM pom...@gm...: why InitStatement(),yyrestart() and > yyparse() aren't in libqscript_runtime.so? > |
|
From: Neil D'S. <nei...@gm...> - 2010-06-07 12:49:18
|
Hi Pompon,
I have just run your code and made the ifBody_, elseBody_ as public in
IfStatement and ran the code on the data. The output is fine, excellent
work!
We just need to adjust the output to format in "sample_file_format.C"
. You will find this file in the qscript/stubs/data-file-standard directory.
As always, drop me a line if you have any question.
Kind Regards,
NxD
On Sun, Jun 6, 2010 at 10:37 PM, Neil D'Souza
<nei...@gm...>wrote:
> Hi Pompon,
>
> Thanks for this - I will test your code out - I have just finished a
> massive change to the compiler - GenerateCode and PrintExpressionCode - now
> write to "Code" Objects because I realised that I needed another stream to
> handle array questions navigation correctly and this will save us changing
> function signatures in the future should we need another output stream when
> generating code.
>
> look at the comment at the beginning. What shall we do?IfStatement::ifBody_
> ::elseBody_cannot be accessed from TextMapGenerator
>
> reason: IfStatement::ifBody_ ::elseBody are protected
> solution: make public or make friend with TextMapGenerator NxD: make it
> public, right now lets not worry about encapsulation etc, give it what it
> wants to make it compile.
>
>
> And please verify if my main(){} properly performs the parsing.
> NxD: It should work fine - after the call to yyparse() the parse trees are
> built. Once I replace the main.cpp with this one I will come to know. Will
> work on it tomorrow.
>
> what is DummyArrayQuestion and how to deal with it?
> NxD: When reading data from the disk we need to know the dimension of any
> array questions based on the level of nesting inside the for loop
> I came up with this idea to write the dimension of the array while saving
> the data. You will notice that DummyArrayQuestion has an empty
> implementation of GenerateCode,
> i.e. this question is not asked to the end user. However, it does have an
> implementation of WriteDataToDisk - which writes out the bounds of the array
> to the disk. The DummyArrayQuestion is created in the question
> definitions sections and added to the "question_list" just like an ordinary
> question. When write_data_to_disk is called, it iterates over every question
> in "question_list" and will invoke the DummyArrayQuestion::WriteDataToDisk
> function storing the BOUNDS of the array to the data file.
>
> is line "qscript_parser::GenerateCode()" necessary for anything
>
> NxD: This innocent looking function is the one that generates the code in
> test_statement.C - it is the code generation phase, visiting each node in
> qscript_parser::tree_root and generating code.
>
> Do you want me to integrate your parsing with my files to data_conv, so as
> to avoid the intermediate config file?
> If you can set it up as a symbolic link, or use the files in the
> simple_compiler/include directory after an install is done, it would be
> great. We should be using only 1 parser file otherwise we will be
> maintaining 2 files which will lead to a mess sooner or later.
>
> The other option is to integrate the data_conv code with the code in the
> qscript folder.
> For this case, we could have the following 1) Default Behaviour: When the
> compiler generates code for data entry of a questionnaire it also generates
> a map
> 2) We create a command line option to write out the datafile according to
> the map. When invoked with this option the compiler will write a program
> that recodes the data according to a map.
> If you are not happy with my suggestion above, feel free to suggest
> something better.
>
> Rgds,
> NxD
>
>
>
>> These messages were sent while you were offline.
>>
>> 7:09 PM pompon: I've written text map generator according to the
>> instructions from your last mail. Here it is (replacement for
>> qscript/src/main.cpp - map is printed to stdout - nothing interesting by
>> now):
>> /*
>> stmt.h: IfStatement::ifBody_ ::elseBody cannot be accessed from
>> TextMapGenerator
>> reason: IfStatement::ifBody_ ::elseBody are protected
>> solution: make public or make friend with TextMapGenerator
>> */
>>
>> #include "qscript_parser.h"
>> #include <iostream>
>> #include <fstream>
>> //#include <typeinfo>
>>
>> #define REP(i,n) for(int i=0; i<(n); ++i)
>>
>> class TextMapGenerator
>> {
>> public:
>> std::vector<AbstractQuestion*> question;
>> std::vector<named_range*> range;
>>
>> static const char *text(DataType dt)
>> {
>> switch(dt)
>> {
>> case INT8_TYPE : return "int8" ; case INT16_TYPE : return "int16" ;
>> case INT32_TYPE : return "int32" ; case FLOAT_TYPE : return "float" ;
>> case DOUBLE_TYPE: return "double"; default: return "<unrecognized type>";
>> }
>> }
>>
>> void visit(AbstractStatement *stmt, int depth = 0)
>> {
>> if(!stmt) return;
>> string pre="";//(depth,' ');
>> //std::ostream &os = std::cout;
>> if(AbstractQuestion *q = dynamic_cast<AbstractQuestion*>(stmt))
>> {
>> question.push_back(q);
>> /*os << pre << "[AbstractQuestion] " << q->questionName_ << ' ';
>>
>> os << std::endl;*/
>> }
>> else if(CompoundStatement *cs = dynamic_cast<CompoundStatement*>(stmt))
>> {
>> //os << pre << "[CompoundStatement]" << std::endl;
>> visit(cs->compoundBody_,depth+1);
>> }
>> else if(ForStatement *fs = dynamic_cast<ForStatement*>(stmt))
>> {
>> //os << pre << "[ForStatement]" << std::endl;
>> visit(fs->forBody_,depth+1);
>> }
>> else if(IfStatement *is = dynamic_cast<IfStatement*>(stmt))
>> {
>> //os << pre << "[IfStatement]" << std::endl;
>> visit(is->ifBody_,depth+1);
>> //os << pre << "[IfStatement : else]" << std::endl;
>> visit(is->elseBody_,depth+1);
>> }
>> else if(FunctionStatement *fs = dynamic_cast<FunctionStatement*>(stmt))
>> {
>> //os << pre << "[FunctionStatement]" << std::endl;
>> visit(fs->functionBody_,depth+1);
>> }
>> else if(named_range *nr = dynamic_cast<named_range*>(stmt))
>> {
>> range.push_back(nr);
>> //os << pre << "[named_range]" << std::endl;
>> }
>> //else if(dynamic_cast<FunctionDeclarationStatement*>(stmt))
>> // os << pre << "[FunctionDeclarationStatement]" << std::endl;
>> //else if(dynamic_cast<ExpressionStatement*>(stmt)) os << pre <<
>> "[ExpressionStatement]" << std::endl;
>> //else if(dynamic_cast<StubManipStatement*>(stmt)) os << pre <<
>> "[StubManipStatement]" << std::endl;
>> //else if(dynamic_cast<DeclarationStatement*>(stmt)) os << pre <<
>> "[DeclarationStatement]" << std::endl;
>> //else { os << pre << "[unknown statement] " << typeid(*stmt).name() <<
>> std::endl; }
>> visit(stmt->next_,depth);
>> }
>>
>> void print(std::ostream &os)
>> {
>> os << question.size() << '\n';
>> REP(i,question.size())
>> {
>> os << question[i]->questionName_ << ' ' << text(question[i]->dt);
>> if(question[i]->q_type==mpn) os << ' ' << question[i]->no_mpn; else os <<
>> " 1";
>> if(RangeQuestion *q = dynamic_cast<RangeQuestion*>(question[i]))
>> {
>> //os << " [RangeQuestion]";
>> }
>> else if(NamedStubQuestion *q =
>> dynamic_cast<NamedStubQuestion*>(question[i]))
>> {
>> os << ' ' << q->nr_ptr->name;
>> //os << " [NamedStubQuestion]";
>> }
>> else if(DummyArrayQuestion *q =
>> dynamic_cast<DummyArrayQuestion*>(question[i]))
>> {
>> os << " [DummyArrayQuestion]";
>> }
>> else os << " <unknown question type>";
>> os << '\n';
>> }
>>
>> REP(i,range.size())
>> {
>> os << range[i]->name;
>> REP(j,range[i]->stubs.size())
>> os << ' ' << range[i]->stubs[j].code << " \"" <<
>> range[i]->stubs[j].stub_text << '\"';
>> os << '\n';
>> }
>> }
>>
>> };
>>
>> void yyrestart(FILE *);
>> int yyparse();
>>
>> void InitStatement();
>>
>> int main(int argc, char* argv[])
>> {
>> InitStatement();
>> qscript_parser::active_scope = new Scope();
>> qscript_parser::active_scope_list.push_back(qscript_parser::active_scope);
>>
>> yyrestart(stdin);
>> if(!yyparse() && !qscript_parser::no_errors)
>> {
>> std::cout << "{input parsed}" << std::endl;
>> qscript_parser::GenerateCode();
>> std::cout << "{code generated}" << std::endl;
>> TextMapGenerator G; G.visit(qscript_parser::tree_root);
>> G.print(std::cout);
>> std::cout << "{text map generated}" << std::endl;
>> }
>> else std::cout << "There were : " << qscript_parser::no_errors << " errors
>> in parse" << std::endl;
>> return qscript_parser::no_errors;
>> }
>> 7:11 PM look at the comment at the beginning. What shall we do?
>> 7:15 PM And please verify if my main(){} properly performs the parsing.
>> 7:16 PM what is DummyArrayQuestion and how to deal with it?
>> ------------------------------
>> 8 minutes
>> 7:24 PM pom...@gm...: Do you want me to integrate your parsing
>> with my files to data_conv, so as to avoid the intermediate config file?
>> ------------------------------
>> 21 minutes
>> 7:46 PM pom...@gm...: is line "qscript_parser::GenerateCode()"
>> necessary for anything?
>>
>
>
|
|
From: Neil D'S. <nei...@gm...> - 2010-06-06 17:07:45
|
Hi Pompon,
Thanks for this - I will test your code out - I have just finished a
massive change to the compiler - GenerateCode and PrintExpressionCode - now
write to "Code" Objects because I realised that I needed another stream to
handle array questions navigation correctly and this will save us changing
function signatures in the future should we need another output stream when
generating code.
look at the comment at the beginning. What shall we do?IfStatement::ifBody_
::elseBody_cannot be accessed from TextMapGenerator
reason: IfStatement::ifBody_ ::elseBody are protected
solution: make public or make friend with TextMapGenerator NxD: make it
public, right now lets not worry about encapsulation etc, give it what it
wants to make it compile.
And please verify if my main(){} properly performs the parsing.
NxD: It should work fine - after the call to yyparse() the parse trees are
built. Once I replace the main.cpp with this one I will come to know. Will
work on it tomorrow.
what is DummyArrayQuestion and how to deal with it?
NxD: When reading data from the disk we need to know the dimension of any
array questions based on the level of nesting inside the for loop
I came up with this idea to write the dimension of the array while saving
the data. You will notice that DummyArrayQuestion has an empty
implementation of GenerateCode,
i.e. this question is not asked to the end user. However, it does have an
implementation of WriteDataToDisk - which writes out the bounds of the array
to the disk. The DummyArrayQuestion is created in the question definitions
sections and added to the "question_list" just like an ordinary question.
When write_data_to_disk is called, it iterates over every question in
"question_list" and will invoke the DummyArrayQuestion::WriteDataToDisk
function storing the BOUNDS of the array to the data file.
is line "qscript_parser::GenerateCode()" necessary for anything
NxD: This innocent looking function is the one that generates the code in
test_statement.C - it is the code generation phase, visiting each node in
qscript_parser::tree_root and generating code.
Do you want me to integrate your parsing with my files to data_conv, so as
to avoid the intermediate config file?
If you can set it up as a symbolic link, or use the files in the
simple_compiler/include directory after an install is done, it would be
great. We should be using only 1 parser file otherwise we will be
maintaining 2 files which will lead to a mess sooner or later.
The other option is to integrate the data_conv code with the code in the
qscript folder.
For this case, we could have the following 1) Default Behaviour: When the
compiler generates code for data entry of a questionnaire it also generates
a map
2) We create a command line option to write out the datafile according to
the map. When invoked with this option the compiler will write a program
that recodes the data according to a map.
If you are not happy with my suggestion above, feel free to suggest
something better.
Rgds,
NxD
> These messages were sent while you were offline.
>
> 7:09 PM pompon: I've written text map generator according to the
> instructions from your last mail. Here it is (replacement for
> qscript/src/main.cpp - map is printed to stdout - nothing interesting by
> now):
> /*
> stmt.h: IfStatement::ifBody_ ::elseBody cannot be accessed from
> TextMapGenerator
> reason: IfStatement::ifBody_ ::elseBody are protected
> solution: make public or make friend with TextMapGenerator
> */
>
> #include "qscript_parser.h"
> #include <iostream>
> #include <fstream>
> //#include <typeinfo>
>
> #define REP(i,n) for(int i=0; i<(n); ++i)
>
> class TextMapGenerator
> {
> public:
> std::vector<AbstractQuestion*> question;
> std::vector<named_range*> range;
>
> static const char *text(DataType dt)
> {
> switch(dt)
> {
> case INT8_TYPE : return "int8" ; case INT16_TYPE : return "int16" ;
> case INT32_TYPE : return "int32" ; case FLOAT_TYPE : return "float" ;
> case DOUBLE_TYPE: return "double"; default: return "<unrecognized type>";
> }
> }
>
> void visit(AbstractStatement *stmt, int depth = 0)
> {
> if(!stmt) return;
> string pre="";//(depth,' ');
> //std::ostream &os = std::cout;
> if(AbstractQuestion *q = dynamic_cast<AbstractQuestion*>(stmt))
> {
> question.push_back(q);
> /*os << pre << "[AbstractQuestion] " << q->questionName_ << ' ';
>
> os << std::endl;*/
> }
> else if(CompoundStatement *cs = dynamic_cast<CompoundStatement*>(stmt))
> {
> //os << pre << "[CompoundStatement]" << std::endl;
> visit(cs->compoundBody_,depth+1);
> }
> else if(ForStatement *fs = dynamic_cast<ForStatement*>(stmt))
> {
> //os << pre << "[ForStatement]" << std::endl;
> visit(fs->forBody_,depth+1);
> }
> else if(IfStatement *is = dynamic_cast<IfStatement*>(stmt))
> {
> //os << pre << "[IfStatement]" << std::endl;
> visit(is->ifBody_,depth+1);
> //os << pre << "[IfStatement : else]" << std::endl;
> visit(is->elseBody_,depth+1);
> }
> else if(FunctionStatement *fs = dynamic_cast<FunctionStatement*>(stmt))
> {
> //os << pre << "[FunctionStatement]" << std::endl;
> visit(fs->functionBody_,depth+1);
> }
> else if(named_range *nr = dynamic_cast<named_range*>(stmt))
> {
> range.push_back(nr);
> //os << pre << "[named_range]" << std::endl;
> }
> //else if(dynamic_cast<FunctionDeclarationStatement*>(stmt))
> // os << pre << "[FunctionDeclarationStatement]" << std::endl;
> //else if(dynamic_cast<ExpressionStatement*>(stmt)) os << pre <<
> "[ExpressionStatement]" << std::endl;
> //else if(dynamic_cast<StubManipStatement*>(stmt)) os << pre <<
> "[StubManipStatement]" << std::endl;
> //else if(dynamic_cast<DeclarationStatement*>(stmt)) os << pre <<
> "[DeclarationStatement]" << std::endl;
> //else { os << pre << "[unknown statement] " << typeid(*stmt).name() <<
> std::endl; }
> visit(stmt->next_,depth);
> }
>
> void print(std::ostream &os)
> {
> os << question.size() << '\n';
> REP(i,question.size())
> {
> os << question[i]->questionName_ << ' ' << text(question[i]->dt);
> if(question[i]->q_type==mpn) os << ' ' << question[i]->no_mpn; else os << "
> 1";
> if(RangeQuestion *q = dynamic_cast<RangeQuestion*>(question[i]))
> {
> //os << " [RangeQuestion]";
> }
> else if(NamedStubQuestion *q =
> dynamic_cast<NamedStubQuestion*>(question[i]))
> {
> os << ' ' << q->nr_ptr->name;
> //os << " [NamedStubQuestion]";
> }
> else if(DummyArrayQuestion *q =
> dynamic_cast<DummyArrayQuestion*>(question[i]))
> {
> os << " [DummyArrayQuestion]";
> }
> else os << " <unknown question type>";
> os << '\n';
> }
>
> REP(i,range.size())
> {
> os << range[i]->name;
> REP(j,range[i]->stubs.size())
> os << ' ' << range[i]->stubs[j].code << " \"" <<
> range[i]->stubs[j].stub_text << '\"';
> os << '\n';
> }
> }
>
> };
>
> void yyrestart(FILE *);
> int yyparse();
>
> void InitStatement();
>
> int main(int argc, char* argv[])
> {
> InitStatement();
> qscript_parser::active_scope = new Scope();
> qscript_parser::active_scope_list.push_back(qscript_parser::active_scope);
>
> yyrestart(stdin);
> if(!yyparse() && !qscript_parser::no_errors)
> {
> std::cout << "{input parsed}" << std::endl;
> qscript_parser::GenerateCode();
> std::cout << "{code generated}" << std::endl;
> TextMapGenerator G; G.visit(qscript_parser::tree_root); G.print(std::cout);
> std::cout << "{text map generated}" << std::endl;
> }
> else std::cout << "There were : " << qscript_parser::no_errors << " errors
> in parse" << std::endl;
> return qscript_parser::no_errors;
> }
> 7:11 PM look at the comment at the beginning. What shall we do?
> 7:15 PM And please verify if my main(){} properly performs the parsing.
> 7:16 PM what is DummyArrayQuestion and how to deal with it?
> ------------------------------
> 8 minutes
> 7:24 PM pom...@gm...: Do you want me to integrate your parsing
> with my files to data_conv, so as to avoid the intermediate config file?
> ------------------------------
> 21 minutes
> 7:46 PM pom...@gm...: is line "qscript_parser::GenerateCode()"
> necessary for anything?
>
|
|
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.
>
|
|
From: Neil D'S. <nx...@ya...> - 2010-05-31 11:09:20
|
I have released qscript-0.4.tar.gz. You should be able to build with $make -f CustomQScriptMakefile local_install There are quite a few sample input files in the "inputs" directory. If you try doing a build and face any difficulties, please send a mail to the mailing list. Regards, NxD |
|
From: Neil D'S. <nx...@ya...> - 2010-05-30 14:30:29
|
Hi Pompon,
1) I added some code to fix the navigation error you pointed out Yesterday. However the terminal questions are not yet being handled.
2) I have updated the cmake "CMakeLists.txt" to use the .hpp files generated as the new cmake (version 2.8 ) does not allow you to intercept the BISON_TARGET
and rename the *.hpp file to *.h . Hence I modified the lexers to include the *.hpp files. You should now be able to build with cmake or CustomQScriptMakefile
3) I figured we might as well start using the mailing list so that all discussions are in a common place.
Rgds,
NxD
|