Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
belr
Commits
97a8c821
Commit
97a8c821
authored
Jan 05, 2015
by
Simon Morlat
Browse files
templatized parser, with the base type for all parsed elements.
parent
a9f7564e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
237 additions
and
166 deletions
+237
-166
src/belr.cc
src/belr.cc
+10
-10
src/belr.hh
src/belr.hh
+10
-10
src/grammarbuilder.cc
src/grammarbuilder.cc
+1
-0
src/grammarbuilder.hh
src/grammarbuilder.hh
+1
-1
src/parser-impl.cc
src/parser-impl.cc
+148
-0
src/parser.cc
src/parser.cc
+1
-104
src/parser.hh
src/parser.hh
+66
-41
No files found.
src/belr.cc
View file @
97a8c821
...
...
@@ -18,10 +18,10 @@ const string &Recognizer::getName()const{
return
mName
;
}
size_t
Recognizer
::
feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
Recognizer
::
feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
match
;
shared_ptr
<
HandlerContext
>
hctx
=
ctx
->
beginParse
(
shared_from_this
());
shared_ptr
<
HandlerContext
Base
>
hctx
=
ctx
->
beginParse
(
shared_from_this
());
match
=
_feed
(
ctx
,
input
,
pos
);
if
(
match
!=
string
::
npos
&&
match
>
0
){
if
(
0
&&
mName
.
size
()
>
0
){
...
...
@@ -43,7 +43,7 @@ CharRecognizer::CharRecognizer(int to_recognize, bool caseSensitive) : mToRecogn
}
}
size_t
CharRecognizer
::
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
CharRecognizer
::
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
if
(
mCaseSensitive
){
return
input
[
pos
]
==
mToRecognize
?
1
:
string
::
npos
;
}
...
...
@@ -58,10 +58,10 @@ shared_ptr<Selector> Selector::addRecognizer(const shared_ptr<Recognizer> &r){
return
static_pointer_cast
<
Selector
>
(
shared_from_this
());
}
size_t
Selector
::
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
Selector
::
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
matched
=
0
;
size_t
bestmatch
=
0
;
shared_ptr
<
HandlerContext
>
bestBranch
;
shared_ptr
<
HandlerContext
Base
>
bestBranch
;
for
(
auto
it
=
mElements
.
begin
();
it
!=
mElements
.
end
();
++
it
){
auto
br
=
ctx
->
branch
();
...
...
@@ -84,7 +84,7 @@ size_t Selector::_feed(const shared_ptr<ParserContext> &ctx, const string &input
ExclusiveSelector
::
ExclusiveSelector
(){
}
size_t
ExclusiveSelector
::
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
ExclusiveSelector
::
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
matched
=
0
;
for
(
auto
it
=
mElements
.
begin
();
it
!=
mElements
.
end
();
++
it
){
...
...
@@ -105,7 +105,7 @@ shared_ptr<Sequence> Sequence::addRecognizer(const shared_ptr<Recognizer> &eleme
return
static_pointer_cast
<
Sequence
>
(
shared_from_this
());
}
size_t
Sequence
::
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
Sequence
::
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
matched
=
0
;
size_t
total
=
0
;
...
...
@@ -132,7 +132,7 @@ shared_ptr<Loop> Loop::setRecognizer(const shared_ptr<Recognizer> &element, int
return
static_pointer_cast
<
Loop
>
(
shared_from_this
());
}
size_t
Loop
::
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
Loop
::
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
matched
=
0
;
size_t
total
=
0
;
int
repeat
;
...
...
@@ -150,7 +150,7 @@ size_t Loop::_feed(const shared_ptr<ParserContext> &ctx, const string &input, si
CharRange
::
CharRange
(
int
begin
,
int
end
)
:
mBegin
(
begin
),
mEnd
(
end
){
}
size_t
CharRange
::
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
CharRange
::
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
int
c
=
input
[
pos
];
if
(
c
>=
mBegin
&&
c
<=
mEnd
)
return
1
;
return
string
::
npos
;
...
...
@@ -192,7 +192,7 @@ shared_ptr<Recognizer> RecognizerPointer::getPointed(){
return
mRecognizer
;
}
size_t
RecognizerPointer
::
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
size_t
RecognizerPointer
::
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
){
if
(
mRecognizer
){
return
mRecognizer
->
feed
(
ctx
,
input
,
pos
);
}
else
{
...
...
src/belr.hh
View file @
97a8c821
...
...
@@ -12,16 +12,16 @@ namespace belr{
string
tolower
(
const
string
&
str
);
class
ParserContext
;
class
ParserContext
Base
;
class
Recognizer
:
public
enable_shared_from_this
<
Recognizer
>
{
public:
void
setName
(
const
string
&
name
);
const
string
&
getName
()
const
;
size_t
feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
size_t
feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
protected:
Recognizer
();
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
)
=
0
;
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
)
=
0
;
string
mName
;
};
...
...
@@ -29,7 +29,7 @@ class CharRecognizer : public Recognizer{
public:
CharRecognizer
(
int
to_recognize
,
bool
caseSensitive
=
false
);
private:
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
int
mToRecognize
;
bool
mCaseSensitive
;
};
...
...
@@ -39,7 +39,7 @@ class CharRange : public Recognizer{
public:
CharRange
(
int
begin
,
int
end
);
private:
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
int
mBegin
,
mEnd
;
};
...
...
@@ -48,7 +48,7 @@ public:
Selector
();
shared_ptr
<
Selector
>
addRecognizer
(
const
shared_ptr
<
Recognizer
>
&
element
);
protected:
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
list
<
shared_ptr
<
Recognizer
>>
mElements
;
};
...
...
@@ -57,7 +57,7 @@ class ExclusiveSelector : public Selector{
public:
ExclusiveSelector
();
private:
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
};
class
Sequence
:
public
Recognizer
{
...
...
@@ -65,7 +65,7 @@ public:
Sequence
();
shared_ptr
<
Sequence
>
addRecognizer
(
const
shared_ptr
<
Recognizer
>
&
element
);
private:
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
list
<
shared_ptr
<
Recognizer
>>
mElements
;
};
...
...
@@ -74,7 +74,7 @@ public:
Loop
();
shared_ptr
<
Loop
>
setRecognizer
(
const
shared_ptr
<
Recognizer
>
&
element
,
int
min
=
0
,
int
max
=-
1
);
private:
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
shared_ptr
<
Recognizer
>
mRecognizer
;
int
mMin
,
mMax
;
};
...
...
@@ -100,7 +100,7 @@ public:
shared_ptr
<
Recognizer
>
getPointed
();
void
setPointed
(
const
shared_ptr
<
Recognizer
>
&
r
);
private:
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
virtual
size_t
_feed
(
const
shared_ptr
<
ParserContext
Base
>
&
ctx
,
const
string
&
input
,
size_t
pos
);
shared_ptr
<
Recognizer
>
mRecognizer
;
};
...
...
src/grammarbuilder.cc
View file @
97a8c821
#include "abnf.hh"
#include "grammarbuilder.hh"
#include "parser-impl.cc"
#include <iostream>
...
...
src/grammarbuilder.hh
View file @
97a8c821
...
...
@@ -15,7 +15,7 @@ private:
void
addRule
(
void
*
list
,
void
*
rule
);
void
*
createRuleList
();
void
*
createRule
();
Parser
mParser
;
Parser
<
void
*>
mParser
;
};
}
...
...
src/parser-impl.cc
0 → 100644
View file @
97a8c821
#include "parser.hh"
#include <iostream>
#include <algorithm>
namespace
belr
{
template
<
typename
_parserElementT
>
void
Assignment
<
_parserElementT
>::
invoke
(
_parserElementT
parent
,
const
string
&
input
){
if
(
mChild
){
shared_ptr
<
ParserCollector
<
_parserElementT
,
_parserElementT
>>
cc
=
dynamic_pointer_cast
<
ParserCollector
<
_parserElementT
,
_parserElementT
>>
(
mCollector
);
if
(
cc
){
cc
->
invoke
(
parent
,
mChild
->
realize
(
input
));
}
}
else
{
string
value
=
input
.
substr
(
mBegin
,
mCount
);
shared_ptr
<
ParserCollector
<
_parserElementT
,
const
string
&>>
cc1
=
dynamic_pointer_cast
<
ParserCollector
<
_parserElementT
,
const
string
&>>
(
mCollector
);
if
(
cc1
){
cc1
->
invoke
(
parent
,
value
);
return
;
}
shared_ptr
<
ParserCollector
<
_parserElementT
,
const
char
*>>
cc2
=
dynamic_pointer_cast
<
ParserCollector
<
_parserElementT
,
const
char
*>>
(
mCollector
);
if
(
cc2
){
cc2
->
invoke
(
parent
,
value
.
c_str
());
return
;
}
shared_ptr
<
ParserCollector
<
_parserElementT
,
int
>>
cc3
=
dynamic_pointer_cast
<
ParserCollector
<
_parserElementT
,
int
>>
(
mCollector
);
if
(
cc3
){
cc3
->
invoke
(
parent
,
atoi
(
value
.
c_str
()));
return
;
}
}
}
template
<
typename
_parserElementT
>
ParserContext
<
_parserElementT
>::
ParserContext
(
Parser
<
_parserElementT
>
&
parser
)
:
mParser
(
parser
){
}
template
<
typename
_parserElementT
>
shared_ptr
<
HandlerContext
<
_parserElementT
>>
ParserContext
<
_parserElementT
>::
_beginParse
(
const
shared_ptr
<
Recognizer
>
&
rec
){
shared_ptr
<
HandlerContext
<
_parserElementT
>>
ctx
;
auto
it
=
mParser
.
mHandlers
.
find
(
rec
->
getName
());
if
(
it
!=
mParser
.
mHandlers
.
end
()){
ctx
=
(
*
it
).
second
->
createContext
();
mHandlerStack
.
push_back
(
ctx
);
}
return
ctx
;
}
template
<
typename
_parserElementT
>
void
ParserContext
<
_parserElementT
>::
_endParse
(
const
shared_ptr
<
Recognizer
>
&
rec
,
const
shared_ptr
<
HandlerContext
<
_parserElementT
>>
&
ctx
,
const
string
&
input
,
size_t
begin
,
size_t
count
){
if
(
ctx
){
mHandlerStack
.
pop_back
();
}
if
(
!
mHandlerStack
.
empty
()){
/*assign object to parent */
mHandlerStack
.
back
()
->
setChild
(
rec
->
getName
(),
begin
,
count
,
ctx
);
}
else
{
/*no parent, this is our root object*/
mRoot
=
ctx
;
}
}
template
<
typename
_parserElementT
>
_parserElementT
ParserContext
<
_parserElementT
>::
createRootObject
(
const
string
&
input
){
return
mRoot
?
mRoot
->
realize
(
input
)
:
NULL
;
}
template
<
typename
_parserElementT
>
shared_ptr
<
HandlerContext
<
_parserElementT
>>
ParserContext
<
_parserElementT
>::
_branch
(){
shared_ptr
<
HandlerContext
<
_parserElementT
>>
ret
=
mHandlerStack
.
back
()
->
branch
();
mHandlerStack
.
push_back
(
ret
);
return
ret
;
}
template
<
typename
_parserElementT
>
void
ParserContext
<
_parserElementT
>::
_merge
(
const
shared_ptr
<
HandlerContext
<
_parserElementT
>>
&
other
){
if
(
mHandlerStack
.
back
()
!=
other
){
cerr
<<
"The branch being merged is not the last one of the stack !"
<<
endl
;
abort
();
}
mHandlerStack
.
pop_back
();
return
mHandlerStack
.
back
()
->
merge
(
other
);
}
template
<
typename
_parserElementT
>
void
ParserContext
<
_parserElementT
>::
_removeBranch
(
const
shared_ptr
<
HandlerContext
<
_parserElementT
>>
&
other
){
auto
it
=
find
(
mHandlerStack
.
rbegin
(),
mHandlerStack
.
rend
(),
other
);
if
(
it
==
mHandlerStack
.
rend
()){
cerr
<<
"A branch could not be found in the stack while removing it !"
<<
endl
;
abort
();
}
else
{
advance
(
it
,
1
);
mHandlerStack
.
erase
(
it
.
base
());
}
}
template
<
typename
_parserElementT
>
shared_ptr
<
HandlerContextBase
>
ParserContext
<
_parserElementT
>::
beginParse
(
const
shared_ptr
<
Recognizer
>
&
rec
){
return
static_pointer_cast
<
HandlerContext
<
_parserElementT
>>
(
_beginParse
(
rec
));
}
template
<
typename
_parserElementT
>
void
ParserContext
<
_parserElementT
>::
endParse
(
const
shared_ptr
<
Recognizer
>
&
rec
,
const
shared_ptr
<
HandlerContextBase
>
&
ctx
,
const
string
&
input
,
size_t
begin
,
size_t
count
){
_endParse
(
rec
,
static_pointer_cast
<
HandlerContext
<
_parserElementT
>>
(
ctx
),
input
,
begin
,
count
);
}
template
<
typename
_parserElementT
>
shared_ptr
<
HandlerContextBase
>
ParserContext
<
_parserElementT
>::
branch
(){
return
static_pointer_cast
<
HandlerContext
<
_parserElementT
>>
(
_branch
());
}
template
<
typename
_parserElementT
>
void
ParserContext
<
_parserElementT
>::
merge
(
const
shared_ptr
<
HandlerContextBase
>
&
other
){
_merge
(
static_pointer_cast
<
HandlerContext
<
_parserElementT
>>
(
other
));
}
template
<
typename
_parserElementT
>
void
ParserContext
<
_parserElementT
>::
removeBranch
(
const
shared_ptr
<
HandlerContextBase
>
&
other
){
_removeBranch
(
static_pointer_cast
<
HandlerContext
<
_parserElementT
>>
(
other
));
}
template
<
typename
_parserElementT
>
shared_ptr
<
HandlerContext
<
_parserElementT
>>
ParserHandler
<
_parserElementT
>::
createContext
(){
return
make_shared
<
HandlerContext
<
_parserElementT
>>
(
this
->
shared_from_this
());
}
template
<
typename
_parserElementT
>
Parser
<
_parserElementT
>::
Parser
(
const
shared_ptr
<
Grammar
>
&
grammar
)
:
mGrammar
(
grammar
){
if
(
!
mGrammar
->
isComplete
()){
cerr
<<
"Grammar not complete, aborting."
<<
endl
;
return
;
}
}
template
<
typename
_parserElementT
>
_parserElementT
Parser
<
_parserElementT
>::
parseInput
(
const
string
&
rulename
,
const
string
&
input
,
size_t
*
parsed_size
){
size_t
parsed
;
shared_ptr
<
Recognizer
>
rec
=
mGrammar
->
getRule
(
rulename
);
auto
pctx
=
make_shared
<
ParserContext
<
_parserElementT
>>
(
*
this
);
parsed
=
rec
->
feed
(
pctx
,
input
,
0
);
if
(
parsed_size
)
*
parsed_size
=
parsed
;
return
pctx
->
createRootObject
(
input
);
}
}
src/parser.cc
View file @
97a8c821
#include <parser.hh>
#include <iostream>
#include <algorithm>
namespace
belr
{
CollectorBase
::~
CollectorBase
(){
}
void
Assignment
::
invoke
(
void
*
parent
,
const
string
&
input
){
if
(
mChild
){
shared_ptr
<
ParserCollector
<
void
*>>
cc
=
dynamic_pointer_cast
<
ParserCollector
<
void
*>>
(
mCollector
);
if
(
cc
){
cc
->
invoke
(
parent
,
mChild
->
realize
(
input
));
}
}
else
{
string
value
=
input
.
substr
(
mBegin
,
mCount
);
shared_ptr
<
ParserCollector
<
const
string
&>>
cc1
=
dynamic_pointer_cast
<
ParserCollector
<
const
string
&>>
(
mCollector
);
if
(
cc1
){
cc1
->
invoke
(
parent
,
value
);
return
;
}
shared_ptr
<
ParserCollector
<
const
char
*>>
cc2
=
dynamic_pointer_cast
<
ParserCollector
<
const
char
*>>
(
mCollector
);
if
(
cc2
){
cc2
->
invoke
(
parent
,
value
.
c_str
());
return
;
}
shared_ptr
<
ParserCollector
<
int
>>
cc3
=
dynamic_pointer_cast
<
ParserCollector
<
int
>>
(
mCollector
);
if
(
cc3
){
cc3
->
invoke
(
parent
,
atoi
(
value
.
c_str
()));
return
;
}
}
}
ParserContext
::
ParserContext
(
Parser
&
parser
)
:
mParser
(
parser
){
}
shared_ptr
<
HandlerContext
>
ParserContext
::
beginParse
(
const
shared_ptr
<
Recognizer
>
&
rec
){
shared_ptr
<
HandlerContext
>
ctx
;
auto
it
=
mParser
.
mHandlers
.
find
(
rec
->
getName
());
if
(
it
!=
mParser
.
mHandlers
.
end
()){
ctx
=
(
*
it
).
second
->
createContext
();
mHandlerStack
.
push_back
(
ctx
);
}
return
ctx
;
}
void
ParserContext
::
endParse
(
const
shared_ptr
<
Recognizer
>
&
rec
,
const
shared_ptr
<
HandlerContext
>
&
ctx
,
const
string
&
input
,
size_t
begin
,
size_t
count
){
if
(
ctx
){
mHandlerStack
.
pop_back
();
}
if
(
!
mHandlerStack
.
empty
()){
/*assign object to parent */
mHandlerStack
.
back
()
->
setChild
(
rec
->
getName
(),
begin
,
count
,
ctx
);
}
else
{
/*no parent, this is our root object*/
mRoot
=
ctx
;
}
}
void
*
ParserContext
::
createRootObject
(
const
string
&
input
){
return
mRoot
?
mRoot
->
realize
(
input
)
:
NULL
;
}
shared_ptr
<
HandlerContext
>
ParserContext
::
branch
(){
shared_ptr
<
HandlerContext
>
ret
=
mHandlerStack
.
back
()
->
branch
();
mHandlerStack
.
push_back
(
ret
);
return
ret
;
}
void
ParserContext
::
merge
(
const
shared_ptr
<
HandlerContext
>
&
other
){
if
(
mHandlerStack
.
back
()
!=
other
){
cerr
<<
"The branch being merged is not the last one of the stack !"
<<
endl
;
abort
();
}
mHandlerStack
.
pop_back
();
return
mHandlerStack
.
back
()
->
merge
(
other
);
}
void
ParserContext
::
removeBranch
(
const
shared_ptr
<
HandlerContext
>
&
other
){
auto
it
=
find
(
mHandlerStack
.
rbegin
(),
mHandlerStack
.
rend
(),
other
);
if
(
it
==
mHandlerStack
.
rend
()){
cerr
<<
"A branch could not be found in the stack while removing it !"
<<
endl
;
abort
();
}
else
{
advance
(
it
,
1
);
mHandlerStack
.
erase
(
it
.
base
());
}
}
shared_ptr
<
HandlerContext
>
ParserHandler
::
createContext
(){
return
make_shared
<
HandlerContext
>
(
shared_from_this
());
}
Parser
::
Parser
(
const
shared_ptr
<
Grammar
>
&
grammar
)
:
mGrammar
(
grammar
){
if
(
!
mGrammar
->
isComplete
()){
cerr
<<
"Grammar not complete, aborting."
<<
endl
;
return
;
}
}
void
*
Parser
::
parseInput
(
const
string
&
rulename
,
const
string
&
input
,
size_t
*
parsed_size
){
size_t
parsed
;
shared_ptr
<
Recognizer
>
rec
=
mGrammar
->
getRule
(
rulename
);
shared_ptr
<
ParserContext
>
pctx
=
make_shared
<
ParserContext
>
(
*
this
);
parsed
=
rec
->
feed
(
pctx
,
input
,
0
);
if
(
parsed_size
)
*
parsed_size
=
parsed
;
return
pctx
->
createRootObject
(
input
);
}
}
//end of namespace
\ No newline at end of file
src/parser.hh
View file @
97a8c821
...
...
@@ -12,113 +12,138 @@ public:
virtual
~
CollectorBase
();
};
template
<
typename
_valueT
>
template
<
typename
_parserElementT
,
typename
_valueT
>
class
ParserCollector
:
public
CollectorBase
{
public:
ParserCollector
(
const
function
<
void
(
void
*
,
_valueT
)
>
&
fn
)
:
mFunc
(
fn
){
ParserCollector
(
const
function
<
void
(
_parserElementT
,
_valueT
)
>
&
fn
)
:
mFunc
(
fn
){
}
function
<
void
(
void
*
,
_valueT
)
>
mFunc
;
void
invoke
(
void
*
obj
,
_valueT
value
){
function
<
void
(
_parserElementT
,
_valueT
)
>
mFunc
;
void
invoke
(
_parserElementT
obj
,
_valueT
value
){
mFunc
(
obj
,
value
);
}
};
template
<
typename
_parserElementT
>
class
HandlerContext
;
class
ParserHandler
:
public
enable_shared_from_this
<
ParserHandler
>
{
template
<
typename
_parserElementT
>
class
ParserHandler
:
public
enable_shared_from_this
<
ParserHandler
<
_parserElementT
>>
{
public:
friend
class
HandlerContext
;
ParserHandler
(
const
function
<
void
*
()
>
&
create
)
friend
class
HandlerContext
<
_parserElementT
>
;
ParserHandler
(
const
function
<
_parserElementT
()
>
&
create
)
:
mHandlerCreateFunc
(
create
){
}
template
<
typename
_valueT
>
shared_ptr
<
ParserHandler
>
setCollector
(
const
string
&
child_rule_name
,
function
<
void
(
void
*
,
_valueT
)
>
fn
){
mCollectors
[
child_rule_name
]
=
make_shared
<
ParserCollector
<
_valueT
>>
(
fn
);
return
shared_from_this
();
shared_ptr
<
ParserHandler
<
_parserElementT
>
>
setCollector
(
const
string
&
child_rule_name
,
function
<
void
(
_parserElementT
,
_valueT
)
>
fn
){
mCollectors
[
child_rule_name
]
=
make_shared
<
ParserCollector
<
_
parserElementT
,
_
valueT
>>
(
fn
);
return
this
->
shared_from_this
();
}
void
*
invoke
(){
_parserElementT
invoke
(){
return
mHandlerCreateFunc
();
}
shared_ptr
<
HandlerContext
>
createContext
();
shared_ptr
<
HandlerContext
<
_parserElementT
>
>
createContext
();
private:
function
<
void
*
()
>
mHandlerCreateFunc
;
function
<
_parserElementT
()
>
mHandlerCreateFunc
;
map
<
string
,
shared_ptr
<
CollectorBase
>
>
mCollectors
;
};
template
<
typename
_parserElementT
>
class
Assignment
{
private:
shared_ptr
<
CollectorBase
>
mCollector
;
size_t
mBegin
;
size_t
mCount
;
shared_ptr
<
HandlerContext
>
mChild
;
shared_ptr
<
HandlerContext
<
_parserElementT
>
>
mChild
;
public:
Assignment
(
const
shared_ptr
<
CollectorBase
>
&
c
,
size_t
begin
,
size_t
count
,
const
shared_ptr
<
HandlerContext
>
&
child
)
Assignment
(
const
shared_ptr
<
CollectorBase
>
&
c
,
size_t
begin
,
size_t
count
,
const
shared_ptr
<
HandlerContext
<
_parserElementT
>
>
&
child
)
:
mCollector
(
c
),
mBegin
(
begin
),
mCount
(
count
),
mChild
(
child
)
{
}
void
invoke
(
void
*
parent
,
const
string
&
input
);
void
invoke
(
_parserElementT
parent
,
const
string
&
input
);
};
class
HandlerContext
{
class
HandlerContextBase
{
};
template
<
typename
_parserElementT
>
class
HandlerContext
:
public
HandlerContextBase
{
public:
HandlerContext
(
const
shared_ptr
<
ParserHandler
>
&
handler
)
:
HandlerContext
(
const
shared_ptr
<
ParserHandler
<
_parserElementT
>
>
&
handler
)
:
mHandler
(
handler
){
}
void
setChild
(
const
string
&
subrule_name
,
size_t
begin
,
size_t
count
,
const
shared_ptr
<
HandlerContext
>
&
child
){
auto
it
=
mHandler
->
mCollectors
.
find
(
subrule_name
);
if
(
it
!=
mHandler
->
mCollectors
.
end
()){
mAssignments
.
push_back
(
Assignment
((
*
it
).
second
,
begin
,
count
,
child
));
mAssignments
.
push_back
(
Assignment
<
_parserElementT
>
((
*
it
).
second
,
begin
,
count
,
child
));
}
}
void
*
realize
(
const
string
&
input
){
_parserElementT
realize
(
const
string
&
input
){
void
*
ret
=
mHandler
->
invoke
();
for
(
auto
it
=
mAssignments
.
begin
();
it
!=
mAssignments
.
end
();
++
it
){
(
*
it
).
invoke
(
ret
,
input
);
}
return
ret
;
}
shared_ptr
<
HandlerContext
>
branch
(){
shared_ptr
<
HandlerContext
<
_parserElementT
>
>
branch
(){
return
make_shared
<
HandlerContext
>
(
mHandler
);
}
void
merge
(
const
shared_ptr
<
HandlerContext
>
&
other
){
void
merge
(
const
shared_ptr
<
HandlerContext
<
_parserElementT
>
>
&
other
){
mAssignments
.
splice
(
mAssignments
.
begin
(),
other
->
mAssignments
);
}
private:
shared_ptr
<
ParserHandler
>
mHandler
;
list
<
Assignment
>
mAssignments
;
shared_ptr
<
ParserHandler
<
_parserElementT
>
>
mHandler
;
list
<
Assignment
<
_parserElementT
>
>
mAssignments
;
};
template
<
typename
_parserElementT
>
class
Parser
;
class
ParserContext
{
class
ParserContextBase
{
public:
virtual
shared_ptr
<
HandlerContextBase
>
beginParse
(
const
shared_ptr
<
Recognizer
>
&
rec
)
=
0
;
virtual
void
endParse
(
const
shared_ptr
<
Recognizer
>
&
rec
,
const
shared_ptr
<
HandlerContextBase
>
&
ctx
,
const
string
&
input
,
size_t
begin
,
size_t
count
)
=
0
;
virtual
shared_ptr
<
HandlerContextBase
>
branch
()
=
0
;
virtual
void
merge
(
const
shared_ptr
<
HandlerContextBase
>
&
other
)
=
0
;
virtual
void
removeBranch
(
const
shared_ptr
<
HandlerContextBase
>
&
other
)
=
0
;
};
template
<
typename
_parserElementT
>
class
ParserContext
:
public
ParserContextBase
{
public:
ParserContext
(
Parser
&
parser
);
shared_ptr
<
HandlerContext
>
beginParse
(
const
shared_ptr
<
Recognizer
>
&
rec
);
void
endParse
(
const
shared_ptr
<
Recognizer
>
&
rec
,
const
shared_ptr
<
HandlerContext
>
&
ctx
,
const
string
&
input
,
size_t
begin
,
size_t
count
);
shared_ptr
<
HandlerContext
>
branch
();
void
merge
(
const
shared_ptr
<
HandlerContext
>
&
other
);
void
removeBranch
(
const
shared_ptr
<
HandlerContext
>
&
other
);
void
*
createRootObject
(
const
string
&
input
);
ParserContext
(
Parser
<
_parserElementT
>
&
parser
);
_parserElementT
createRootObject
(
const
string
&
input
);
protected:
virtual
shared_ptr
<
HandlerContextBase
>
beginParse
(
const
shared_ptr
<
Recognizer
>
&
rec
);
virtual
void
endParse
(
const
shared_ptr
<
Recognizer
>
&
rec
,
const
shared_ptr
<
HandlerContextBase
>
&
ctx
,
const
string
&
input
,
size_t
begin
,
size_t
count
);
virtual
shared_ptr
<
HandlerContextBase
>
branch
();
virtual
void
merge
(
const
shared_ptr
<
HandlerContextBase
>
&
other
);
virtual
void
removeBranch
(
const
shared_ptr
<
HandlerContextBase
>
&
other
);
shared_ptr
<
HandlerContext
<
_parserElementT
>>
_beginParse
(
const
shared_ptr
<
Recognizer
>
&
rec
);
void
_endParse
(
const
shared_ptr
<
Recognizer
>
&
rec
,
const
shared_ptr
<
HandlerContext
<
_parserElementT
>>
&
ctx
,
const
string
&
input
,
size_t
begin
,
size_t
count
);
shared_ptr
<
HandlerContext
<
_parserElementT
>>
_branch
();
void
_merge
(
const
shared_ptr
<
HandlerContext
<
_parserElementT
>>
&
other
);
void
_removeBranch
(
const
shared_ptr
<
HandlerContext
<
_parserElementT
>>
&
other
);
private:
Parser
&
mParser
;
list
<
shared_ptr
<
HandlerContext
>>
mHandlerStack
;
shared_ptr
<
HandlerContext
>
mRoot
;
Parser
<
_parserElementT
>
&
mParser
;