Re: Help with Boost Grammar

Posted by Decmac04 on Stack Overflow See other posts from Stack Overflow or by Decmac04
Published on 2010-04-19T19:50:41Z Indexed on 2010/04/19 19:53 UTC
Read the original article Hit count: 504

Filed under:
|
|
|
|

I have redesigned and extended the grammar I asked about earlier as shown below:

// BIFAnalyser.cpp : Defines the entry point for the console application. // // /*============================================================================= Copyright (c) Temitope Jos Onunkun 2010 http://www.dcs.kcl.ac.uk/pg/onun/

Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)

=============================================================================*/ //////////////////////////////////////////////////////////////////////////// // // // B Machine parser using the Boost "Grammar" and "Semantic Actions". // // // ////////////////////////////////////////////////////////////////////////////

include

include

include

include

include

include

//////////////////////////////////////////////////////////////////////////// using namespace std; using namespace boost::spirit;

//////////////////////////////////////////////////////////////////////////// // // Semantic Actions // //////////////////////////////////////////////////////////////////////////// // // namespace {

//semantic action function on individual lexeme void do_noint(char const* start, char const* end) { string str(start, end);

if (str != "NAT1") cout << "PUSH(" << str << ')' << endl; }

//semantic action function on addition of lexemes void do_add(char const*, char const*)
{ cout << "ADD" << endl; // for(vector::iterator vi = strVect.begin(); vi < strVect.end(); ++vi) // cout << *vi << " "; }

//semantic action function on subtraction of lexemes void do_subt(char const*, char const*)
{ cout << "SUBTRACT" << endl; }

//semantic action function on multiplication of lexemes void do_mult(char const*, char const*)
{ cout << "\nMULTIPLY" << endl; }

//semantic action function on division of lexemes void do_div(char const*, char const*)
{ cout << "\nDIVIDE" << endl;

}

//

//

vector > flowTable;

//semantic action function on simple substitution void do_sSubst(char const* start, char const* end)
{ string str(start, end);

//use boost tokenizer to break down tokens typedef boost::tokenizer > Tokenizer; boost::char_separator sep(" -+/*:=()",0,boost::drop_empty_tokens); // char separator definition Tokenizer tok(str, sep); Tokenizer::iterator tok_iter = tok.begin();

pair dependency; //create a pair object for dependencies

//create a vector object to store all tokens vector dx; //

int counter = 0; // tracks token position

for(tok.begin(); tok_iter != tok.end(); ++tok_iter) //save all tokens in vector { dx.push_back(*tok_iter ); } counter = dx.size();

// vector d_hat; //stores set of dependency pairs

string dep; //pairs variables as string object

// dependency.first = *tok.begin(); vector FV;

for(int unsigned i=1; i < dx.size(); i++) {
// if(!atoi(dx.at(i).c_str()) && (dx.at(i) !=" ")) { dependency.second = dx.at(i); dep = dependency.first + "|->" + dependency.second + " "; d_hat.push_back(dep);

vector<string> row; 
row.push_back(dependency.first);  //push x_hat into first column of each row

for(unsigned int j=0; j<2; j++)
{

 row.push_back(dependency.second);//push an element (column) into the row
}

flowTable.push_back(row); //Add the row to the main vector

} }

//displays internal representation of information flow table cout << "\n****************\nDependency Table\n****************\n"; cout << "X_Hat\tDx\tG_Hat\n"; cout << "-----------------------------\n"; for(unsigned int i=0; i < flowTable.size(); i++) { for(unsigned int j=0; j<2; j++) { cout << flowTable[i][j] << "\t "; } if (*tok.begin() != "WHILE" ) //if there are no global flows, cout << "\t{}"; //display empty set

cout << "\n"; } cout << "***************\n\n";

for(int unsigned j=0; j < FV.size(); j++) {
if(FV.at(j) != dependency.second) dep = dependency.first + "|->" + dependency.second + " "; d_hat.push_back(dep); }

