Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
3.50/5 (2 votes)
See more:
I have been using the following win32 console code to try to parse a B Machine Grammar embedded within C++ using Boost Spirit grammar template. This is my first attempt at using spirit. The code compiles, but when I run the .exe file produced by VC++2008, the output scrolls in the dos window and disappears, although I pass a correct file path to the program.

The code is given below:
//////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/core.hpp>
#include <boost/spirit/actor/push_back_actor.hpp>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "stdafx.h"
////////////////////////////////////////////////////////////////////////////
using namespace std;
using namespace boost::spirit;
//////////////////////////////////////////////////////////////
//////                                                    ////
//////   Machine Grammar Parser                           ////
//////                                                    //// 
//////////////////////////////////////////////////////////////


struct machine : public grammar<machine>
{
    template <typename ScannerT>
    struct definition
    {
        definition(machine const& )
        {
			machine_grammar = 
			    str_p("MACHINE") >> Identifier >> *('(' >> param_list >> ')') >> 
				*(str_p("CONSTRAINTS") >> Formula >> *('&' >> Formula)) >> 
				*(str_p("USES") >> machine_ref >> *(',' >> machine_ref)) >> 
				*(str_p("SEES") >> machine_ref >> *(',' >> machine_ref)) >> 
				*(str_p("INCLUDES") >> machine_ref >> *('(' >> param_list >> ')') >>
	                 *(',' >> machine_ref >> *('(' >> param_list >> ')'))) >> 
				*(str_p("PROMOTES") >>operation_ref >> *(',' >> operation_ref)) >> 
				*(str_p("EXTENDS") >> machine_ref >> *('(' >> param_list >> ')') >>
	                 *(',' >> machine_ref >> *('(' >> param_list >> ')'))) >> 
				*(str_p("SETS") >> (uCase_Ide >> *(';' >> uCase_Ide)) 
				     | (enum_set >> *(';' >> enum_set))) >> 
				*(str_p("CONSTANTS") >> Identifier >> *(',' >> Identifier)) >> 
				*(str_p("PROPERTIES") >> Formula >> *('&' >> Formula)) >> 
				*(str_p("VARIABLES") >> Identifier >> *(',' >> Identifier)) >> 
				*(str_p("INVARIANT") >> Formula >> *('&' >> Formula)) >> 
				*(str_p("ASSERTION")  >> Formula >> *('&' >> Formula)) >> 
				*(str_p("DEFINITIONS")  >> Formula >> '=' >> '=' >> Formula >> 
	                 *(';' >> Formula >> '=' >> '=' >> Formula)) >> 
				*(str_p("INITIALISATION") >> Formula) >> 
				*(str_p("OPERATIONS") >> operation >> *(';' >> operation)) >> 
				str_p("END");
			Identifier = lexeme_d[alpha_p >> +alnum_p];
			Formula = (Identifier >> rel_op >> Identifier) | (Identifier >> rel_op 
				   >> lexeme_d[+digit_p]);
			machine_ref = *(rename_prefix >> '.') >> Identifier;
			param_list = Identifier >> *(',' >> Identifier);
			operation = *(param_list >> "<--") >> Identifier >> *('(' >> param_list >> ')') 
				  >> '=' >> machine_subst;
			enum_set = uCase_Ide >> '=' >> '{' >> set_members >> '}';
			set_members = (Identifier >> *(',' >> Identifier)) | (Bnumber >> *(',' >> Bnumber));			
			rename_prefix = Identifier;
			operation_ref = *(rename_prefix >> '.') >> Identifier;
			
			Bnumber     =   lexeme_d[ (!ch_p('-') >> +digit_p) ];
			factor      =   Bnumber |   '(' >> expression >> ')';
			term        =   factor >> *(  ('*' >> factor) | ('/' >> factor) );
			expression  =   term >> *(  ('+' >> term) | ('-' >> term) );
			simple_subst = (Identifier >> ":=" >> expression >> 
                   *(str_p('||') >> Identifier >> ":=" >> expression));
			machine_subst = simple_subst | "IF" >> Formula >> "THEN" >> simple_subst >> 
				   *("ELSIF" >> simple_subst) >> *("ELSE" >> simple_subst) >> "END";
			rel_op = ch_p('<') | ch_p('=') | ch_p('>')| str_p("<=") | str_p(">=") | ch_p(':') 
				   | str_p("/=") | str_p("/:") | str_p("<:") | str_p("<<:") | str_p("/<:") 
				   | str_p("/<<:");
			
	  }
rule<ScannerT> Bnumber, factor, term, expression, simple_subst, machine_subst, rel_op, 
	   Formula, Identifier, set_members, enum_set, param_list, operation, rename_prefix, 
	   operation_ref, machine_ref, machine_grammar, uCase_Ide;
rule<ScannerT> const&
        start() const { return machine_grammar; }
    };
} ;


//////////////////////////////////////////////////////////////
//////                                                    ////
//////   Main Program                                     ////
//////                                                    //// 
//////////////////////////////////////////////////////////////
int main()
{
  cout << "****************************************************\n\n";
  cout << "\t\t Parsing B Machines\n\n";
  cout << "****************************************************\n\n";
///////
   cout << "Please enter a filename: "; //prompt for file name to be input
  char strFilename[256]; //file name store as a string object
  cin >> strFilename;
  ifstream inFile(strFilename); // opens file object for reading
//////
  machine mach;
  string str;
     while(inFile >> str)
    {
        if (str.empty() || str[0] == 'q' || str[0] == 'Q')
            break;
        parse_info<> info = parse(str.c_str(), mach, space_p);		 
	

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



The file I passed to the program (saved as a text file) is given below:

CSS
MACHINE ChooseRoute
SETS ROUTES = 1..4
VARIABLES rt1, rt2, rt3, rt4
INVARIANT rt1 : ROUTES & rt2:ROUTES &
          rt3 : ROUTES & rt4:ROUTES
INITIALISATION rt1,rt2,rt3,rt4 := 0,0,0,0
OPERATIONS
makeRoute =
    CHOICE rt1:= 1 OR rt2:=2 OR rt3 := 3 OR rt4:=4 END
CASE rt1=2 THEN rt1:=1 OR rt2 =4 THEN rt2=2 END
END



I need help to get the program to parse and display output on win32 console.
Posted
Updated 24-Mar-10 1:54am
v2

1 solution

Before the
return 0;
add:
cout<<"hit any key to exit\n";
cin >> strFilename;


Then at least you get a chance to read the console text before the program exits and the console disappears....
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900