#include "Regex.h"
#include "RegexExpression.h"
#include "RegexPure.h"
#include "RegexRich.h"
namespace
{
namespace
{
using
namespace
collections
;
using
namespace
regex_internal
;
::
(
)
:start(
)
,length(
0
)
{
}
::
(
const
&
,
,
)
:value(
==
0
?
L""
:
.
(
,
))
,start(
)
,length(
)
{
}
::
()
const
{
return
;
}
::
()
const
{
return
;
}
const
&
::
()
const
{
return
;
}
bool
::
(
const
&
)
const
{
return
==
.
&&
==
.
&&
==
.
;
}
::
(
const
&
,
*
)
:success(
true
)
,result(
,
->
,
->
)
{
}
::
(
const
&
,
*
,
*
)
:success(
true
)
,result(
,
->
,
->
)
{
for
(
=
0
;
i
<
->
.
();
i
++)
{
&
=
->
i
];
if
(
capture
.
==-
1
)
{
.
(
(
,
capture
.
,
capture
.
));
}
else
{
.
(
->
().
(
capture
.
),
(
,
capture
.
,
capture
.
));
}
}
}
::
(
const
&
)
:success(
false
)
,result(
)
{
}
bool
::
()
const
{
return
;
}
const
&
::
()
const
{
return
;
}
const
::
&
::
()
const
{
return
;
}
const
::
&
::
()
const
{
return
;
}
void
::
(
const
&
,
bool
,
bool
,
bool
,
::
&
)
const
{
if
(
)
{
const
wchar_t
*
=
.
();
const
wchar_t
*
=
start
;
;
while
(
->
(
input
,
start
,
result
))
{
=
input
-
start
;
if
(
)
{
if
(
result
.
>
offset
||
)
{
.
(
new
(
(
,
offset
,
result
.
-
offset
)));
}
}
if
(
)
{
.
(
new
(
, &
result
,
));
}
input
=
start
+
result
.
+
result
.
;
}
if
(
)
{
=
input
-
start
;
=
.
()-
remain
;
if
(
length
||
)
{
.
(
new
(
(
,
remain
,
length
)));
}
}
}
else
{
const
wchar_t
*
=
.
();
const
wchar_t
*
=
start
;
;
while
(
->
(
input
,
start
,
result
))
{
=
input
-
start
;
if
(
)
{
if
(
result
.
>
offset
||
)
{
.
(
new
(
(
,
offset
,
result
.
-
offset
)));
}
}
if
(
)
{
.
(
new
(
, &
result
));
}
input
=
start
+
result
.
+
result
.
;
}
if
(
)
{
=
input
-
start
;
=
.
()-
remain
;
if
(
length
||
)
{
.
(
new
(
(
,
remain
,
length
)));
}
}
}
}
::
(
const
&
,
bool
)
{
::
;
::
=
(
);
::
=
regex
();
expression
(
subsets
);
bool
=
false
;
bool
=
false
;
if
(
)
{
if
(
expression
())
{
pureRequired
=
true
;
}
else
{
if
(
expression
())
{
pureRequired
=
true
;
richRequired
=
true
;
}
else
{
richRequired
=
true
;
}
}
}
else
{
richRequired
=
true
;
}
try
{
if
(
pureRequired
)
{
<
*,
*>
;
<
*,
*>
;
::
=
expression
();
::
=
(
eNfa
,
,
nfaStateMap
);
::
=
(
nfa
,
dfaStateMap
);
=
new
(
dfa
,
subsets
);
}
if
(
richRequired
)
{
<
*,
*>
;
<
*,
*>
;
::
=
expression
();
::
=
(
eNfa
,
,
nfaStateMap
);
::
=
(
nfa
,
dfaStateMap
);
=
new
(
dfa
);
}
}
catch
(...)
{
if
(
)
delete
;
if
(
)
delete
;
throw
;
}
}
::
()
{
if
(
)
delete
;
if
(
)
delete
;
}
bool
::
()
const
{
return
?
false
:
true
;
}
bool
::
()
const
{
return
?
true
:
false
;
}
::
::
(
const
&
)
const
{
if
(
)
{
;
if
(
->
(
.
(),
.
(),
result
))
{
return
new
(
, &
result
,
);
}
else
{
return
0
;
}
}
else
{
;
if
(
->
(
.
(),
.
(),
result
))
{
return
new
(
, &
result
);
}
else
{
return
0
;
}
}
}
::
::
(
const
&
)
const
{
if
(
)
{
;
if
(
->
(
.
(),
.
(),
result
))
{
return
new
(
, &
result
,
);
}
else
{
return
0
;
}
}
else
{
;
if
(
->
(
.
(),
.
(),
result
))
{
return
new
(
, &
result
);
}
else
{
return
0
;
}
}
}
bool
::
(
const
&
)
const
{
if
(
)
{
;
return
->
(
.
(),
.
(),
result
);
}
else
{
;
return
->
(
.
(),
.
(),
result
);
}
}
bool
::
(
const
&
)
const
{
if
(
)
{
;
return
->
(
.
(),
.
(),
result
);
}
else
{
;
return
->
(
.
(),
.
(),
result
);
}
}
void
::
(
const
&
,
::
&
)
const
{
(
,
false
,
true
,
false
,
);
}
void
::
(
const
&
,
bool
,
::
&
)
const
{
(
,
,
false
,
true
,
);
}
void
::
(
const
&
,
bool
,
::
&
)
const
{
(
,
,
true
,
true
,
);
}
bool
::
(
const
&
)
const
{
return
==
.
&&
==
.
&&
==
.
;
}
bool
::
(
const
wchar_t
*
)
const
{
return
(
)==
&&
(
,
,
)==
0
;
}
class
:
public
,
public
<
>
{
protected
:
;
= -
1
;
*
;
const
<
>&
;
const
wchar_t
*
;
;
;
const
wchar_t
*
;
=
0
;
=
0
;
bool
=
false
;
;
public
:
(
const
&
)
:token(
.
)
, index(
.
)
, pure(
.
)
, stateTokens(
.
)
, proc(
.
)
, reading(
.
)
, start(
.
)
, rowStart(
.
)
, columnStart(
.
)
, codeIndex(
.
)
, cacheAvailable(
.
)
, cacheToken(
.
)
{
}
(
*
,
const
<
>&
,
const
wchar_t
*
,
,
)
:index(-
1
)
, pure(
)
, stateTokens(
)
, start(
)
, codeIndex(
)
, proc(
)
, reading(
)
{
}
<
>*
()
const
{
return
new
(*
this
);
}
const
&
()
const
{
return
;
}
()
const
{
return
;
}
bool
()
{
if
(!
&& !*
)
return
false
;
if
(
)
{
;
=
false
;
}
else
{
.
=
;
.
=
0
;
.
=
0
;
.
= -
2
;
.
=
true
;
}
.
=
;
.
=
;
.
=
;
.
=
;
.
=
;
;
while
(*
)
{
= -
1
;
bool
=
true
;
if
(!
->
(
,
,
result
))
{
result
.
=
-
;
if
(
id
== -
1
&&
result
.
!= -
1
)
{
=
->
(
result
.
);
if
(
state
!= -
1
)
{
id
=
state
];
}
}
if
(
id
== -
1
)
{
result
.
=
1
;
}
else
{
completeToken
=
false
;
}
}
else
{
id
=
.
(
result
.
);
}
if
(
id
!= -
1
&&
.
)
{
(
result
.
,
result
.
,
id
,
completeToken
,
nullptr
);
.
(
.
,
, -
1
,
true
,
token
);
#if _DEBUG
CHECK_ERROR(token.interTokenState == nullptr, L"RegexTokenEnumerator::Next()#The extendProc is only allowed to create interTokenState in RegexLexerColorizer.");
#endif
do
{
if
(!(
token
.
==
nullptr
))
throw
(
L"RegexTokenEnumerator::Next()#The extendProc is only allowed to create interTokenState in RegexLexerColorizer."
);}
while
(
0
);
result
.
=
token
.
;
id
=
token
.
;
completeToken
=
token
.
;
}
if
(
.
== -
2
)
{
.
=
result
.
;
.
=
result
.
;
.
=
id
;
.
=
completeToken
;
}
else
if
(
.
==
id
&&
id
== -
1
)
{
.
+=
result
.
;
}
else
{
=
true
;
.
=
;
.
=
result
.
;
.
=
result
.
;
.
=
;
.
=
id
;
.
=
completeToken
;
}
+=
result
.
;
if
(
)
{
break
;
}
}
++;
for
(
=
0
;
i
<
.
;
i
++)
{
.
=
;
.
=
;
if
(
.
[
i
] ==
L'\n'
)
{
++;
=
0
;
}
else
{
++;
}
}
return
true
;
}
void
()
{
= -
1
;
=
;
=
false
;
}
void
(
<
>&
,
bool
(*
)(
))
{
while
(
())
{
if
(!
(
.
))
{
.
(
);
}
}
}
};
::
(
*
,
const
<
>&
,
const
&
,
,
)
:pure(
)
, stateTokens(
)
, code(
)
, codeIndex(
)
, proc(
)
{
}
::
(
const
&
)
:pure(
.
)
, stateTokens(
.
)
, code(
.
)
, codeIndex(
.
)
, proc(
.
)
{
}
<
>*
::
()
const
{
return
new
(
,
,
.
(),
,
);
}
bool
(
)
{
return
false
;
}
void
::
(
collections
::
<
>&
,
bool
(*
)(
))
const
{
if
(
==
0
)
{
=&
;
}
(
,
,
.
(),
,
).
(
,
);
}
::
(
*
,
const
<
>&
)
:pure(
)
, stateTokens(
)
{
}
::
(
const
&
)
: pure(
.
)
, stateTokens(
.
)
{
}
::
()
{
}
::
()
{
}
::
()
const
{
return
->
();
}
::
(
)
const
{
=
== -
1
? -
1
:
->
(
);
return
finalState
== -
1
? -
1
:
.
(
finalState
);
}
void
::
(
wchar_t
,
&
,
&
,
bool
&
,
bool
&
)
const
{
=
;
=-
1
;
=
false
;
=
false
;
if
(
==-
1
)
{
=
->
();
=
true
;
}
=
->
(
,
);
if
(
==-
1
)
{
=
true
;
if
(
previousState
==-
1
)
{
=
true
;
return
;
}
else
if
(
->
(
previousState
))
{
=
->
(
,
->
());
}
}
if
(
->
(
))
{
=
.
(
);
=
true
;
return
;
}
else
{
=
==-
1
;
return
;
}
}
::
(
wchar_t
,
)
const
{
=-
1
;
bool
=
false
;
bool
=
false
;
(
,
,
token
,
finalState
,
previousTokenStop
);
return
;
}
bool
::
(
const
wchar_t
*
,
)
const
{
=
->
();
for
(
=
0
;
i
<
;
i
++)
{
state
=
->
(
[
i
],
state
);
if
(
state
==-
1
)
return
true
;
if
(
->
(
state
))
return
true
;
}
return
false
;
}
bool
::
(
const
&
)
const
{
return
(
.
(),
.
());
}
::
(
const
&
,
)
:walker(
)
, proc(
)
{
.
=
.
();
}
::
(
const
&
)
:walker(
.
)
, proc(
.
)
, internalState(
.
)
{
}
::
()
{
}
::
::
()
{
return
;
}
void
::
(
)
{
;
}
void
::
(
wchar_t
)
{
(&
,
1
,
0
,
false
);
}
::
()
const
{
return
.
();
}
void
::
CallExtendProcAndColorizeProc
(
const
wchar_t
*
,
,
&
,
bool
)
{
=
.
;
.
(
.
,
+
.
,
-
.
,
false
,
);
#if _DEBUG
{
bool
=
.
+
.
==
&& !
.
;
CHECK_ERROR(
token.completeToken || pausedAtTheEnd,
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed pause before the end of the input."
);
do
{
if
(!(
.
||
pausedAtTheEnd
))
throw
(
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed pause before the end of the input."
);}
while
(
0
);
CHECK_ERROR(
token.completeToken || token.token != -1,
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed to pause without a valid token id."
);
do
{
if
(!(
.
||
.
!= -
1
))
throw
(
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed to pause without a valid token id."
);}
while
(
0
);
CHECK_ERROR(
oldTokenLength <= token.length,
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed to decrease the token length."
);
do
{
if
(!(
oldTokenLength
<=
.
))
throw
(
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed to decrease the token length."
);}
while
(
0
);
CHECK_ERROR(
(token.interTokenState == nullptr) == !pausedAtTheEnd,
L"RegexLexerColorizer::Colorize(const wchar_t*, vint, void*)#The extendProc should return an inter token state object if and only if a valid token does not end at the end of the input."
);
do
{
if
(!((
.
==
nullptr
) == !
pausedAtTheEnd
))
throw
(
L"RegexLexerColorizer::Colorize(const wchar_t*, vint, void*)#The extendProc should return an inter token state object if and only if a valid token does not end at the end of the input."
);}
while
(
0
);
}
#endif
if
((
.
=
.
))
{
.
=
.
;
}
if
(
)
{
.
(
.
,
.
,
.
,
.
);
}
}
::
(
const
wchar_t
*
,
,
,
bool
)
{
if
(
.
)
{
(-
1
, -
1
,
.
,
false
,
.
);
.
(
.
,
,
,
false
,
token
);
#if _DEBUG
{
bool
=
token
.
==
&& !
token
.
;
CHECK_ERROR(
token.completeToken || pausedAtTheEnd,
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed to pause before the end of the input."
);
do
{
if
(!(
token
.
||
pausedAtTheEnd
))
throw
(
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed to pause before the end of the input."
);}
while
(
0
);
CHECK_ERROR(
token.completeToken || token.token == internalState.interTokenId,
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed to continue pausing with a different token id."
);
do
{
if
(!(
token
.
||
token
.
==
.
))
throw
(
L"RegexLexerColorizer::WalkOneToken(const wchar_t*, vint, vint, bool)#The extendProc is not allowed to continue pausing with a different token id."
);}
while
(
0
);
CHECK_ERROR(
(token.interTokenState == nullptr) == !pausedAtTheEnd,
L"RegexLexerColorizer::Colorize(const wchar_t*, vint, void*)#The extendProc should return an inter token state object if and only if a valid token does not end at the end of the input."
);
do
{
if
(!((
token
.
==
nullptr
) == !
pausedAtTheEnd
))
throw
(
L"RegexLexerColorizer::Colorize(const wchar_t*, vint, void*)#The extendProc should return an inter token state object if and only if a valid token does not end at the end of the input."
);}
while
(
0
);
}
#endif
if
(
)
{
.
(
.
,
0
,
token
.
,
token
.
);
}
if
(!(
.
=
token
.
))
{
.
= -
1
;
}
return
token
.
;
}
=
0
;
= -
1
;
= -
1
;
=
.
;
for
(
=
;
i
<
;
i
++)
{
= -
1
;
bool
=
false
;
bool
=
false
;
.
(
[
i
],
.
,
currentToken
,
finalState
,
previousTokenStop
);
if
(
previousTokenStop
)
{
if
(
.
&&
lastFinalStateToken
!= -
1
)
{
(
,
lastFinalStateLength
,
lastFinalStateToken
,
true
,
nullptr
);
CallExtendProcAndColorizeProc
(
,
,
token
,
);
if
(
token
.
)
{
.
=
.
();
}
return
+
token
.
;
}
else
if
(
i
==
)
{
if
(
tokenStartState
==
())
{
if
(
)
{
.
(
.
,
,
1
, -
1
);
}
.
=
.
();
return
i
+
1
;
}
}
else
{
if
(
)
{
.
(
.
,
,
lastFinalStateLength
,
lastFinalStateToken
);
}
.
=
lastFinalStateState
;
return
+
lastFinalStateLength
;
}
}
if
(
finalState
)
{
lastFinalStateLength
=
i
+
1
-
;
lastFinalStateToken
=
currentToken
;
lastFinalStateState
=
.
;
}
}
if
(
lastFinalStateToken
!= -
1
&&
+
lastFinalStateLength
==
)
{
if
(
.
)
{
(
,
lastFinalStateLength
,
lastFinalStateToken
,
true
,
nullptr
);
CallExtendProcAndColorizeProc
(
,
,
token
,
);
}
else
if
(
)
{
.
(
.
,
,
lastFinalStateLength
,
lastFinalStateToken
);
}
}
else
if
(
)
{
.
(
.
,
,
-
,
.
(
.
));
}
return
;
}
void
*
::
(
const
wchar_t
*
,
)
{
=
0
;
while
(
index
!=
)
{
index
=
(
,
,
index
,
true
);
}
return
.
;
}
::
(
const
collections
::
<
>&
,
)
:proc(
)
{
<
::
>
;
<
::
>
;
::
;
<
<
>>
=
.
();
while
(
enumerator
())
{
const
&
=
enumerator
();
::
=
(
code
);
::
=
regex
();
expression
(
subsets
);
expressions
.
(
expression
);
}
for
(
=
0
;
i
<
expressions
.
();
i
++)
{
<
*,
*>
;
<
*,
*>
;
::
=
expressions
i
];
expression
(
subsets
);
::
=
expression
();
::
=
(
eNfa
,
,
nfaStateMap
);
::
=
(
nfa
,
dfaStateMap
);
dfas
.
(
dfa
);
}
for
(
=
0
;
i
<
dfas
.
();
i
++)
{
::
=
dfas
i
];
for
(
=
0
;
j
<
dfa
.
();
j
++)
{
if
(
dfa
j
]
)
{
dfa
j
]
= (
void
*)
i
;
}
else
{
dfa
j
]
= (
void
*)
dfas
.
();
}
}
}
::
=
new
;
for
(
=
0
;
i
<
dfas
.
();
i
++)
{
(
bigEnfa
,
dfas
i
]
);
(
bigEnfa
,
dfas
i
]
);
}
bigEnfa
=
bigEnfa
();
for
(
=
0
;
i
<
dfas
.
();
i
++)
{
bigEnfa
(
bigEnfa
,
dfas
i
]
);
}
<
*,
*>
;
<
*,
*>
;
::
=
(
bigEnfa
,
,
nfaStateMap
);
for
(
=
0
;
i
<
nfaStateMap
.
().
();
i
++)
{
void
*
=
nfaStateMap
.
().
(
i
)->
;
nfaStateMap
.
()
i
]->
=
userData
;
}
::
=
(
bigNfa
,
dfaStateMap
);
for
(
=
0
;
i
<
dfaStateMap
.
().
();
i
++)
{
void
*
=
dfaStateMap
.
(
i
).
(
0
)->
;
for
(
=
1
;
j
<
dfaStateMap
.
(
i
).
();
j
++)
{
void
*
=
dfaStateMap
.
(
i
).
(
j
)->
;
if
(
userData
>
newData
)
{
userData
=
newData
;
}
}
dfaStateMap
.
()
i
]->
=
userData
;
}
=
new
(
bigDfa
,
subsets
);
.
(
bigDfa
.
());
for
(
=
0
;
i
<
.
();
i
++)
{
void
*
=
bigDfa
i
]
;
i
] = (
)
userData
;
}
}
::
()
{
if
(
)
delete
;
}
::
(
const
&
,
)
const
{
->
PrepareForRelatedFinalStateTable
();
return
(
,
,
,
,
);
}
::
()
const
{
->
PrepareForRelatedFinalStateTable
();
return
(
,
);
}
::
()
const
{
return
(
(),
);
}
}
}