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