#include "ParsingAnalyzer.h"
namespace
{
namespace
{
using
namespace
collections
;
using
namespace
definitions
;
namespace
{
bool
::
(
*
)
{
if
(
->
())
return
false
;
if
(
.
().
(
->
())!=-
1
)
return
false
;
switch
(
)
{
case
:
switch
(
->
())
{
case
:
break
;
case
:
break
;
case
:
break
;
case
:
break
;
default
:
return
false
;
}
break
;
case
:
switch
(
->
())
{
case
:
break
;
default
:
return
false
;
}
break
;
case
:
switch
(
->
())
{
case
:
case
:
case
:
break
;
default
:
return
false
;
}
break
;
default
:
return
false
;
}
->
=
this
;
.
(
);
.
(
->
(),
);
return
true
;
}
::
(
*
,
,
const
&
,
*
,
const
&
)
:manager(
)
,type(
)
,name(
)
,descriptorSymbol(
)
,descriptorString(
)
,parentSymbol(
0
)
,arrayTypeSymbol(
0
)
{
}
::
()
{
}
*
::
()
{
return
;
}
::
::
()
{
return
;
}
const
&
::
()
{
return
;
}
::
()
{
return
.
();
}
*
::
(
)
{
if
(
0
<=
&&
<
.
())
{
return
];
}
else
{
return
0
;
}
}
*
::
(
const
&
)
{
=
.
().
(
);
if
(
index
==-
1
)
{
return
0
;
}
else
{
return
.
().
(
index
);
}
}
*
::
()
{
return
;
}
::
()
{
return
;
}
*
::
()
{
return
;
}
bool
::
()
{
switch
(
)
{
case
::
:
case
::
:
case
::
:
case
::
:
return
true
;
default
:
return
false
;
}
}
*
::
(
const
&
)
{
if
(
==
::
)
{
*
=
this
;
while
(
scope
)
{
*
=
scope
->
(
);
if
(
subSymbol
)
{
return
subSymbol
;
}
else
{
scope
=
scope
->
();
}
}
}
return
0
;
}
*
::
(
*
)
{
if
(
==
::
&&
->
()==
::
)
{
=
0
;
=
0
;
*
=
this
;
*
=
;
while
(
a
||
b
)
{
if
(
a
)
{
aCount
++;
a
=
a
->
();
}
if
(
b
)
{
bCount
++;
b
=
b
->
();
}
}
a
=
this
;
b
=
;
=
aCount
<
bCount
?
aCount
:
bCount
;
for
(
=
aCount
;
i
>
min
;
i
--)
{
a
=
a
->
();
}
for
(
=
bCount
;
i
>
min
;
i
--)
{
b
=
b
->
();
}
while
(
a
!=
b
)
{
a
=
a
->
();
b
=
b
->
();
}
return
a
;
}
return
0
;
}
bool
::
(
<
>
,
*
)
{
if
(
->
(
.
()))
{
.
(
);
return
true
;
}
return
false
;
}
::
()
{
=
new
(
this
,
::
,
L""
,
0
,
L""
);
=
new
(
this
,
::
,
L"token"
,
0
,
L""
);
.
(
);
.
(
);
}
::
()
{
}
*
::
()
{
return
;
}
*
::
()
{
return
;
}
*
::
(
*
)
{
if
(
->
())
{
if
(!
->
)
{
->
=
new
(
this
,
::
,
L""
,
,
L""
);
.
(
->
);
}
return
->
;
}
else
{
return
0
;
}
}
*
::
(
definitions
::
ParsingDefinitionClassDefinition
*
,
*
,
*
)
{
if
((!
||
->
()==
::
) && (!
||
->
()))
{
*
=
new
(
this
,
::
,
->
,
,
L""
);
if
(
(
symbol
,
?
:
))
{
symbolClassDefinitionCache
.
(
symbol
,
);
classDefinitionSymbolCache
.
(
,
symbol
);
return
symbol
;
}
}
return
0
;
}
*
::
(
const
&
,
*
,
*
)
{
if
(
&&
->
()==
::
&&
&&
->
())
{
*
=
new
(
this
,
::
,
,
,
L""
);
if
(
(
symbol
,
))
{
return
symbol
;
}
}
return
0
;
}
*
::
(
const
&
,
*
)
{
if
(!
||
->
()==
::
)
{
*
=
new
(
this
,
::
,
,
0
,
L""
);
if
(
(
symbol
,
?
:
))
{
return
symbol
;
}
}
return
0
;
}
*
::
(
const
&
,
*
)
{
if
(
&&
->
()==
::
)
{
*
=
new
(
this
,
::
,
,
,
L""
);
if
(
(
symbol
,
))
{
return
symbol
;
}
}
return
0
;
}
*
::
(
const
&
,
const
&
)
{
*
=
new
(
this
,
::
,
,
,
);
if
(
(
symbol
,
))
{
return
symbol
;
}
return
0
;
}
*
::
(
const
&
,
*
)
{
if
(
&&
->
())
{
*
=
new
(
this
,
::
,
,
,
L""
);
if
(
(
symbol
,
))
{
return
symbol
;
}
}
return
0
;
}
::
*
::
(
*
)
{
=
symbolClassDefinitionCache
.
().
(
);
return
index
==-
1
?
0
:
symbolClassDefinitionCache
.
().
(
index
);
}
*
::
(
*
)
{
=
classDefinitionSymbolCache
.
().
(
);
return
index
==-
1
?
0
:
classDefinitionSymbolCache
.
().
(
index
);
}
*
::
(
definitions
::
*
,
*
)
{
(
,
);
=
definitionTypeSymbolCache
.
().
(
key
);
return
index
==-
1
?
0
:
definitionTypeSymbolCache
.
().
(
index
);
}
bool
::
(
definitions
::
*
,
*
,
*
)
{
(
,
);
=
definitionTypeSymbolCache
.
().
(
key
);
if
(
index
==-
1
)
{
definitionTypeSymbolCache
.
(
key
,
);
return
true
;
}
else
{
return
false
;
}
}
*
::
(
definitions
::
*
)
{
=
definitionGrammarSymbolCache
.
().
(
);
return
index
==-
1
?
0
:
definitionGrammarSymbolCache
.
().
(
index
);
}
bool
::
(
definitions
::
*
,
*
)
{
=
definitionGrammarSymbolCache
.
().
(
);
if
(
index
==-
1
)
{
definitionGrammarSymbolCache
.
(
,
);
return
true
;
}
else
{
return
false
;
}
}
*
::
(
definitions
::
*
)
{
=
definitionGrammarTypeCache
.
().
(
);
return
index
==-
1
?
0
:
definitionGrammarTypeCache
.
().
(
index
);
}
bool
::
(
definitions
::
*
,
*
)
{
=
definitionGrammarTypeCache
.
().
(
);
if
(
index
==-
1
)
{
definitionGrammarTypeCache
.
(
,
);
return
true
;
}
else
{
return
false
;
}
}
(
*
)
{
if
(
->
()==
::
)
{
return
(
->
())+
L"[]"
;
}
else
{
=
->
();
=
->
();
while
(
&&
!=
->
()->
())
{
name
=
->
()+
L"."
+
name
;
=
->
();
}
return
name
;
}
}
class
:
public
,
public
::
{
public
:
*
;
*
;
<
<
>>&
;
*
;
(
*
,
*
,
<
<
>>&
)
:manager(
)
,scope(
)
,errors(
)
,result(
0
)
{
}
void
(
ParsingDefinitionPrimitiveType
*
)
override
{
*
=
;
while
(
currentScope
)
{
*
=
currentScope
->
(
->
);
if
(
type
)
{
if
(
type
->
())
{
=
type
;
}
else
{
.
(
new
(
,
L"\""
+
->
+
L"\" in current scope is not a type."
));
}
return
;
}
currentScope
=
currentScope
->
();
}
.
(
new
(
,
L"Cannot not find \""
+
->
+
L"\" in current scope."
));
}
void
(
ParsingDefinitionTokenType
*
)
override
{
=
->
();
}
void
(
*
)
override
{
*
=
(
->
.
(),
,
,
);
if
(
type
)
{
*
=
type
->
(
->
);
if
(!
subType
)
{
.
(
new
(
,
L"\""
+
(
type
)+
L"\" does not has a sub type called \""
+
->
+
L"\"."
));
}
else
if
(
subType
->
())
{
=
subType
;
}
else
{
.
(
new
(
,
L"\""
+
(
type
)+
L"\" contains a sub definition called \""
+
->
+
L"\" but this is not a type."
));
}
}
}
void
(
ParsingDefinitionArrayType
*
)
override
{
*
=
(
->
.
(),
,
,
);
if
(
type
)
{
=
->
(
type
);
}
}
};
*
(
definitions
::
*
,
*
,
*
,
collections
::
<
<
>>&
)
{
*
=
->
(
,
);
if
(!
result
)
{
(
, (
?
:
->
()),
);
->
(&
visitor
);
result
=
visitor
.
;
->
(
,
,
result
);
}
return
result
;
}
class
PrepareSymbolsTypeDefinitionVisitor
:
public
,
public
ParsingDefinitionTypeDefinition
::
{
public
:
*
;
*
;
<
<
>>&
;
PrepareSymbolsTypeDefinitionVisitor
(
*
,
*
,
<
<
>>&
)
:manager(
)
,scope(
)
,errors(
)
{
}
bool
(
ParsingDefinitionTypeDefinition
*
,
const
&
)
{
if
(
->
(
->
))
{
.
(
new
(
,
L"Cannot redefine \""
+
->
+
L"\" to be "
+
+
L"."
));
return
false
;
}
else
{
return
true
;
}
}
void
(
ParsingDefinitionClassMemberDefinition
*
)
override
{
if
(
(
,
L"a class field"
))
{
*
=
(
->
.
(),
,
,
);
if
(
fieldType
)
{
*
=
->
(
->
,
,
fieldType
);
if
(!
field
)
{
.
(
new
(
,
L"A class field cannot be defined here."
));
}
}
}
}
void
(
ParsingDefinitionClassDefinition
*
)
override
{
if
(
(
,
L"a class type"
))
{
*
=
0
;
if
(
->
)
{
baseType
=
(
->
.
(),
,
,
);
}
*
=
->
(
,
baseType
, (
->
()==
::
?
0
:
));
if
(
classType
)
{
PrepareSymbolsTypeDefinitionVisitor
(
,
classType
,
);
FOREACH(Ptr<ParsingDefinitionTypeDefinition>, subType, node->subTypes)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionTypeDefinition
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionTypeDefinition
>
;
__foreach_iterator__
.
(
subType
);)
{
subType
(&
visitor
);
}
FOREACH(Ptr<ParsingDefinitionClassMemberDefinition>, member, node->members)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionClassMemberDefinition
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionClassMemberDefinition
>
;
__foreach_iterator__
.
(
member
);)
{
member
(&
visitor
);
}
}
else
{
.
(
new
(
,
L"A class type cannot be defined here."
));
}
}
}
void
(
ParsingDefinitionEnumMemberDefinition
*
)
override
{
if
(
(
,
L"an enum item"
))
{
*
=
->
(
->
,
);
if
(!
enumItem
)
{
.
(
new
(
,
L"An enum item cannot be defined here."
));
}
}
}
void
(
ParsingDefinitionEnumDefinition
*
)
override
{
if
(
(
,
L"an enum type"
))
{
*
=
->
(
->
, (
->
()==
::
?
0
:
));
if
(
enumType
)
{
PrepareSymbolsTypeDefinitionVisitor
(
,
enumType
,
);
FOREACH(Ptr<ParsingDefinitionEnumMemberDefinition>, member, node->members)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionEnumMemberDefinition
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionEnumMemberDefinition
>
;
__foreach_iterator__
.
(
member
);)
{
member
(&
visitor
);
}
}
else
{
.
(
new
(
,
L"An enum type cannot be defined here."
));
}
}
}
};
void
(
<
definitions
::
>
,
*
,
collections
::
<
<
>>&
)
{
{
PrepareSymbolsTypeDefinitionVisitor
(
,
->
(),
);
FOREACH(Ptr<ParsingDefinitionTypeDefinition>, typeDefinition, definition->types)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionTypeDefinition
>>&
= ::
vl
::
collections
::
(
types
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionTypeDefinition
>
;
__foreach_iterator__
.
(
typeDefinition
);)
{
typeDefinition
(&
visitor
);
}
}
FOREACH(Ptr<ParsingDefinitionTokenDefinition>, token, definition->tokens)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionTokenDefinition
>>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionTokenDefinition
>
;
__foreach_iterator__
.
(
token
);)
{
if
(
->
()->
(
token
))
{
.
(
new
(
token
.
(),
L"Cannot redefine \""
+
token
+
L"\" to be a token definition."
));
}
else
{
->
(
token
,
token
regex
);
try
{
regex_internal
::
(
token
regex
);
}
catch
(
const
&
)
{
.
(
new
(
token
.
(),
L"Wrong token definition for \""
+
token
+
L"\": "
+
ex
.
()));
}
}
}
FOREACH(Ptr<ParsingDefinitionRuleDefinition>, rule, definition->rules)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionRuleDefinition
>>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionRuleDefinition
>
;
__foreach_iterator__
.
(
rule
);)
{
if
(
->
()->
(
rule
))
{
.
(
new
(
rule
.
(),
L"Cannot redefine \""
+
rule
+
L"\" to be a rule definition."
));
}
else
{
*
=
(
rule
.
(),
,
0
,
);
if
(
type
)
{
if
(
type
->
()!=
::
)
{
.
(
new
(
rule
.
(),
L"\""
+
(
type
)+
L"\" cannot be a type of a rule because this is not a class type."
));
}
->
(
rule
,
type
);
}
}
}
}
class
ValidateRuleStructureVisitor
:
public
,
public
::
{
public
:
<
>
;
*
;
ParsingDefinitionRuleDefinition
*
;
<
<
>>&
;
;
ValidateRuleStructureVisitor
(
<
>
,
*
,
ParsingDefinitionRuleDefinition
*
,
<
<
>>&
)
:definition(
)
,manager(
)
,errors(
)
,rule(
)
,loopCount(
0
)
{
}
void
(
*
,
*
)
{
if
(
->
()==
::
)
{
*
=
->
()->
(
->
)->
();
*
=
;
while
(
currentType
&&
currentType
!=
ruleType
)
{
currentType
=
currentType
->
();
}
if
(!
currentType
)
{
.
(
new
(
,
L"Cannot create type \""
+
(
)+
L"\" in a rule of type \""
+
(
ruleType
)+
L"\" because there are no implicit conversions from the created type to the rule type."
));
}
}
else
{
.
(
new
(
,
L"\""
+
(
)+
L"\" cannot be created because this is not a class type."
));
}
}
void
(
ParsingDefinitionPrimitiveGrammar
*
)
override
{
*
=
->
()->
(
->
);
if
(!
symbol
)
{
.
(
new
(
,
L"Cannot find a token or a rule with name \""
+
->
+
L"\"."
));
}
else
switch
(
symbol
->
())
{
case
::
:
{
bool
=
false
;
FOREACH(Ptr<ParsingDefinitionTokenDefinition>, token, definition->tokens)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionTokenDefinition
>>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionTokenDefinition
>
;
__foreach_iterator__
.
(
token
);)
{
if
(
token
==
symbol
->
())
{
discard
=
token
;
break
;
}
}
if
(
discard
)
{
.
(
new
(
,
L"Cannot use discard token \""
+
->
+
L"\" as input."
));
break
;
}
}
case
::
:
{
*
=
symbol
->
();
->
(
,
symbol
);
->
(
,
symbolType
);
}
break
;
default
:
.
(
new
(
,
L"\""
+
->
+
L"\" is not a token definition or rule definition."
));
}
}
void
(
ParsingDefinitionTextGrammar
*
)
override
{
=
regex_internal
::
(
->
text
);
for
(
=
0
;
i
<
->
()->
();
i
++)
{
*
=
->
()->
(
i
);
if
(
symbol
->
()==
::
)
{
=
regex_internal
::
NormalizeEscapedTextForRegex
(
symbol
->
());
if
(
normalizedRegex
==
regex
)
{
->
(
,
symbol
);
->
(
,
->
());
return
;
}
}
}
.
(
new
(
,
L"Cannot find a token whose definition is exactly \""
+
regex
+
L"\"."
));
}
void
(
ParsingDefinitionSequenceGrammar
*
)
override
{
->
(
this
);
->
(
this
);
}
void
(
ParsingDefinitionAlternativeGrammar
*
)
override
{
->
(
this
);
->
(
this
);
}
void
(
ParsingDefinitionLoopGrammar
*
)
override
{
++;
->
(
this
);
--;
}
void
(
ParsingDefinitionOptionalGrammar
*
)
override
{
->
(
this
);
}
void
(
ParsingDefinitionCreateGrammar
*
)
override
{
if
(
>
0
)
{
.
(
new
(
,
L"Parsing tree node creation (the \"as\" operator) is not allowed inside loops."
));
}
if
(
*
=
(
->
.
(),
,
0
,
))
{
(
,
nodeType
);
}
->
(
this
);
}
void
(
ParsingDefinitionAssignGrammar
*
)
override
{
if
(!
->
.
<
ParsingDefinitionPrimitiveGrammar
>() && !
->
.
<
ParsingDefinitionTextGrammar
>())
{
.
(
new
(
,
L"Only parsing tree node returned from a rule or a token can be assigned to a class field."
));
}
->
(
this
);
}
void
(
ParsingDefinitionUseGrammar
*
)
override
{
if
(
>
0
)
{
.
(
new
(
,
L"Parsing tree node reusing (the \"!\" operator) is not allowed inside loops."
));
}
if
(!
->
.
<
ParsingDefinitionPrimitiveGrammar
>())
{
.
(
new
(
,
L"Only parsing tree node returned from a rule can be reused."
));
}
else
if
(
*
=
->
(
->
.
()))
{
if
(
symbol
->
()!=
::
)
{
.
(
new
(
,
L"Only parsing tree node returned from a rule can be reused."
));
}
}
if
(
*
=
->
(
->
.
()))
{
(
,
nodeType
);
}
->
(
this
);
}
void
(
ParsingDefinitionSetterGrammar
*
)
override
{
->
(
this
);
}
};
void
(
<
definitions
::
>
,
<
definitions
::
ParsingDefinitionRuleDefinition
>
,
*
,
collections
::
<
<
>>&
)
{
FOREACH(Ptr<ParsingDefinitionGrammar>, grammar, rule->grammars)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
grammar
);)
{
ValidateRuleStructureVisitor
(
,
,
.
(),
);
grammar
(&
visitor
);
}
}
struct
{
*
;
*
;
bool
;
*
;
()
:previousFragment(
0
)
,grammar(
0
)
,epsilon(
false
)
,createdType(
0
)
{
}
};
struct
{
<
<
>>
;
*
;
()
:pathType(
0
)
{
}
()
{
;
FOREACH(Ptr<GrammarPathFragment>, fragment, fragments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
fragment
);)
{
if
(!
fragment
)
{
if
(
result
!=
L""
)
result
+=
L" "
;
result
(
fragment
);
}
}
return
result
;
}
};
struct
{
<
<
>>
;
};
class
EnumerateGrammarPathVisitor
:
public
,
public
::
{
public
:
*
;
ParsingDefinitionRuleDefinition
*
;
<
<
>>
;
<
*>
;
EnumerateGrammarPathVisitor
(
*
,
ParsingDefinitionRuleDefinition
*
)
:manager(
)
,rule(
)
{
}
EnumerateGrammarPathVisitor
(
const
EnumerateGrammarPathVisitor
&
)
:manager(
.
)
,rule(
.
)
{
(
,
.
);
}
void
(
const
EnumerateGrammarPathVisitor
&
)
{
(
,
.
,
true
);
(
,
.
,
true
);
}
void
(
*
,
bool
,
*
)
{
if
(
.
()==
0
)
{
*
=
new
;
fragment
->
=
;
fragment
->
=
;
fragment
->
=
;
.
(
fragment
);
.
(
fragment
);
}
else
for
(
=
0
;
i
<
.
();
i
++)
{
*
=
new
;
fragment
->
=
;
fragment
->
=
;
fragment
->
=
;
.
(
fragment
);
fragment
->
=
i
];
i
]=
fragment
;
}
}
void
(
<
<
>>&
)
{
FOREACH(GrammarPathFragment*, fragment, currentFragmentEnds)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
*>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
*
;
__foreach_iterator__
.
(
fragment
);)
{
<
>
=
new
;
.
(
path
);
*
=
fragment
;
while
(
current
)
{
path
.
(
0
,
.
(
current
)]);
current
=
current
->
;
}
}
}
void
(
ParsingDefinitionPrimitiveGrammar
*
)
override
{
(
,
false
,
0
);
}
void
(
ParsingDefinitionTextGrammar
*
)
override
{
(
,
false
,
0
);
}
void
(
ParsingDefinitionSequenceGrammar
*
)
override
{
->
(
this
);
->
(
this
);
}
void
(
ParsingDefinitionAlternativeGrammar
*
)
override
{
EnumerateGrammarPathVisitor
(*
this
);
->
(&
visitor
);
->
(
this
);
(
visitor
);
}
void
(
ParsingDefinitionLoopGrammar
*
)
override
{
EnumerateGrammarPathVisitor
(*
this
);
->
(&
visitor
);
(
,
true
,
0
);
(
visitor
);
}
void
(
ParsingDefinitionOptionalGrammar
*
)
override
{
EnumerateGrammarPathVisitor
(*
this
);
->
(&
visitor
);
(
,
true
,
0
);
(
visitor
);
}
void
(
ParsingDefinitionCreateGrammar
*
)
override
{
->
(
this
);
(
,
true
,
->
(
->
.
(),
0
));
}
void
(
ParsingDefinitionAssignGrammar
*
)
override
{
->
(
this
);
(
,
true
,
0
);
}
void
(
ParsingDefinitionUseGrammar
*
)
override
{
->
(
this
);
(
,
true
,
->
(
->
.
())->
());
}
void
(
ParsingDefinitionSetterGrammar
*
)
override
{
->
(
this
);
(
,
true
,
0
);
}
};
class
ResolveAssignerGrammarVisitor
:
public
,
public
::
{
public
:
typedef
<
*,
<
>>
;
*
;
<
<
>>&
;
&
;
ResolveAssignerGrammarVisitor
(
*
,
<
<
>>&
,
&
)
:manager(
)
,errors(
)
,grammarPaths(
)
{
}
*
(
*
,
const
&
)
{
<
>
=
];
*
=
paths
0
]
;
for
(
=
1
;
i
<
paths
.
();
i
++)
{
pathType
=
pathType
->
(
paths
i
]
);
if
(!
pathType
)
break
;
}
;
;
for
(
int
=
0
;
i
<
paths
.
();
i
++)
{
if
(
i
>
0
)
{
pathNames
+=
L", "
;
typeNames
+=
L", "
;
}
pathNames
+=
L"{"
+
paths
i
]
()+
L"}"
;
typeNames
+=
L"\""
+
(
paths
i
]
)+
L"\""
;
}
if
(
pathType
)
{
*
=
pathType
->
(
);
if
(!
field
)
{
.
(
new
(
,
L"There are multiple grammar paths with different created types get through this operation for class field \""
+
+
L"\", but the common base type \""
+
(
pathType
)+
L"\" of these types doesn't contains the required class field. Types: "
+
typeNames
+
L"; Paths: "
+
pathNames
+
L"."
));
}
else
if
(
field
->
()!=
::
)
{
.
(
new
(
,
L"There are multiple grammar paths with different created types get through this operation for class field \""
+
+
L"\", and the common base type \""
+
(
pathType
)+
L"\" of these types contains a symbol called \""
+
+
L"\", but this is not a class field. Types: "
+
typeNames
+
L"; Paths: "
+
pathNames
+
L"."
));
}
else
{
return
field
;
}
}
else
{
.
(
new
(
,
L"There are multiple grammar paths with different created types get through this operation for class field \""
+
+
L"\", but these types don't have a common base type. Types: "
+
typeNames
+
L"; Paths: "
+
pathNames
+
L"."
));
}
return
0
;
}
void
(
ParsingDefinitionPrimitiveGrammar
*
)
override
{
}
void
(
ParsingDefinitionTextGrammar
*
)
override
{
}
void
(
ParsingDefinitionSequenceGrammar
*
)
override
{
}
void
(
ParsingDefinitionAlternativeGrammar
*
)
override
{
}
void
(
ParsingDefinitionLoopGrammar
*
)
override
{
}
void
(
ParsingDefinitionOptionalGrammar
*
)
override
{
}
void
(
ParsingDefinitionCreateGrammar
*
)
override
{
}
void
(
ParsingDefinitionAssignGrammar
*
)
override
{
if
(
*
=
(
,
->
))
{
->
(
,
field
);
->
(
,
field
->
());
*
=
field
->
();
*
=
->
(
->
.
());
*
=
fieldType
;
if
(
targetFieldType
->
()==
::
)
{
targetFieldType
=
targetFieldType
->
();
}
if
(
targetFieldType
!=
valueType
&&
valueType
->
(
targetFieldType
)!=
targetFieldType
)
{
.
(
new
(
,
L"Cannot assign value from grammar {"
+
(
->
.
())+
L"} of type \""
+
(
valueType
)+
L"\" to the field \""
+
->
+
L"\" of type \""
+
(
fieldType
)+
L"\"."
));
}
}
}
void
(
ParsingDefinitionUseGrammar
*
)
override
{
}
void
(
ParsingDefinitionSetterGrammar
*
)
override
{
if
(
*
=
(
,
->
))
{
->
(
,
field
);
->
(
,
field
->
());
if
(
field
->
()->
()!=
::
)
{
.
(
new
(
,
L"Setter operation (the \"with\" operator) can only specify the value of a class field of an enum type. But \""
+
(
field
->
())+
L"\" is not a enum type."
));
}
else
{
*
=
field
->
();
*
=
enumType
->
(
->
);
if
(!
enumItem
)
{
.
(
new
(
,
L"Type \""
+
(
enumType
)+
L"\" from field \""
+
->
+
L"\" does not have an enum item called \""
+
->
+
L"\"."
));
}
else
if
(
enumItem
->
()!=
::
)
{
.
(
new
(
,
L"Type \""
+
(
enumType
)+
L"\" from field \""
+
->
+
L"\" has a symbol called \""
+
->
+
L"\", but this is not an enum item."
));
}
}
}
}
};
void
(
<
definitions
::
ParsingDefinitionRuleDefinition
>
,
*
,
collections
::
<
<
>>&
)
{
*
=
->
()->
(
)->
();
FOREACH(Ptr<ParsingDefinitionGrammar>, grammar, rule->grammars)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
grammar
);)
{
<
<
>>
;
{
EnumerateGrammarPathVisitor
(
,
.
());
grammar
(&
visitor
);
visitor
.
(
paths
);
}
FOREACH(Ptr<GrammarPath>, path, paths)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
paths
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
path
);)
{
path
=
ruleType
;
=
0
;
=
0
;
FOREACH(Ptr<GrammarPathFragment>, fragment, path->fragments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
path
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
fragment
);)
{
if
(
fragment
)
{
createdTypeCount
++;
path
=
fragment
;
}
if
(!
fragment
)
{
transitionCount
++;
}
}
if
(
createdTypeCount
==
0
)
{
.
(
new
(
grammar
.
(),
L"No parsing tree node is created if the following path is chosen: \""
+
path
()+
L"\" in rule \""
+
+
L"\"."
));
}
else
if
(
createdTypeCount
>
1
)
{
.
(
new
(
grammar
.
(),
L"Multiple parsing tree nodes are created if the following path is chosen: \""
+
path
()+
L"\" in rule \""
+
+
L"\"."
));
}
if
(
transitionCount
==
0
)
{
.
(
new
(
grammar
.
(),
L"Rule \""
+
+
L"\" is not allowed to infer to an empty token sequence."
));
}
}
ResolveAssignerGrammarVisitor
::
;
FOREACH(Ptr<GrammarPath>, path, paths)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
paths
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
path
);)
{
FOREACH(Ptr<GrammarPathFragment>, fragment, path->fragments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
path
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
fragment
);)
{
*
=
fragment
;
<
>
;
=
grammarPathMap
.
().
(
grammar
);
if
(
index
==-
1
)
{
container
new
;
grammarPathMap
.
(
grammar
,
container
);
}
else
{
container
grammarPathMap
.
().
(
index
);
}
container
.
(
path
);
}
}
ResolveAssignerGrammarVisitor
(
,
,
grammarPathMap
);
FOREACH(ParsingDefinitionGrammar*, grammar, grammarPathMap.Keys())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
*>&
= ::
vl
::
collections
::
(
grammarPathMap
.
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
*
;
__foreach_iterator__
.
(
grammar
);)
{
grammar
->
(&
visitor
);
}
}
}
void
(
<
ParsingDefinitionTypeDefinition
>
,
*
,
*
,
collections
::
<
<
>>&
)
{
if
(
<
ParsingDefinitionClassDefinition
>
=
.
<
ParsingDefinitionClassDefinition
>())
{
if
(
node
)
{
*
=
(
node
.
(),
,
,
);
=
(
node
.
());
if
(!
ambigiousType
)
{
.
(
new
(
node
.
(),
L"Ambiguous type \""
+
ambiguousTypeText
+
L"\" for type \""
+
node
+
L"\" does not exist."
));
}
else
if
(
ambigiousType
->
()!=
::
)
{
.
(
new
(
node
.
(),
L"Ambiguous type \""
+
ambiguousTypeText
+
L"\" for type \""
+
node
+
L"\" is not a type."
));
}
else
if
(
ambigiousType
->
()!=
->
()->
(
node
))
{
.
(
new
(
node
.
(),
L"Ambiguous type \""
+
ambiguousTypeText
+
L"\" for type \""
+
node
+
L"\" does not inherit from \""
+
node
+
L"\"."
));
}
else
{
bool
=
false
;
if
(
ambigiousType
->
()==
1
)
{
*
=
ambigiousType
->
(
0
);
if
(
field
->
()
L"items"
&&
field
->
()==
::
)
{
*
=
field
->
();
if
(
fieldType
->
()==
::
&&
fieldType
->
()==
ambigiousType
->
())
{
correct
=
true
;
}
}
}
if
(!
correct
)
{
.
(
new
(
node
.
(),
L"Ambiguous type \""
+
ambiguousTypeText
+
L"\" for type \""
+
node
+
L"\" can only contains one field called \"item\" which should be an array of \""
+
node
+
L"\"."
));
}
}
}
*
=
->
(
node
.
());
if
(
classType
)
{
FOREACH(Ptr<ParsingDefinitionTypeDefinition>, subType, node->subTypes)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionTypeDefinition
>>&
= ::
vl
::
collections
::
(
node
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionTypeDefinition
>
;
__foreach_iterator__
.
(
subType
);)
{
(
subType
,
,
classType
,
);
}
}
}
}
void
(
<
definitions
::
>
,
*
,
collections
::
<
<
>>&
)
{
FOREACH(Ptr<ParsingDefinitionTypeDefinition>, type, definition->types)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionTypeDefinition
>>&
= ::
vl
::
collections
::
(
types
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionTypeDefinition
>
;
__foreach_iterator__
.
(
type
);)
{
(
type
,
,
->
(),
);
}
FOREACH(Ptr<ParsingDefinitionRuleDefinition>, rule, definition->rules)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
ParsingDefinitionRuleDefinition
>>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
ParsingDefinitionRuleDefinition
>
;
__foreach_iterator__
.
(
rule
);)
{
=
.
();
(
,
rule
,
,
);
if
(
.
()==
errorCount
)
{
(
rule
,
,
);
}
}
}
void
(
<
definitions
::
>
,
*
,
collections
::
<
<
>>&
)
{
(
,
,
);
if
(
.
()>
0
)
return
;
(
,
,
);
}
}
}
}