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; }
participants (1)
-
sps22