cout << "PUSH(" << str << ')' << endl;

cout << "\n*******\nDependency pairs\n*******\n";

for(int unsigned i=0; i < d_hat.size(); i++) cout << d_hat.at(i) << "\n...\n";

cout << "\nSIMPLE SUBSTITUTION\n\n";

}

//semantic action function on multiple substitution

void do_mSubst(char const* start, char const* end)
{ string str(start, end);

cout << "PUSH(" << str << ')' << endl; //cout << "\nMULTIPLE SUBSTITUTION\n\n"; }

//semantic action function on unbounded choice substitution void do_mChoice(char const* start, char const* end)
{ string str(start, end);

cout << "PUSH(" << str << ')' << endl; cout << "\nUNBOUNDED CHOICE SUBSTITUTION\n\n"; }

void do_logicExpr(char const* start, char const* end)
{ string str(start, end);

//use boost tokenizer to break down tokens typedef boost::tokenizer > Tokenizer; boost::char_separator sep(" -+/*=:()><",0,boost::drop_empty_tokens); // char separator definition Tokenizer tok(str, sep); Tokenizer::iterator tok_iter = tok.begin();

//pair dependency; //create a pair object for dependencies

//create a vector object to store all tokens vector dx;

for(tok.begin(); tok_iter != tok.end(); ++tok_iter) //save all tokens in vector { dx.push_back(*tok_iter ); }

for(unsigned int i=0; i

cout << "PUSH(" << str << ')' << endl; cout << "\nPREDICATE\n\n"; }

void do_predicate(char const* start, char const* end)
{ string str(start, end);

cout << "PUSH(" << str << ')' << endl; cout << "\nMULTIPLE PREDICATE\n\n"; }

void do_ifSelectPre(char const* start, char const* end)
{ string str(start, end);

//if

cout << "PUSH(" << str << ')' << endl; cout << "\nPROTECTED SUBSTITUTION\n\n"; }

//semantic action function on machine substitution void do_machSubst(char const* start, char const* end)
{ string str(start, end);

cout << "PUSH(" << str << ')' << endl; cout << "\nMACHINE SUBSTITUTION\n\n"; } }

//////////////////////////////////////////////////////////////////////////// // // Machine Substitution Grammar // ////////////////////////////////////////////////////////////////////////////

// Simple substitution grammar parser with integer values removed struct Substitution : public grammar { template struct definition { definition(Substitution const& ) {

machine_subst = ( (simple_subst) | (multi_subst) | (if_select_pre_subst) | (unbounded_choice) )[&do_machSubst] ;

unbounded_choice = str_p("ANY") >> ide_list

str_p("WHERE") >> predicate str_p("THEN")
machine_subst str_p("END") ;

if_select_pre_subst = ( ( str_p("IF") >> predicate >> str_p("THEN") >> machine_subst

*( str_p("ELSIF") >> predicate >> machine_subst ) !( str_p("ELSE") >> machine_subst) str_p("END") ) | ( str_p("SELECT") >> predicate >> str_p("THEN") >> machine_subst *( str_p("WHEN") >> predicate >> machine_subst ) !( str_p("ELSE") >> machine_subst) str_p("END")) | ( str_p("PRE") >> predicate >> str_p("THEN") >> machine_subst str_p("END") ) )[&do_ifSelectPre] ;

multi_subst = ( (machine_subst)

*( ( str_p("||") >> (machine_subst) ) | ( str_p("[]") >> (machine_subst) ) ) ) [&do_mSubst] ;

simple_subst = (identifier

str_p(":=") >> arith_expr) [&do_sSubst] ;

expression = predicate | arith_expr ;

predicate = ( (logic_expr)

*( ( ch_p('&') >> (logic_expr) ) | ( str_p("OR") >> (logic_expr) ) ) )[&do_predicate] ;

logic_expr = ( identifier

(str_p("<") >> arith_expr) | (str_p("<") >> arith_expr) | (str_p("/:") >> arith_expr) | (str_p("<:") >> arith_expr) | (str_p("/<:") >> arith_expr) | (str_p("<<:") >> arith_expr) | (str_p("/<<:") >> arith_expr) | (str_p("<=") >> arith_expr) | (str_p("=") >> arith_expr) | (str_p(">=") >> arith_expr) | (str_p("=>") >> arith_expr) ) [&do_logicExpr] ;

arith_expr = term

*( ('+' >> term)[&do_add] | ('-' >> term)[&do_subt] ) ;

term = factor

( ('' >> factor)[&do_mult] | ('/' >> factor)[&do_div] ) ;

factor = lexeme_d[( identifier | +digit_p)[&do_noint]] | '(' >> expression >> ')' | ('+' >> factor) ;

ide_list = identifier

*( ch_p(',') >> identifier ) ;

identifier = alpha_p >> +( alnum_p | ch_p('_') ) ;

}

