Spirit parser question

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Spirit parser question

Colin Thomas
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Spirit parser question

Jens Kallup
Hello,

you could have a look to:
https://github.com/paule32/keyBase/blob/master/parser_sbase.cc#L405

this is my parser_work in progress.

You describe a common misstake, see line:
https://github.com/paule32/keyBase/blob/master/parser_sbase.cc#L519

see the rule in detail: std::string() !!!

if () missing, you get error output ;-)

Hope This Helps
Jens

------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Spirit parser question

sehe
In reply to this post by Colin Thomas
On 19-07-17 14:34, Colin Thomas wrote:
> 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
>
Here's a simpli-/sanitized version that removes a few potential
pitfalls. http://coliru.stacked-crooked.com/a/6364db99c5442c5d

All that aside, what is the ast type (`vector<variant<int, bool> >`)
intended to contain and how would you prefer to fill it? Can you give
sample files and sample result data?

Cheers


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Spirit parser question

sehe
In reply to this post by Jens Kallup
On 19-07-17 16:13, Jens Kallup wrote:
>
> if () missing, you get error output ;-)

This is not applicable


------------------------------------------------------------------------------
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
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general