JsonLex.cpp
Go to the documentation of this file.
1 #include "JsonLex.hpp"
2 
3 namespace iv
4 {
5 
7  cm( inst, this, "JsonLex" ),
8  _lex( inst ),
9  next( Next::Value ),
10  layer_types()
11 {
12  this->cm.owns( this->_lex.cm );
13 
14  this->_lex.DefineOperator( "," );
15  this->_lex.DefineOperator( ":" );
16  this->_lex.DefineOperator( "{" );
17  this->_lex.DefineOperator( "}" );
18  this->_lex.DefineOperator( "[" );
19  this->_lex.DefineOperator( "]" );
20 
21  this->_lex.DefineKeyword( "true" );
22  this->_lex.DefineKeyword( "false" );
23  this->_lex.DefineKeyword( "null" );
24 }
25 
27 {
28  return this->_lex.instance();
29 }
30 
31 Lex const & JsonLex::lex() const
32 {
33  return this->_lex;
34 }
35 
36 void JsonLex::Init( std::istream & in )
37 {
38  this->next = Next::Value;
39  this->layer_types = std::stack< LayerType >();
40  this->_lex.Init( in );
41 }
42 
44 {
45  return this->_lex.Failed();
46 }
47 
48 bool JsonLex::IsNext( Token token )
49 {
50  switch( token )
51  {
52  case Token::Integer:
53  return this->next == Next::Value && this->_lex.IsNext( Lex::Integer );
54 
55  case Token::Double:
56  return this->next == Next::Value && this->_lex.IsNext( Lex::Double );
57 
58  case Token::String:
59  return this->next == Next::Value && this->_lex.IsNext( Lex::String );
60 
61  case Token::Bool:
62  return this->next == Next::Value && ( this->_lex.IsNextKeyword( "true" ) || this->_lex.IsNextKeyword( "false" ) );
63 
64  case Token::Null:
65  return this->next == Next::Value && this->_lex.IsNextKeyword( "null" );
66 
67  case Token::ArrayBegin:
68  return this->next == Next::Value && this->_lex.IsNextOperator( "[" );
69 
70  case Token::ArrayEnd:
71  return this->next == Next::ArrayEnd && this->_lex.IsNextOperator( "]" );
72 
73  case Token::TableBegin:
74  return this->next == Next::Value && this->_lex.IsNextOperator( "{" );
75 
76  case Token::TableEnd:
77  return this->next == Next::TableEnd && this->_lex.IsNextOperator( "}" );
78 
79  case Token::TableKey:
80  return this->next == Next::TableKey && this->_lex.IsNext( Lex::String );
81 
82  case Token::Eof:
83  return this->next == Next::Eof && this->_lex.IsNext( Lex::Eof );
84 
85  default:
86  return false;
87  }
88 }
89 
90 void JsonLex::value_ended()
91 {
92  if( this->layer_types.empty() )
93  {
94  this->next = Next::Eof;
95  }
96  else
97  {
98  LayerType type = this->layer_types.top();
99  if( type == LayerType::Array )
100  {
101  if( this->_lex.IsNextOperator( "," ) )
102  {
103  this->_lex.AcceptOperator( "," );
104  this->next = Next::Value;
105  }
106  else
107  {
108  this->next = Next::ArrayEnd;
109  }
110  }
111  else
112  {
113  if( this->_lex.IsNextOperator( "," ) )
114  {
115  this->_lex.AcceptOperator( "," );
116  this->next = Next::TableKey;
117  }
118  else
119  {
120  this->next = Next::TableEnd;
121  }
122  }
123  }
124 }
125 
126 void JsonLex::JsonFail()
127 {
128  //this->_lex.LogicFail( "Json structure problem." );
129  this->_lex.ParserFail( "JsonFail" );
130 }
131 
132 void JsonLex::Accept( Token token )
133 {
134  if( !this->IsNext( token ) )
135  {
136  this->JsonFail();
137  return;
138  }
139 
140  switch( token )
141  {
142  case Token::Integer:
143  this->_lex.Accept( Lex::Integer );
144  this->value_ended();
145  break;
146 
147  case Token::Double:
148  this->_lex.Accept( Lex::Double );
149  this->value_ended();
150  break;
151 
152  case Token::String:
153  this->_lex.Accept( Lex::String );
154  this->value_ended();
155  break;
156 
157  case Token::Bool:
158  if( this->_lex.IsNextKeyword( "true" ) )
159  this->_lex.AcceptKeyword( "true" );
160  else
161  this->_lex.AcceptKeyword( "false" );
162  this->value_ended();
163  break;
164 
165  case Token::Null:
166  this->_lex.AcceptKeyword( "null" );
167  this->value_ended();
168  break;
169 
170  case Token::ArrayBegin:
171  this->_lex.AcceptOperator( "[" );
172  this->layer_types.push( LayerType::Array );
173  if( this->_lex.IsNextOperator( "]" ) )
174  this->next = Next::ArrayEnd;
175  else
176  this->next = Next::Value;
177  break;
178 
179  case Token::ArrayEnd:
180  this->_lex.AcceptOperator( "]" );
181  this->layer_types.pop();
182  this->value_ended();
183  break;
184 
185  case Token::TableKey:
186  this->_lex.Accept( Lex::String );
187  this->_lex.AcceptOperator( ":" );
188  this->next = Next::Value;
189  break;
190 
191  case Token::TableBegin:
192  this->_lex.AcceptOperator( "{" );
193  this->layer_types.push( LayerType::Table );
194  if( this->_lex.IsNextOperator( "}" ) )
195  this->next = Next::TableEnd;
196  else
197  this->next = Next::TableKey;
198  break;
199 
200  case Token::TableEnd:
201  this->_lex.AcceptOperator( "}" );
202  this->layer_types.pop();
203  this->value_ended();
204  break;
205 
206  case Token::Eof:
207  this->_lex.Accept( Lex::Eof );
208  break;
209  }
210 }
211 
213 {
214  if( !this->IsNext( Token::TableKey ) )
215  {
216  this->JsonFail();
217  return "";
218  }
219 
220  auto result = this->_lex.AcceptString();
221  this->_lex.AcceptOperator( ":" );
222  this->next = Next::Value;
223  return result;
224 }
225 
227 {
228  if( !this->IsNext( Token::Integer ) )
229  {
230  this->JsonFail();
231  return 0;
232  }
233 
234  auto result = this->_lex.AcceptInteger();
235  this->value_ended();
236  return result;
237 }
238 
240 {
241  if( !this->IsNext( Token::Double ) )
242  {
243  this->JsonFail();
244  return 0.0;
245  }
246 
247  auto result = this->_lex.AcceptDouble();
248  this->value_ended();
249  return result;
250 }
251 
253 {
254  if( !this->IsNext( Token::String ) )
255  {
256  this->JsonFail();
257  return "";
258  }
259 
260  std::string result = this->_lex.AcceptString();
261  this->value_ended();
262  return result;
263 }
264 
266 {
267  if( !this->IsNext( Token::Bool ) )
268  {
269  this->JsonFail();
270  return false;
271  }
272 
273  bool result;
274  if( this->_lex.IsNextKeyword( "true" ) )
275  {
276  this->_lex.AcceptKeyword( "true" );
277  result = true;
278  }
279  else
280  {
281  this->_lex.AcceptKeyword( "false" );
282  result = false;
283  }
284  this->value_ended();
285  return result;
286 }
287 
289 {
290  if( !this->IsNext( Token::Null ) )
291  {
292  this->JsonFail();
293  return;
294  }
295 
296  this->_lex.AcceptKeyword( "null" );
297  this->value_ended();
298 }
299 
300 }