I've having a hard time getting my parser to work correctly. I'm trying to
create a script parser to create tests, actions, and groups defined in a
file. I have the grammer working except for one small issue. I can't get
rid of the closing quote on my sentence. It skips the first one just fine.
I'm using spirit 1.6.2
The script is below named script.txt:
----------------------
Groups
{G100, "This is group G100",
G200, "This is group G200"
}
Actions
{A100, "This is an action"
}
Tests
{T100, "This is a test", 0, 5, "VDC"
}
TestFlow
{a
}
----------------------------------
I want to have the option of using double quotes (") around strings for the
discriptions in Groups, Actions, and Tests section to make it easier to
read. I use comma as a delimiter.
Here is my spirit code below:
----------------------------------
#include <iostream>
#include <fstream>
#include <vector>
#if defined(_DEBUG)
//#define BOOST_SPIRIT_DEBUG
#endif // defined(_DEBUG)
#include "boost/spirit.hpp"
#include
#include
#include
////////////////////////////////////////////////////////////////////////////
///
// used namespaces
using namespace boost::spirit;
using namespace std;
namespace
{
void
my_action(char const* first, char const* last)
{
std::string str(first, last);
std::cout << str << std::endl;
}
void
my_number(float val)
{
std::cout << val << std::endl;
}
}
struct script_grammar : public grammar
{
template <typename ScannerT>
struct definition
{
definition(script_grammar const& self)
{
Group_Composite = Group >>
BeginBrace >>
+Group_Action_Parms >>
EndBrace;
Action_Composite = Action >>
BeginBrace >>
+Group_Action_Parms >>
EndBrace;
Test_Composite = Test >>
BeginBrace >>
+Test_Parms >>
EndBrace;
TestFlow_Composite = TestFlow >>
BeginBrace >>
+TestFlow_Parms >>
EndBrace;
Group = as_lower_d[str_p("groups")];
Group_Action_Parms = Token[&my_action] >>
Comma >>
Token[&my_action] >>
!Comma;
Action = as_lower_d[str_p("actions")];
Test = as_lower_d[str_p("tests")];
Test_Parms = Token[&my_action] >>
Comma >>
Token[&my_action] >>
Comma >>
real_p[&my_number] >>
Comma >>
real_p[&my_number] >>
Comma >>
Token[&my_action] >>
!Comma;
TestFlow = as_lower_d[str_p("testflow")];
TestFlow_Parms = Token;
BeginBrace = ch_p('{');
EndBrace = ch_p('}');
Comma = ch_p(',');
Token = +Token_Sub;
Token_Sub = alnum_p; //(alnum_p - ch_p(34)); // ^
ch_p('\"'));
first = *(
Group_Composite |
Action_Composite |
Test_Composite ) >>
TestFlow_Composite;
BOOST_SPIRIT_DEBUG_RULE(Group_Composite);
BOOST_SPIRIT_DEBUG_RULE(Action_Composite);
BOOST_SPIRIT_DEBUG_RULE(Test_Composite);
BOOST_SPIRIT_DEBUG_RULE(TestFlow_Composite);
BOOST_SPIRIT_DEBUG_RULE(Group);
BOOST_SPIRIT_DEBUG_RULE(Group_Action_Parms);
BOOST_SPIRIT_DEBUG_RULE(Action);
BOOST_SPIRIT_DEBUG_RULE(Test);
BOOST_SPIRIT_DEBUG_RULE(Test_Parms);
BOOST_SPIRIT_DEBUG_RULE(TestFlow);
BOOST_SPIRIT_DEBUG_RULE(TestFlow_Parms);
BOOST_SPIRIT_DEBUG_RULE(BeginBrace);
BOOST_SPIRIT_DEBUG_RULE(EndBrace);
BOOST_SPIRIT_DEBUG_RULE(Comma);
BOOST_SPIRIT_DEBUG_RULE(Token);
BOOST_SPIRIT_DEBUG_RULE(first);
BOOST_SPIRIT_DEBUG_RULE(Token_Sub);
}
rule<ScannerT> Group_Composite,
Action_Composite,
Test_Composite,
TestFlow_Composite,
Group,
Group_Action_Parms,
Action,
Test,
Test_Parms,
TestFlow,
TestFlow_Parms,
BeginBrace,
EndBrace,
Comma,
Token,
Token_Sub;
rule<ScannerT> first;
rule<ScannerT> const&
start() const { return first; }
};
};
struct skip_grammar : public grammar
{
template <typename ScannerT>
struct definition
{
definition(skip_grammar const& /*self*/)
{
skip
= space_p
| ch_p('\"')
;
BOOST_SPIRIT_DEBUG_RULE(skip);
}
rule<ScannerT> skip;
rule<ScannerT> const&
start() const { return skip; }
};
};
template<typename GrammarT>
void
parse(GrammarT const& g, char const* filename)
{
ifstream in(filename);
if (!in)
{
cerr << "Could not open input file: " << filename << endl;
return;
}
in.unsetf(ios::skipws); // Turn off white space skipping on the stream
vector<char> vec;
std::copy(
istream_iterator<char>(in),
istream_iterator<char>(),
std::back_inserter(vec));
vector<char>::const_iterator start = vec.begin();
vector<char>::const_iterator end = vec.end();
skip_grammar skip;
parse_info result =
parse(start, end, g, skip);
if (result.full)
cerr << filename << " Parses OK" << endl;
else {
cerr << filename << " Fails Parsing" << endl;
for (int i = 0; i < 50; i++)
{
if (result.stop == end)
break;
cerr << *result.stop++;
}
cerr << endl;
}
}
// main entrypoint
int
main(int argc, char* argv[])
{
// Start grammar definition
cerr << "Start of Parsing ..." << endl;
// main driver code
script_grammar g;
if (2 == argc)
parse(g, argv[1]);
else
cerr << "No filename given" << endl;
return 0;
}
The output looks like this:
Start of Parsing ...
G100
This is group G100"
G200
This is group G200"
A100
This is an action"
T100
This is a test"
0
5
VDC"
c:\script.txt Parses OK
I'm trying to get rid of the quote on the end. Please help.
Thanks,
Brad
Brad Retzlaff
Design Engineer
Functional Test Development
Plexus Technology Group
55 Jewelers Park Dr.
PO Box 677
Neenah, WI 54957
Phone: (920) 720-6733
Fax: (920) 751-5366
http://www.plexus.com http://www.plexus.com/