summaryrefslogtreecommitdiff
path: root/cli/cli/lexer.hxx
blob: bd7b0c9c10d69b7f3d46386a9dc9135974b16c5c (plain)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// file      : cli/lexer.hxx
// author    : Boris Kolpackov <boris@codesynthesis.com>
// license   : MIT; see accompanying LICENSE file

#ifndef CLI_LEXER_HXX
#define CLI_LEXER_HXX

#include <map>
#include <string>
#include <locale>
#include <cstddef> // std::size_t
#include <istream>

#include <cli/token.hxx>

class lexer
{
public:
  lexer (std::istream& is, std::string const& id);

  token
  next ();

  bool
  valid () const;

protected:
  class xchar
  {
  public:
    typedef std::char_traits<char> traits_type;
    typedef traits_type::int_type int_type;
    typedef traits_type::char_type char_type;

    xchar (int_type v, std::size_t l, std::size_t c);

    operator char_type () const;

    int_type
    value () const;

    std::size_t
    line () const;

    std::size_t
    column () const;

  private:
    int_type v_;
    std::size_t l_;
    std::size_t c_;
  };

  xchar
  peek ();

  xchar
  get ();

  void
  unget (xchar);

protected:
  class invalid_input {};

  void
  skip_spaces ();

  token
  identifier (xchar);

  token
  int_literal (xchar,
               bool neg = false,
               std::size_t ml = 0,
               std::size_t mc = 0);

  token
  char_literal (xchar);

  token
  string_literal (xchar);

  std::string
  string_literal_trailer ();

  token
  path_literal (xchar);

  token
  call_expression (xchar);

  token
  template_expression (xchar);

protected:
  bool
  is_alpha (char c) const;

  bool
  is_oct_digit (char c) const;

  bool
  is_dec_digit (char c) const;

  bool
  is_hex_digit (char c) const;

  bool
  is_alnum (char c) const;

  bool
  is_space (char c) const;

  bool
  is_eos (xchar const& c) const;

  char
  to_upper (char c) const;

private:
  typedef std::map<std::string, token::keyword_type> keyword_map;

  std::locale loc_;
  std::istream& is_;
  std::string id_;
  std::size_t l_;
  std::size_t c_;

  keyword_map keyword_map_;

  bool eos_;
  bool include_; // Literal in include or source.
  bool valid_;

  xchar buf_;
  bool unget_;
};

#include <cli/lexer.ixx>

#endif // CLI_LEXER_HXX