5 * Created by Bryan Donlan on Thu 11 Aug 2005.
6 * Copyright (c) 2005 Bryan Donlan. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
24 #include "exceptions.h"
28 #include <boost/variant.hpp>
29 #include <boost/format.hpp>
31 void yyrestart(std::istream
*stream
, bool use_c2
);
33 enum toktype
{ ANYTOKEN
= 0, EOI
= 0, TOK_CONST
, TOK_WORD
, TOK_BYTESTR
};
38 struct type_visitor
: public boost::static_visitor
<toktype
> {
39 toktype
operator()(const token_eoi
) const { return EOI
; }
40 toktype
operator()(const caosVar
&) const { return TOK_CONST
; }
41 toktype
operator()(const std::string
&) const { return TOK_WORD
; }
42 toktype
operator()(const bytestring_t
&) const { return TOK_BYTESTR
; }
44 struct dump_visitor
: public boost::static_visitor
<std::string
> {
45 std::string
operator()(const token_eoi
) const { return std::string("EOI"); }
46 std::string
operator()(const caosVar
&v
) const { return std::string(v
.dump()); }
47 std::string
operator()(const std::string
&v
) const { return v
; }
48 std::string
operator()(const bytestring_t
&bs
) const {
49 std::ostringstream oss
;
51 for (size_t i
= 0; i
< bs
.size(); i
++)
57 struct fmt_visitor
: boost::static_visitor
<std::string
> {
58 std::string
operator()(const token_eoi
) const { return std::string("<EOI>"); }
59 std::string
operator()(const caosVar
&v
) const {
61 return boost::str(boost::format("%d") % v
.getInt());
62 } else if (v
.hasFloat()) {
63 return boost::str(boost::format("%f") % v
.getFloat());
64 } else if (v
.hasString()) {
65 std::ostringstream outbuf
;
66 std::string inbuf
= v
.getString();
68 for (size_t i
= 0; i
< inbuf
.size(); i
++) {
70 case '\n': outbuf
<< "\\\n"; break;
71 case '\r': outbuf
<< "\\\r"; break;
72 case '\t': outbuf
<< "\\\t"; break;
73 case '\"': outbuf
<< "\\\""; break;
74 default: outbuf
<< inbuf
[i
]; break;
80 throw creaturesException(std::string("Impossible caosvar type in token: ") + v
.dump());
83 std::string
operator()(const std::string
&word
) const { return word
; }
84 std::string
operator()(const bytestring_t
&bs
) const {
85 std::ostringstream oss
;
87 for (size_t i
= 0; i
< bs
.size(); i
++)
97 boost::variant
<token_eoi
, std::string
, caosVar
, bytestring_t
> payload
;
102 toktype
type() const {
103 return boost::apply_visitor(type_visitor(), payload
);
106 const bytestring_t
&bytestr() const {
107 const bytestring_t
*bs
= boost::get
<bytestring_t
>(&payload
);
108 if (!bs
) unexpected();
112 const std::string
&word() const {
113 const std::string
*s
= boost::get
<std::string
>(&payload
);
114 if (!s
) unexpected();
118 const caosVar
&constval() const {
119 const caosVar
*s
= boost::get
<caosVar
>(&payload
);
120 if (!s
) unexpected();
124 token(const token
&cp
) : payload(cp
.payload
), index(cp
.index
), lineno(cp
.lineno
) { }
125 token(const caosVar
&cv
, int lineno_
) : payload(cv
), index(-1), lineno(lineno_
) {}
126 token(const std::string
&word
, int lineno_
) : payload(word
), index(-1), lineno(lineno_
) {}
127 token(const bytestring_t
&bs
, int lineno_
) : payload(bs
), index(-1), lineno(lineno_
) {}
129 std::string
dump() const {
130 std::ostringstream oss
;
131 oss
<< boost::apply_visitor(dump_visitor(), payload
);
132 oss
<< " (line " << lineno
<< ")";
136 std::string
format() const {
137 return boost::apply_visitor(fmt_visitor(), payload
);
140 void unexpected() const {
143 case EOI
: err
= "EOI"; break;
144 case TOK_WORD
: err
= "word"; break;
145 case TOK_BYTESTR
: err
= "bytestring"; break;
146 case TOK_CONST
: err
= "constant value"; break;
147 default: throw creaturesException("Internal error: unable to classify token in token::unexpected()");
150 throw parseException(std::string("Unexpected ") + err
);
154 extern token lasttok
; // internal use only