Hallo,
ich habe Probleme beim Übersetzen dieses Codes.
was ist daran falsch?
ich habe Probleme beim Übersetzen dieses Codes.
was ist daran falsch?
C++:
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <typeinfo>
#include <set>
#include <utility>
using namespace std;
#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
#define BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/get.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
using namespace boost::spirit;
namespace bs = boost::spirit;
namespace phx = boost::phoenix;
namespace ascii = boost::spirit::ascii;
using boost::spirit::ascii::space; // use the ASCII space parser
using boost::spirit::ascii::char_;
using boost::spirit::_val;
using boost::phoenix::val;
#include <QString>
#include <QVariant>
#include <QMessageBox>
// ------------------------------------------------------
// namespace to avoid conflicts with other frameworks ...
// ------------------------------------------------------
namespace kallup
{
int line_no = 1;
QString number, ident;
double value = 0.00; // math
struct class_op;
struct binary_op;
struct unary_op;
struct nil { };
struct expression_ast
{
typedef
boost::variant<
nil
, int
, double
, std::string
, boost::recursive_wrapper<expression_ast>
, boost::recursive_wrapper<binary_op>
, boost::recursive_wrapper<unary_op>
, boost::recursive_wrapper<class_op>
>
type;
type expr;
template <typename Expr>
expression_ast(Expr const & expr)
: expr(expr) { }
expression_ast() {}
expression_ast(
std::string const& name
, std::string const& str1
, std::string const& str2
, expression_ast const& rhs);
expression_ast(expression_ast const & rhs, std::string const & name);
expression_ast& operator += (expression_ast const & rhs);
expression_ast& operator -= (expression_ast const & rhs);
expression_ast& operator *= (expression_ast const & rhs);
expression_ast& operator /= (expression_ast const & rhs);
};
expression_ast dast;
struct binary_op
{
binary_op(
char op
, expression_ast const & left
, expression_ast const & right)
: op(op)
, left(left)
, right(right)
{
std::cout << "Math2: " << std::endl;
}
char op;
expression_ast left;
expression_ast right;
};
struct unary_op
{
unary_op(
char op
, expression_ast const& subject)
: op(op), subject(subject) {}
char op;
expression_ast subject;
};
struct class_op
{
class_op(
std::string const& op
, std::string const& cname
, std::string const& oname
, expression_ast const& left
, expression_ast const& right)
: op(op)
, class_cname(cname)
, class_oname(oname)
, left(left)
, right(right) { }
std::string op;
std::string class_cname;
std::string class_oname;
expression_ast left;
expression_ast right;
};
expression_ast::expression_ast(expression_ast const & rhs, std::string const & name) {
cout << "dinit" << endl;
cout << name << endl;
cout << rhs.expr.type().name() << endl;
expr = rhs;
}
expression_ast::expression_ast (
std::string const& name
, std::string const& str1
, std::string const& str2, expression_ast const& rhs) {
expr = class_op(name, str1, str2, *this, rhs);
}
expression_ast& expression_ast::operator += (expression_ast const& rhs) {
expr = binary_op('+', expr, rhs);
return *this;
}
expression_ast& expression_ast::operator -= (expression_ast const& rhs) {
expr = binary_op('-', expr, rhs);
return *this;
}
expression_ast& expression_ast::operator *= (expression_ast const& rhs) {
expr = binary_op('*', expr, rhs);
return *this;
}
expression_ast& expression_ast::operator /= (expression_ast const& rhs) {
expr = binary_op('/', expr, rhs);
return *this;
}
// We should be using expression_ast::operator-. There's a bug
// in phoenix type deduction mechanism that prevents us from
// doing so. Phoenix will be switching to BOOST_TYPEOF. In the
// meantime, we will use a phoenix::function below:
struct negate_expr {
template <typename T>
struct result { typedef T type; };
expression_ast operator()(expression_ast & expr) const {
cout << "lllllllllllllllll\n";
return expression_ast(unary_op('-', expr));
}
};
phx::function<negate_expr> neg;
#if 0
struct __addnumber
{
template <typename T>
struct result { typedef T type; };
expression_ast operator()(expression_ast const &_expr, std::string &namber) const
{
cout << "scene: " << endl;
//dast = int(1);
cout << "add number ok." << endl;
//cout << _expr.expr.type().name() << endl;
return expression_ast(int(1)); //binary_op('+', _expr, _expr));
}
};
phx::function<__addnumber> _addnumber;
#endif
// -----------------------
// walk throug the AST ...
// -----------------------
struct ast_print
{
typedef void result_type;
void operator()(int const value)
{
cout << "const int = " << value << endl;
dast = value;
cout << dast.expr.type().name() << endl;
}
void operator()(expression_ast const& ast) const
{
//if (!(ast.expr.type().name() == std::string("N11dBaseParser3nilE")))
boost::apply_visitor(*this, ast.expr);
}
void operator()(binary_op const& expr) const
{
std::cout << "op:" << expr.op << "(";
boost::apply_visitor(*this, expr.left.expr);
std::cout << ", ";
boost::apply_visitor(*this, expr.right.expr);
std::cout << ')';
}
void operator()(unary_op const& expr) const
{
std::cout << "op:" << expr.op << "(";
boost::apply_visitor(*this, expr.subject.expr);
std::cout << ')';
}
void operator()(class_op const& expr) const
{
std::cout << "class:"
<< expr.class_cname << ":"
<< expr.class_oname
<< "(null)"
<< std::endl;
boost::apply_visitor(*this, expr.left.expr);
}
};
template <typename Lexer>
struct dbase_tokens : lex::lexer<Lexer>
{
// ----------------------------
// tokens with no attributes...
// ----------------------------
lex::token_def<lex::omit> whitespace;
lex::token_def<lex::omit> cpcomment;
lex::token_def<lex::omit> d_comment;
lex::token_def<lex::omit> c_comment;
lex::token_def<lex::omit> kw_class;
lex::token_def<lex::omit> kw_of;
lex::token_def<lex::omit> kw_endclass;
// --------------------------
// tokens with attributes ...
// --------------------------
lex::token_def<char> printLn;
lex::token_def<lex::omit> my_assign;
lex::token_def<int> number_digit;
lex::token_def<std::string> identifier;
lex::token_def<std::string> quoted_string;
dbase_tokens()
{
// ------------
// keywords ...
// ------------
kw_class = "(?i:class)";
kw_endclass = "(?i:endclass)";
kw_of = "(?i:of)";
printLn = "\\\?";
my_assign = "\\=";
// Values.
number_digit = "[0-9]*";
quoted_string = "\\\"(\\\\.|[^\\\"])*\\\"";
// Identifier.
identifier = "[a-zA-Z][a-zA-Z0-9_]*";
cpcomment = "\\/\\/[^\\n]*\\n"; // single line comment
d_comment = "\\*\\*[^\\n]*\\n"; // dBase line comment
c_comment = "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"; // c-style comments
whitespace = "[ \\t\\n]+";
this->self += lex::token_def<>
('(') | ')'
| '+' | '-'
| '*' | '/'
| ',' | '.';
this->self +=
printLn
;
this->self +=
kw_class | kw_of | kw_endclass
;
this->self +=
identifier
| my_assign
| number_digit
| quoted_string
;
this->self +=
whitespace [ lex::_pass = lex::pass_flags::pass_ignore ]
| cpcomment
| c_comment
| d_comment
;
}
};
template <typename Iterator, typename Lexer>
struct dbase_grammar
: public qi::grammar<Iterator>
{ template <typename TokenDef>
dbase_grammar(TokenDef & tok) :
dbase_grammar::base_type(start, "start")
{
using qi::_val;
start
= +symsbols
;
expression =
term [ _val = qi::_1 ]
>> *( ('+' >> term [ _val += qi::_1 ])
| ('-' >> term [ _val -= qi::_1 ])
)
;
term =
factor [ _val = qi::_1]
>> *( ('*' >> factor [ _val *= qi::_1])
| ('/' >> factor [ _val /= qi::_1])
)
;
factor =
tok.number_digit [ _val = qi::_1 ]
| '(' >> expression [ _val = qi::_1 ] >> ')'
| ('-' >> factor [ _val = neg(qi::_1)])
| ('+' >> factor [ _val = qi::_1 ] )
;
symsbols
= printLn
| comments
| class_definition
| h_expression
;
h_expression
= (tok.identifier >> *comments
>> tok.my_assign >> *comments
>> tok.number_digit >> *comments)
;
comments
= tok.cpcomment
| tok.c_comment
| tok.d_comment
;
printLn
= tok.printLn >> *comments >> tok.quoted_string
| tok.printLn >> tok.quoted_string
;
class_definition
= ( tok.kw_class >> *comments
>> tok.identifier >> *comments
>> tok.kw_of >> *comments
>> tok.identifier >> *comments >> class_body
>> tok.kw_endclass)
;
class_body
= *comments
;
start.name("start");
symsbols.name("symsbols");
comments.name("comments");
expression.name("expression");
term.name("term");
factor.name("factor");
printLn.name("printLn");
class_definition.name("class_definition");
class_body.name("class_body");
h_expression.name("h_expression");
}
typedef qi::unused_type skipper_type;
typedef qi::rule<Iterator, skipper_type> simple_rule;
simple_rule start, symsbols, comments, printLn;
simple_rule class_body;
qi::rule<Iterator, expression_ast()>
expression, term, factor
, h_expression
, class_definition;
};
class expression { public:
expression() { }
typedef boost::variant<
double
, std::string
>
expression_type;
expression_type expr;
};
class mystream {
public:
mystream() {
m_filePtr = nullptr;
}
mystream(char* fileName, int mode) {
try {
m_filePtr = nullptr;
open(fileName,mode);
} catch (...) {
std::cout << "can not open mem file.\n";
}
}
~mystream() {
close();
}
void open(char* fileName, int mode) {
if (m_filePtr != nullptr)
fclose(m_filePtr);
switch (mode)
{
case 0:
m_filePtr = fopen(fileName, "wb");
break;
case 1:
m_filePtr = fopen(fileName, "rb");
break;
}
}
void close() {
if (!m_filePtr)
fclose(m_filePtr);
}
void read(void *data, unsigned long size) {
if (m_filePtr) {
fread(data,1,size,m_filePtr);
}
}
void write(const void *data, unsigned long size) {
if (m_filePtr) {
fwrite(data,1,size,m_filePtr);
}
}
private:
FILE *m_filePtr;
};
template <class T>
inline mystream & operator << (mystream & s, T val) {
s.write(&val,sizeof(T));
return s;
}
template <class T>
inline mystream & operator >> (mystream & s, T val) {
s.read(&val,sizeof(T));
return s;
}
template<class T>
inline mystream & operator<<(mystream & s, const vector<T>& _arr)
{
s << (long)_arr.size();
if (_arr.size() > 0) s.write(&_arr.front(), (unsigned long)sizeof(T)*_arr.size());
return s;
}
template<class T>
inline mystream & operator>>(mystream & s, vector<T>& _arr)
{
long size;
s >> size;
if (size > 0) {
_arr.resize(size);
s.read(&_arr.front(), (unsigned long)sizeof(T)*_arr.size());
}
return s;
}
// -----------------------------------
// parser oode for an dBase parser ...
// -----------------------------------
class dBase {
public:
dBase() {
std::cout << "handle dbase grammar..."
<< std::endl;
}
bool InitParseText(QString text)
{
std::string data(text.toLatin1().data());
if (data.size() < 1) {
throw QString("No data for parser.");
return false;
}
typedef std::string::iterator base_iterator_type;
typedef lex::lexertl::token< base_iterator_type, boost::mpl::vector<char, int, std::size_t, std::string> > tokentype;
typedef lex::lexertl::actor_lexer<tokentype> lexer_type;
typedef dbase_tokens<lexer_type> dbase_tokens;
typedef dbase_tokens::iterator_type iterator_type;
typedef dbase_grammar<iterator_type, dbase_tokens::lexer_def> dbase_grammar;
dbase_tokens tokens;
dbase_grammar dbase(tokens);
base_iterator_type it = data.begin();
iterator_type iter = tokens.begin(it, data.end());
iterator_type end = tokens.end();
expression_ast ast;
return qi::parse(iter, end, dbase, ast);
}
void start(QString src) {
if (InitParseText(src)) {
QMessageBox::information(0,"Info","SUCCESS");
//ast_print printer;
//printer(dast);
} else {
QMessageBox::critical(0,"Error","ERROR");
}
}
};
template <typename T>
class Parser: public T {
public:
Parser() {
std::cout << "parser init." << std::endl;
line_no = 1;
ident .clear();
number.clear();
}
};
}
// int main() {
bool parseText(QString src)
{
using namespace kallup;
try {
Parser<dBase> p;
p.start(src);
QMessageBox::information(0,"Info","SUCCESS");
return true;
}
catch (QString &e) {
QMessageBox::critical(0,"Error",
QString("Error in line: %1\n%2")
.arg(line_no)
.arg(e));
}
return false;
}
Zuletzt bearbeitet von einem Moderator: