/
ScannerSax.cpp
170 lines (151 loc) · 6.22 KB
/
ScannerSax.cpp
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "ScannerSax.h"
#include "LexerJson.h"
#include "ParserShiftReduce.h"
#include "ParserRecursive.h"
#include <sstream>
#include <list>
namespace ThorsAnvil
{
namespace Json
{
class ScannerSaxInterface: public ParserCleanInterface
{
std::list<int> currentArrayIndex;
ScannerSax& parent;
public:
ScannerSaxInterface(ScannerSax& p): parent(p) {}
virtual void mapOpen() { parent.push_mapAction();}
virtual void mapClose() { parent.pop_mapAction();}
virtual std::string* mapKeyNote(std::string* k) { std::auto_ptr<std::string> ak(k); parent.preActivate(*ak); return ak.release();}
virtual JsonMapValue* mapCreateElement(std::string* k,JsonValue* val) { std::auto_ptr<std::string> ak(k); std::auto_ptr<JsonValue> aval(val); parent.activate(*ak, *aval); return NULL;}
virtual void arrayOpen() { currentArrayIndex.push_front(0); parent.push_arrAction(); parent.preActivate(currentArrayIndex.front());}
virtual void arrayClose() { currentArrayIndex.pop_front(); parent.pop_arrAction();}
virtual JsonArray* arrayNote(JsonArray* arr) { std::auto_ptr<JsonArray> aarr(arr); parent.preActivate(currentArrayIndex.front());return NULL;}
virtual JsonValue* arrayCreateElement(JsonValue* val) { std::auto_ptr<JsonValue> aval(val); parent.activate(currentArrayIndex.front()++, *aval);return NULL;}
virtual JsonValue* valueParseString(std::string* str) { std::auto_ptr<std::string> astr(str); return new JsonStringItem(astr);}
virtual JsonValue* valueParseNumber(std::string* num) { std::auto_ptr<std::string> anum(num); return new JsonNumberItem(anum);}
virtual JsonValue* valueParseBool(bool val) { return new JsonBoolItem(val);}
virtual JsonValue* valueParseNULL() { return new JsonNULLItem();}
virtual std::string* getStringLexer(LexerJson& lexer) { return new std::string(getString(lexer));}
virtual std::string* getNumberLexer(LexerJson& lexer) { return new std::string(getNumber(lexer));}
};
}
}
using namespace ThorsAnvil::Json;
ScannerSax::ScannerSax()
: mapActions(1, ScannerMapActionMap())
, arrActions(1, ScannerArrActionMap())
, mapAction(mapActions.begin())
, arrAction(arrActions.begin())
{
mapActions.push_front(ScannerMapActionMap());
arrActions.push_front(ScannerArrActionMap());
}
ScannerSax::~ScannerSax()
{
}
template<typename Parser>
void ScannerSax::parse(std::istream& src)
{
ScannerSaxInterface scanner(*this);
LexerJson lexer(src);
Parser parser(lexer, scanner);
parser.parse();
}
ActionRefNote ScannerSax::registerActionOnAllMapItems(std::auto_ptr<SaxAction> action)
{
// \xFF is an invalid UTF-8 character
// The parser will never generate mapItem of this string
return registerAction("\xFF", action);
}
ActionRefNote ScannerSax::registerAction(std::string const& mapItem, std::auto_ptr<SaxAction> action)
{
SaxAction*& location = mapActions.front()[mapItem];
std::auto_ptr<SaxAction> oldLocation(location);
location = action.release();
return &location;
}
ActionRefNote ScannerSax::registerActionOnAllArrItems(std::auto_ptr<SaxAction> action)
{
SaxAction*& location = arrActions.front().map[-1];
std::auto_ptr<SaxAction> oldLocation(location);
location = action.release();
return &location;
}
ActionRefNote ScannerSax::registerActionNext(std::auto_ptr<SaxAction> action)
{
int index = arrActions.front().max++;
SaxAction*& location = arrActions.front().map[index];
std::auto_ptr<SaxAction> oldLocation(location);
location = action.release();
return &location;
}
void ScannerSax::replaceAction(ActionRefNote oldActionRef, std::auto_ptr<SaxAction> action)
{
SaxAction*& location = *reinterpret_cast<SaxAction**>(oldActionRef);
std::auto_ptr<SaxAction> oldLocation(location);
location = action.release();
}
SaxAction* ScannerSax::getAction(std::string const& mapItem)
{
SaxAction* action = NULL;
ScannerMapActionMap::const_iterator find1;
ScannerMapActionMap::const_iterator find2;
if ((find1 = mapAction->find(mapItem)) != mapAction->end())
{
action = find1->second;
}
else if ((find2 = mapAction->find("\xFF")) != mapAction->end())
{
action = find2->second;
}
return action;
}
SaxAction* ScannerSax::getAction(int index)
{
SaxAction* action = NULL;
ScannerArrActionMap::const_iterator find;
if ((find = arrAction->find(index)) != arrAction->end())
{
action = find->second;
}
else if ((find = arrAction->find(-1)) != arrAction ->end())
{
action = find->second;
}
return action;
}
void ScannerSax::preActivate(std::string const& mapItem)
{
SaxAction* action = getAction(mapItem);
if (action != NULL)
{
action->doPreAction(*this, Key(mapItem));
}
}
void ScannerSax::preActivate(int index)
{
SaxAction* action = getAction(index);
if (action != NULL)
{
action->doPreAction(*this, Key(index));
}
}
void ScannerSax::activate(std::string const& mapItem, JsonValue const& value)
{
SaxAction* action = getAction(mapItem);
if (action != NULL)
{
action->doAction(*this, Key(mapItem), value);
}
}
void ScannerSax::activate(int index, JsonValue const& value)
{
SaxAction* action = getAction(index);
if (action != NULL)
{
action->doAction(*this, Key(index), value);
}
}
template void ScannerSax::parse<yy::ParserShiftReduce>(std::istream& src);
template void ScannerSax::parse<ThorsAnvil::Json::ParserRecursive>(std::istream& src);