File: Lexer.h

package info (click to toggle)
freeorion 0.5.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 194,940 kB
  • sloc: cpp: 186,508; python: 40,969; ansic: 1,164; xml: 719; makefile: 32; sh: 7
file content (108 lines) | stat: -rw-r--r-- 3,808 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#ifndef _Lexer_h_
#define _Lexer_h_

#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS

#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/lex_lexertl_position_token.hpp>

#include "Tokens.h"

#include <unordered_map>

/** \namespace parse \brief The namespace that encloses the script file lexer
    and parser. */
namespace parse {

/** The type of iterator used by the script file lexer. */
typedef std::string::const_iterator text_iterator;

/** The type of token used by the script file lexer. */
typedef boost::spirit::lex::lexertl::position_token<
    text_iterator,
    boost::mpl::vector<
        bool,
        int,
        double,
        std::string
    >
> token_type;

typedef boost::spirit::lex::lexertl::actor_lexer<token_type> spirit_lexer_base_type;

/** The script file lexer. */
struct lexer : boost::spirit::lex::lexer<spirit_lexer_base_type> {
    lexer();

    /** \name Comment tokens */ ///@{
    boost::spirit::lex::token_def<boost::spirit::lex::omit> inline_comment;
    boost::spirit::lex::token_def<boost::spirit::lex::omit> end_of_line_comment;
    //@}

    using string_token_def = boost::spirit::lex::token_def<std::string>;

    /** \name Tokens for common C++ types and builtins. */ ///@{
    boost::spirit::lex::token_def<bool> bool_;
    boost::spirit::lex::token_def<int> int_;
    boost::spirit::lex::token_def<double> double_;
    boost::spirit::lex::token_def<std::string> string;
    //@}

    /** \name Keyword tokens.  These should be kept in lexicographically
        sorted order, so that finding, adding, and removing tokens is a bit
        easier.  See the note above the Enum tokens section. */ ///@{
#define DECLARE_TOKEN(r, _, name) string_token_def BOOST_PP_CAT(name, _);
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_1)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_2)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_3)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_4)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_5)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_6)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_7)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_8)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_9)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_10)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_11)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_12)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_13)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_14)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_15)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_16)
    BOOST_PP_SEQ_FOR_EACH(DECLARE_TOKEN, _, TOKEN_SEQ_17)
#undef DECLARE_TOKEN
    //@}

    /** \name Error token. */ ///@{
    boost::spirit::lex::token_def<boost::spirit::lex::omit> error_token;
    //@}

    static inline const std::string bool_regex{"(?i:true|false)"};
    static inline const std::string int_regex{"\\d+"};
    static inline const std::string double_regex{"\\d+\\.\\d*|\\d*\\.\\d+"};
    static inline const std::string string_regex{"\\\"[^\\\"]*\\\""};
};

inline const lexer& GetLexer() {
    static const lexer tok;
    return tok;
}

/** The type of iterator passed to the script file parser by the script file
    lexer. */
typedef lexer::iterator_type token_iterator;

typedef lexer::lexer_def lexer_def;

/** The type of the skip-parser, defined in the script file lexer, used by the
    script file parser iterator. */
typedef boost::spirit::qi::in_state_skipper<lexer_def> skipper_type;

}

namespace boost { namespace spirit { namespace traits {

    // If you want to create a token with a custom value type, you must
    // declare the conversion handler here, and define it in the .cpp file.
} } }

#endif