Вход на сайт
Compiler или Scaner или ...??
188 просмотров
Перейти к просмотру всей ветки
scorpi_ скептик
в ответ MARGA_ 18.02.08 14:15
Это не компайлер, это парсер. Идём сюда - http://www.antlr.org/, скачиаваем, пишем грамматику и т.д. Задача правда несколько странная, ибо грамматика должна быть несколько сложнее.
PS На С++ такой парсер пишется кстати очень просто с помощью Boost.Spirit.
Ausgabe:
Если порядок важен, то занать данные вместо map в vector< pair< string, string > >.
PS На С++ такой парсер пишется кстати очень просто с помощью Boost.Spirit.
В ответ на:
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
#pragma warning( disable: 4224 )
#include <boost/spirit/core.hpp>
#include <boost/spirit/utility.hpp>
#include <boost/spirit/actor.hpp>
using namespace boost::spirit;
typedef std::map< std::string, std::string> data_t;
struct margo_parser : public grammar< margo_parser >
{
data_t& data;
margo_parser( data_t& data_ ) : data(data_){}
template< typename ScannerT >
struct definition
{
definition( margo_parser const& self )
{
data_t& d = self.data;
query
= +(
META [ assign_key_a(d, "TypeMetafield") ]
| KEYWORD [ assign_key_a(d, "Schluesselwort") ]
| SIMPLE [ assign_key_a(d, "Phrase") ]
| PHRASE [ assign_key_a(d, "EinachQuery") ]
)
;
META
= lexeme_d[ +alnum_p >> ch_p(':') >> +alnum_p ]
;
KEYWORD
= str_p( "or" ) | str_p( "and" )
;
PHRASE
= confix_p( '"', *print_p, '"' )
;
SIMPLE
= +alnum_p
;
}
rule<ScannerT> query, META, KEYWORD, PHRASE, SIMPLE;
const rule<ScannerT>& start() const { return query; }
};
};
int main()
{
std::string s( "autor:galina and \"haus und test\" or irgendwasWasIchSuche" );
data_t data;
parse_info<> info = parse( s.c_str(), margo_parser(data), space_p );
if ( info.full )
{
std::cout << "Parsing successfull!\n\n";
for( data_t::const_iterator it = data.begin(); it != data.end(); ++it )
std::cout << "(" << it->first << ", " << it->second << ")\n";
}
else
{
std::cout << "Parsing error!\n\n"
<< s.substr( std::max( int(info.stop - 30), 0 ), 60 ) << "\n"
<< std::string( std::max( 30, int(info.stop) ), ' ' ) << "^\n\n";
}
}
Ausgabe:
В ответ на:
Parsing successfull!
("haus und test", EinachQuery)
(and, Schluesselwort)
(autor:galina, TypeMetafield)
(irgendwasWasIchSuche, Phrase)
(or, Schluesselwort)
Если порядок важен, то занать данные вместо map в vector< pair< string, string > >.