|
Boost Users : |
From: ope (ope-devel_at_[hidden])
Date: 2008-02-19 13:44:41
Hi,
my first parser and problems :-) Well, obviously I didn't understood the
translation of BNF in spirit (probably BNF also); attached the code.
The result is:
$ g++ spirit.cpp -o spirit && ./spirit
[Date] =
"[Data Ver] 3.4 "
^-- error ("D")
[Data Ver] = 0
"[File Name] foo.csv"
^-- error ("F")
[File Name] =
[Notes] = y
Can anybody help? Further more I need to replace the comment symbol rule
dynamically ("[Comment Char]") for the data self (not displayed here).
Thanks,
Olaf
---8<---
#include <boost/spirit/core.hpp>
#include <boost/spirit/symbols/symbols.hpp>
#include <boost/spirit/utility/chset.hpp>
#include <boost/spirit/utility/escape_char.hpp>
#include <boost/spirit/utility/confix.hpp>
#include <boost/spirit/actor.hpp>
#include <iostream>
#include <iomanip>
namespace sp = ::boost::spirit;
struct data {
std::pair<int, int> data_ver; // major,minor
std::string comment_char;
std::string file_name;
std::string file_rev;
std::string date;
std::string notes;
};
struct grammar
: public sp::grammar<grammar>
{
explicit grammar( data& data )
: m_data( data )
{ }
template <typename ScannerT>
struct definition
{
definition( const grammar& self )
{
typedef sp::chset<char> chset_t;
using sp::comment_p;
using sp::int_p;
using sp::anychar_p;
using sp::blank_p;
using sp::lexeme_d;
using sp::as_lower_d;
using sp::assign_a;
using sp::strlit;
data& data = self.m_data;
chset_t COMMENT_SYMBOL_CHSET( "!\"#$%&'()*,:;<>?@\\^`{|}~" );
chset_t FILE_NAME_CHSET(
"abcdefghijklmnopqrstuvwxyz0123456789_^$~!#%&-{})(@'`" );
std::pair<int, int> v( 0, 0 );
document
= comment
| data_ver
| comment_char
| file_name
| file_rev
| date
| notes
;
comment
= comment_p('|')
;
data_ver
=
( lexeme_d[strlit<>("[Data Ver]")]
>> int_p[assign_a(v.first)]
>> '.'
>> int_p[assign_a(v.second)]
)[assign_a( data.data_ver, v )]
;
comment_char
= lexeme_d[strlit<>("[Comment Char]")]
// FixMe: dynamic rule for comment !!!
>> COMMENT_SYMBOL_CHSET[assign_a( data.comment_char )]
>> "_char"
;
file_name
=
( lexeme_d[strlit<>("[File Name]")]
>> ( +FILE_NAME_CHSET
>> "."
>> (
as_lower_d[".csv"]
| as_lower_d[".txt"]
)
)
)[assign_a( data.file_name )]
;
file_rev
= lexeme_d[strlit<>("[File Rev]")]
>> (
// treated as string
+anychar_p
)[assign_a( data.file_rev )]
;
date
= "[Date]"
>> (
// treated as string
+anychar_p[assign_a( data.date )]
)
;
notes
= "[Notes]"
>> (
// treated as string
+anychar_p[assign_a( data.notes )]
)
;
}
sp::rule<ScannerT> const& start() const { return document; }
sp::rule<ScannerT> document, comment,
data_ver,
comment_char,
file_name,
file_rev,
date,
notes
;
};
private:
data& m_data;
};
template <typename GrammarT>
static void
parse(GrammarT const& grammar, std::string expr)
{
std::string::iterator first = expr.begin();
sp::parse_info<std::string::iterator> result
= sp::parse(first, expr.end(), grammar);
if ( !result.hit ) {
std::cerr << "\"" << expr << "\""
<< std::endl;
std::cerr << std::setw(result.stop - expr.begin() + 1)
<< "^-- error ("
<< "\"" << *result.stop << "\")"
<< std::endl;
}
else if ( !result.full ) {
first = result.stop;
}
}
int main()
{
data d;
grammar g( d );
parse( g, "[Date] 19.03.2008 | yeah " );
std::cout << "[Date] = " << d.date << std::endl;
parse( g, "[Data Ver] 3.4 " );
std::cout << "[Data Ver] = " << d.data_ver.first << std::endl;
parse( g, "[File Name] foo.csv" );
std::cout << "[File Name] = " << d.file_name << std::endl;
parse( g, "[Notes] Use this section for any special notes
related to the file."
" This information is for modeling
purposes only, and is not"
" guaranteed. | May
vary");
std::cout << "[Notes] = " << d.notes << std::endl;
}
--->8---
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