Boost logo

Boost Users :

From: sps22 (sps22_at_[hidden])
Date: 2003-07-31 11:27:52


Hi,
I am trying to use Spirit (in the latest Boost 1_30_0) for a project.
I want to parse a file whose structure is the following:

section1 {
  something;
}

I am using the file_iterator to iterate on the input file and then
define comment as well as the grammar. I am at my wits end why my
parser keeps failing. (When this simple grammar works, I want to make
the parser more complex.) My code is attached below. (Note: I used
the example in the distribution c_grammar.cpp as the starting point
for it.)

Thanks.

-surinder

PS: This input file structure is going to be, of course, more
complicated than the example shown above. Inside the setions, I would
like to pass on flags and statements to the code. If it is better for
me to use another approach to parse this file structure, please
suggest me.

#include <iostream>
#include <fstream>
#include <vector>

#include <boost/spirit.hpp>

/* Input file for this looks like:

file { something; }

*/

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

//////////////////////////////////////////////////////////////////////
/////////
// parsing helper function

// Here's our comment rule
struct skip_grammar : public grammar<skip_grammar>
{
    template <typename ScannerT>
    struct definition
    {
        definition(skip_grammar const& /*self*/)
        {
            skip
                = space_p
                | comment_p("//") // C++ comment
                | comment_p("/*", "*/") // C comment
                | comment_p("#") // added for correctly
                ;
        }
        rule<ScannerT> skip;
        rule<ScannerT> const&
        start() const { return skip; }
    };
};

//////////////////////////////////////////////////////////////////////
/////////
// typedef
typedef char CharT;
typedef file_iterator <CharT> IteratorT;
typedef scanner <IteratorT> ScannerT;
typedef rule <ScannerT> RuleT;

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;
    }

    IteratorT start(filename);
    if (!start) {
      cerr << "Could not open the file " << endl;
      return ;
    }
    IteratorT end = start.make_end();

    skip_grammar skip;
    parse_info<IteratorT> 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;
    }
}

struct c_grammar : public grammar<c_grammar>
{
  template <typename ScannerT>
  struct definition
  {
    definition(c_grammar const& /*self*/) :
      SEMICOLON(';'), COMMA(','), COLON(':'), ASSIGN('='),
      LEFT_PAREN('('), RIGHT_PAREN(')')
    {
      // C keywords
      keywords =
        "file", "physics", "math";
      // C operators
      LEFT_BRACE = chlit<>('{') | strlit<>("<%");
      RIGHT_BRACE = chlit<>('}') | strlit<>("%>");
      LEFT_BRACKET = chlit<>('[') | strlit<>("<:");
      RIGHT_BRACKET = chlit<>(']') | strlit<>(":>");
      // Tokens
      FILE = strlit<>("file");
      PHYSICS = strlit<>("physics");
      MATH = strlit<>("math");
      // string literals
      STRING_LITERAL_PART =
        lexeme_d[
                 !chlit<>('L') >> chlit<>('\"') >>
                 *( strlit<>("\\\"") | anychar_p - chlit<>('\"') ) >>
                 chlit<>('\"')
        ]
        ;
      STRING_LITERAL = +STRING_LITERAL_PART;
      // Rules
      
      file_statement =
        FILE >> LEFT_BRACE >>
        *(anychar_p) >>
        RIGHT_BRACE; // does not work
      // file_statement = *(anychar_p); // parses OK
      translation_unit = file_statement;

    }
      symbols<> keywords;
      chlit<>
      SEMICOLON, COMMA, COLON, ASSIGN, LEFT_PAREN, RIGHT_PAREN;
      rule<ScannerT>
      LEFT_BRACE, RIGHT_BRACE, LEFT_BRACKET, RIGHT_BRACKET;
      rule<ScannerT> FILE, PHYSICS, MATH, STRING_LITERAL,
STRING_LITERAL_PART;
      rule<ScannerT> file_statement, translation_unit;

      rule<ScannerT> const&
      start() const { return translation_unit; }
    };
};

//////////////////////////////////////////////////////////////////////
/////////
// main entrypoint
int
main(int argc, char* argv[])
{
// Start grammar definition
    cerr << "C Grammar checker implemented with Spirit ..." << endl;

// main driver code
c_grammar g;

    if (2 == argc)
        parse(g, argv[1]);
    else
        cerr << "No filename given" << endl;

    return 0;
}


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