Boost logo

Boost Users :

From: Brad Retzlaff (brad.retzlaff_at_[hidden])
Date: 2005-08-04 11:54:01


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 <boost/spirit/core.hpp>
#include <boost/spirit/utility.hpp>
#include <boost/spirit/symbols.hpp>
 
////////////////////////////////////////////////////////////////////////////
///
// 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<script_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<skip_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<vector<char>::const_iterator> 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/>
 



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net