2
0
mirror of https://github.com/boostorg/spirit.git synced 2026-01-19 04:42:11 +00:00
Files
spirit/example/application/cpp_lexer/cpp_lexer_test.cpp
2003-01-31 11:11:39 +00:00

147 lines
3.8 KiB
C++

//
// C++ Lexer implemented with Spirit (http://spirit.sourceforge.net/)
//
// Copyright© 2002 Juan Carlos Arevalo-Baeza, All rights reserved
// email: jcab@JCABs-Rumblings.com
// Created: 8-Nov-2002
//
#include "cpp_lexer.hpp"
#include <boost/spirit/core.hpp>
#include <boost/spirit/utility/functor_parser.hpp>
#include <boost/phoenix/primitives.hpp>
#include <boost/phoenix/composite.hpp>
#include <boost/phoenix/functions.hpp>
#include <boost/phoenix/operators.hpp>
#include <boost/phoenix/special_ops.hpp>
#include <boost/phoenix/binders.hpp>
#include <boost/phoenix/statements.hpp>
///////////////////////////////////////////////////////////////////////////////
// used namespaces
using namespace boost::spirit;
using phoenix::var;
///////////////////////////////////////////////////////////////////////////////
struct get_file_position_parser {
boost::spirit::file_position& filePos;
get_file_position_parser(boost::spirit::file_position& filePos_):
filePos(filePos_)
{}
typedef nil_t result_t;
template < typename ScannerT >
int operator()(ScannerT const& scan, result_t& result) const {
if (scan.at_end()) {
return -1;
}
filePos = scan.first->filePos;
return 0;
}
};
boost::spirit::functor_parser<get_file_position_parser>
get_file_position_p(boost::spirit::file_position& filePos)
{
return get_file_position_parser(filePos);
}
///////////////////////////////////////////////////////////////////////////////
struct test_grammar: grammar<test_grammar> {
template < typename ScannerT >
struct definition {
typedef rule<ScannerT> rule_t;
rule_t main;
rule_t const& start() const {
return main;
}
boost::spirit::file_position filePos;
definition(test_grammar const& self) {
main =
*(
ch_p(Kwd_using)[var(std::cout) << " using "]
| ch_p(EOL_token) >> get_file_position_p(filePos)[var(std::cout) << "\n" << var(filePos)]
| anychar_p[OutToken][var(std::cout) << " "]
);
}
};
};
///////////////////////////////////////////////////////////////////////////////
// main entrypoint
int
main(int argc, char* argv[])
{
// Start grammar definition
std::cerr << "C++ Lexer implemented with Spirit ..." << std::endl;
char const* rule = "";
char const* fname = "";
// main driver code
if (3 == argc) {
std::cerr << "Using rule " << argv[2] << std::endl;
fname = argv[1];
rule = argv[2];
} else if (2 == argc) {
fname = argv[1];
} else {
std::cerr << "No filename given" << std::endl;
fname = "cpp_lexer.cpp";
std::cerr << "Parsing " << fname << std::endl;
}
FILE* f = fopen(fname, "rb");
if (!f) {
std::cerr << "Cannot open input file: " << fname << std::endl;
}
fseek(f, 0, SEEK_END);
int const size = ftell(f);
fseek(f, 0, SEEK_SET);
char *buf = new char[size];
fread(buf, 1, size, f);
fclose(f);
std::cout << "File size: " << size << " bytes\n";
Token token;
test_grammar grammar;
lex_iterator first(buf, buf+size, fname);
lex_iterator last;
parse_info<lex_iterator> result =
parse(
first, last,
grammar,
ch_p(Comment_token)
)
;
if (result.full) {
std::cerr << "\n" << fname << " Parses OK" << std::endl;
} else {
std::cerr << "\n" << fname << " Fails Parsing" << std::endl;
std::cerr << "These tokens follow:\n";
for (int i = 0; i < 10; i++)
{
if (result.stop == last) {
break;
}
PrintToken(*result.stop++);
}
}
return 0;
}