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;
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; }
};
} ;
int main()
{
cout << "****************************************************\n\n";
cout << "\t\t Parsing B Machines\n\n";
cout << "****************************************************\n\n";
cout << "Please enter a filename: ";
char strFilename[256];
cin >> strFilename;
ifstream inFile(strFilename);
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:
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.