Spirit parser question

Colin Thomas <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <CAPeyVH7bGkGiM0BO_+R014DDK9YweytbaOc0vceJGKGj55Rq0w@mail.gmail.com>
Hi

I used the spirit library ~ 12 years ago and got a parser working then –
the new syntax is throwing me, and I wonder if you could perhaps see where
I’ve missed something



I want to parse a CAD spice netlist (I have a functional adhoc version, but
want to clean it up with spirit).



The very simple initial format is:



* This is a lonnng comment

.SUBCKT fred a b c d

.ENDS



When I run I get:

-------------------------

Parsing succeeded

-------------------------

Which looks good, but when i try to extract elements the fates turn against
me


I have 2 questions re the new format



   1.

   When I have a match, in the old format rules were just specified by
   rule<>.

   I now seem to have specify rule<Iterator, xx, yy), and the definition
   and usage of xx is throwing me I believe.

   I used to be able to define a function after the element, which would
   call a function to process:

   i.e.

void extractComment (char const* str, char const* end) {

 std::string  s(str, end);

 std::cout << "INFO: COMMENT \""<< s << "\"\n";

}



                COMMENT_syntax =

                       lit("*")

                       >> *(char_ -
boost::spirit::qi::eol)[&extractComment]

                       >> boost::spirit::qi::eol

But the compiler seems to be throwing issues between the definition of xx
and the function.

What is the relationship between them both and the arg in phrase_parse (my
old version which just had a parse function). I have looked for a decent
definition of phrase_parser but with no avail





   1.

   If I comment out the [&zzz] calls when matches are made, I get

   -------------------------

   Parsing succeeded

   -------------------------

   Butisn't extracting the data :-( So, I know I’m very close …

I hope you can see the errors of my ways


best regards



Colin



The code is:



#include <boost/config/warning_disable.hpp>

#include <boost/spirit/include/qi.hpp>

#include <boost/spirit/include/phoenix_core.hpp>

#include <boost/spirit/include/phoenix_operator.hpp>

#include <boost/spirit/include/phoenix_fusion.hpp>

#include <boost/spirit/include/phoenix_stl.hpp>

#include <boost/fusion/include/adapt_struct.hpp>

#include <boost/variant/recursive_variant.hpp>

#include <boost/foreach.hpp>



#include <iostream>

#include <fstream>

#include <string>

#include <vector>



#define BOOST_SPIRIT_DEBUG



using namespace boost::spirit;

///////////////////////////////////////////////////////////////////////

//Functions to Process elements as they are extracted:

void extractPinName (char const* str, char const* end) {

std::string  s(str, end);

 std::cout << "INFO: PIN NAME \""<< s << "\"\n";

}

void extractCellName (char const* str, char const* end) {

std::string  s(str, end);

 std::cout << "INFO: CELL NAME \""<< s << "\"\n";

}

void extractComment (char const* str, char const* end) {

std::string  s(str, end);

 std::cout << "INFO: COMMENT \""<< s << "\"\n";

}

///////////////////////////////////////////////////////////////////////////

//  Our Spice grammar definition

///////////////////////////////////////////////////////////////////////////

template <typename Iterator, typename Skipper>

struct spice_grammar : qi::grammar<Iterator,
std::vector<boost::variant<int,bool> >(), qi::blank_type>

//struct spice_grammar : qi::grammar<Iterator, , Skipper>

{

 spice_grammar() : spice_grammar::base_type(ALL_syntax)

 {

  using qi::lit;

  using qi::lexeme;

  using ascii::char_;

  using ascii::string;

  using qi::eol;



                COMMENT_syntax =

                       lit("*")

                       >> *(char_ -
boost::spirit::qi::eol)//[&extractComment]

                       >> boost::spirit::qi::eol

    ;

                SUBCKT_syntax =

                       lit(".SUBCKT")

                       >> CELLNAME_syntax //[&extractCellName]

                       >> *(PINNAME_syntax) //[&extractPinName]

                       >> boost::spirit::qi::eol

    ;

        ENDS_syntax =

                   lit(".ENDS")

                   >>  - boost::spirit::qi::eol

    ;

                CELLNAME_syntax =

                       lexeme[+(char_ - boost::spirit::qi::eol)]

    ;

                PINNAME_syntax =

                       lexeme[+(char_ - boost::spirit::qi::eol)]

    ;

        CELL_syntax =

                       COMMENT_syntax

                       >>

                       SUBCKT_syntax

                       >>

                       ENDS_syntax

    ;

        ALL_syntax =

                      *(CELL_syntax)

    ;

    BOOST_SPIRIT_DEBUG_NODES((COMMENT_syntax)(SUBCKT_syntax)(ENDS_syntax));

 }



        qi::rule<Iterator, std::vector<boost::variant<int,bool> >(),
qi::blank_type> ALL_syntax;

        qi::rule<Iterator, std::vector<boost::variant<int,bool> >(),
qi::blank_type> COMMENT_syntax;

        qi::rule<Iterator, std::vector<boost::variant<int,bool> >(),
qi::blank_type> SUBCKT_syntax;

        qi::rule<Iterator, std::vector<boost::variant<int,bool> >(),
qi::blank_type> ENDS_syntax;

        qi::rule<Iterator, std::vector<boost::variant<int,bool> >(),
qi::blank_type> CELLNAME_syntax;

        qi::rule<Iterator, std::vector<boost::variant<int,bool> >(),
qi::blank_type> CELL_syntax;

        qi::rule<Iterator, std::vector<boost::variant<int,bool> >(),
qi::blank_type> PINNAME_syntax;

};

//]



///////////////////////////////////////////////////////////////////////////////

//  Main program

///////////////////////////////////////////////////////////////////////////////

int main()

{

    char const* filename;

    filename = "SC8T_CKND2X4_CSC20R.cdl";



    std::ifstream in(filename, std::ios_base::in);



    if (!in)

    {

        std::cerr << "Error: Could not open input file: "

            << filename << std::endl;

        return 1;

    }



    std::string storage;                      // We will read the contents
here.

    in.unsetf(std::ios::skipws);       // No white space skipping!

    std::copy(

        std::istream_iterator<char>(in),

        std::istream_iterator<char>(),

        std::back_inserter(storage));



    spice_grammar<std::string::const_iterator, ascii::space_type>
spiceGrammar;

    using boost::spirit::ascii::space;

    std::string::const_iterator iter = storage.begin();

    std::string::const_iterator end = storage.end();

    std::vector<boost::variant<int,bool> > v;

    bool r = phrase_parse(iter, end, spiceGrammar, qi::blank, v);

    //bool r = phrase_parse(iter, end, spiceGrammar, space);



    if (r && iter == end)

    {

        std::cout << "-------------------------\n";

        std::cout << "Parsing succeeded\n";

        std::cout << "-------------------------\n";

        return 0;

    }

    else

    {

        std::string::const_iterator some = iter+30;

        std::string context(iter, (some>end)?end:some);

        std::cout << "-------------------------\n";

        std::cout << "Parsing failed\n";

        std::cout << "stopped at: \": " << context << "...\"\n";

        std::cout << "-------------------------\n";

        return 1;

    }

}

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot

_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.