rule machine_subst, unbounded_choice, if_select_pre_subst, multi_subst, simple_subst, expression, predicate, logic_expr, arith_expr, term, factor, ide_list, identifier;

    rule<ScannerT> const&
    start() const 

{ return predicate; //return multi_subst; //return machine_subst; } }; };

//////////////////////////////////////////////////////////////////////////// // // Main program // //////////////////////////////////////////////////////////////////////////// int main() { cout << "*********************************\n\n"; cout << "\t\t...Machine Parser...\n\n"; cout << "*********************************\n\n"; // cout << "Type an expression...or [q or Q] to quit\n\n";

string str; int machineCount = 0; char strFilename[256]; //file name store as a string object do {

cout << "Please enter a filename...or [q or Q] to quit:\n\n "; //prompt for file name to be input //char strFilename[256]; //file name store as a string object cin >> strFilename;

if(*strFilename == 'q' || *strFilename == 'Q') //termination condition return 0;

ifstream inFile(strFilename); // opens file object for reading //output file for truncated machine (operations only)

if (inFile.fail())
cerr << "\nUnable to open file for reading.\n" << endl;

inFile.unsetf(std::ios::skipws);

Substitution elementary_subst;  //  Simple substitution parser object


string next;

while (inFile >> str) { getline(inFile, next);

str += next;

    if (str.empty() || str[0] == 'q' || str[0] == 'Q')
        break;

parse_info<> info = parse(str.c_str(), elementary_subst >> !end_p, space_p);

if (info.full) { cout << "\n-------------------------\n"; cout << "Parsing succeeded\n"; cout << "\n-------------------------\n"; } else { cout << "\n-------------------------\n"; cout << "Parsing failed\n"; cout << "stopped at: " << info.stop << "\"\n"; cout << "\n-------------------------\n"; }

}

} while ( (*strFilename != 'q' || *strFilename !='Q'));

return 0;

}

However, I am experiencing the following unexpected behaviours on testing:

The text files I used are: f1.txt, ... containing ...: debt:=(LoanRequest+outstandingLoan1)*20 . f2.txt, ... containing ...: debt:=(LoanRequest+outstandingLoan1)*20 || newDebt := loanammount-paidammount || price := purchasePrice + overhead + bb . f3.txt, ... containing ...: yy < (xx+7+ww) . f4.txt, ... containing ...: yy < (xx+7+ww) & yy : NAT .

When I use multi_subst as start rule both files (f1 and f2) are parsed correctly;

When I use machine_subst as start rule file f1 parse correctly, while file f2 fails, producing the error: “Parsing failed

stopped at: || newDebt := loanammount-paidammount || price := purchasePrice + overhead + bb”

When I use predicate as start symbol, file f3 parse correctly, but file f4 yields the error: “ “Parsing failed

stopped at: & yy : NAT”

Can anyone help with the grammar, please? It appears there are problems with the grammar that I have so far been unable to spot.

© Stack Overflow or respective owner

Related posts about boost

Related posts about spirit