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
Alexandru Dura
SPPF Earley Parser
Commits
9d220f4a
Commit
9d220f4a
authored
Feb 17, 2020
by
Alexandru Dura
Browse files
Implement a visitor that pushes metavar nodes towards the root
parent
c4f8d8c0
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/main/java/se/lth/sep/SPPFNode.java
View file @
9d220f4a
...
...
@@ -4,7 +4,7 @@ import java.util.Arrays;
import
java.util.HashSet
;
import
java.util.Set
;
public
class
SPPFNode
implements
Cloneable
{
public
class
SPPFNode
{
static
public
class
FamilyNode
{
private
SPPFNode
[]
child
;
...
...
@@ -42,7 +42,7 @@ public class SPPFNode implements Cloneable {
final
int
prime
=
47
;
int
result
=
1
;
for
(
int
i
=
0
;
i
<
child
.
length
;
++
i
)
{
result
=
prime
*
result
+
((
child
[
0
]
==
null
)
?
0
:
child
[
0
].
hashCode
());
result
=
prime
*
result
+
((
child
[
i
]
==
null
)
?
0
:
child
[
i
].
hashCode
());
}
return
result
;
}
...
...
src/main/java/se/lth/sep/SPPFTrivialProductionRemover.java
View file @
9d220f4a
...
...
@@ -32,60 +32,55 @@ public class SPPFTrivialProductionRemover implements SPPFNodeVisitor {
return
;
}
Set
<
SPPFNode
.
FamilyNode
>
children
=
n
.
getChildren
();
for
(
SPPFNode
.
FamilyNode
f
:
n
.
getChildren
())
{
f
.
accept
(
this
);
}
HashSet
<
SPPFNode
.
FamilyNode
>
newChildren
=
new
HashSet
<>();
HashSet
<
SPPFNode
.
FamilyNode
>
childrenToRemove
=
new
HashSet
<>();
for
(
SPPFNode
.
FamilyNode
f
:
children
)
{
f
.
accept
(
this
);
for
(
SPPFNode
.
FamilyNode
f
:
n
.
getChildren
())
{
if
(
f
.
getNumChildren
()
=
=
0
)
if
(
f
.
getNumChildren
()
!
=
1
)
continue
;
SPPFNode
[]
childArray
=
new
SPPFNode
[
f
.
getNumChildren
()];
boolean
updatedChildren
=
false
;
for
(
int
i
=
0
;
i
<
f
.
getNumChildren
();
++
i
)
{
childArray
[
i
]
=
f
.
getChild
(
i
);
}
for
(
int
i
=
0
;
i
<
f
.
getNumChildren
();
++
i
)
{
SPPFNode
ruleNode
=
f
.
getChild
(
i
);
assert
ruleNode
.
getLabel
()
instanceof
SymbolLabel
;
Category
head
=
((
SymbolLabel
)
ruleNode
.
getLabel
()).
getSymbol
(
grammar
);
boolean
allProductionAreTrivial
=
true
;
for
(
SPPFNode
.
FamilyNode
g
:
ruleNode
.
getChildren
())
{
if
(
g
.
getNumChildren
()
!=
1
)
{
allProductionAreTrivial
=
false
;
break
;
}
SPPFNode
bubbleUpChild
=
null
;
SPPFNode
nn
=
f
.
getChild
(
i
);
for
(
SPPFNode
.
FamilyNode
ff
:
nn
.
getChildren
())
{
if
(
ff
.
getNumChildren
()
!=
1
)
continue
;
Category
body
=
(
(
SymbolLabel
)
g
.
getChild
(
0
).
getLabel
()
).
getSymbol
(
grammar
)
;
if
(
!
is
TrivialProduction
(
head
,
body
))
{
allProductionAreTrivial
=
false
;
SymbolLabel
label
=
(
SymbolLabel
)
ff
.
getChild
(
0
).
getLabel
();
if
(
is
BubleUpChild
(
label
.
getSymbol
(
grammar
)
))
{
bubbleUpChild
=
ff
.
getChild
(
0
)
;
break
;
}
}
if
(!
allProductionAreTrivial
)
continue
;
for
(
SPPFNode
.
FamilyNode
g
:
ruleNode
.
getChildren
())
{
SPPFNode
[]
childArray
=
new
SPPFNode
[
f
.
getNumChildren
()];
for
(
int
j
=
0
;
j
<
f
.
getNumChildren
();
++
j
)
{
if
(
i
==
j
)
{
childArray
[
j
]
=
g
.
getChild
(
0
);
}
else
{
childArray
[
j
]
=
f
.
getChild
(
j
);
}
}
newChildren
.
add
(
new
SPPFNode
.
FamilyNode
(
childArray
));
childrenToRemove
.
add
(
f
);
if
(
bubbleUpChild
!=
null
)
{
childArray
[
i
]
=
bubbleUpChild
;
updatedChildren
=
true
;
}
}
if
(
updatedChildren
)
{
childrenToRemove
.
add
(
f
);
newChildren
.
add
(
new
FamilyNode
(
childArray
));
}
}
c
hildren
.
removeAll
(
childrenToRemove
);
c
hildren
.
addAll
(
newChildren
);
n
.
getC
hildren
()
.
removeAll
(
childrenToRemove
);
n
.
getC
hildren
()
.
addAll
(
newChildren
);
}
public
boolean
is
TrivialProduction
(
Category
head
,
Category
body
)
{
public
boolean
is
BubleUpChild
(
Category
c
)
{
return
false
;
}
}
src/test/java/EarleyParserTest.java
View file @
9d220f4a
...
...
@@ -185,13 +185,10 @@ public class EarleyParserTest {
Util
.
dumpParseResult
(
"testJava1.dot"
,
root
,
g
);
// remove trivial productions
SPPFTrivialProductionRemover
tpr
=
new
SPPFTrivialProductionRemover
(
g
)
{
@Override
public
boolean
isTrivialProduction
(
Category
head
,
Category
body
)
{
String
sig
=
head
.
getName
()
+
"."
+
body
.
getName
();
if
(
body
.
getName
().
equals
(
"METAVARID"
))
@Override
public
boolean
isBubleUpChild
(
Category
c
)
{
if
(
c
.
getName
().
equals
(
"METAVARID"
))
return
true
;
if
(
body
.
getName
().
equals
(
"GAP"
))
return
true
;
if
(
Java14Grammar
.
isTrivialRule
(
sig
))
if
(
c
.
getName
().
equals
(
"GAP"
))
return
true
;
return
false
;
}
...
...
@@ -229,13 +226,10 @@ public class EarleyParserTest {
Util
.
dumpParseResult
(
"testJava2.dot"
,
root
,
g
);
// remove trivial productions
SPPFTrivialProductionRemover
tpr
=
new
SPPFTrivialProductionRemover
(
g
)
{
@Override
public
boolean
isTrivialProduction
(
Category
head
,
Category
body
)
{
String
sig
=
head
.
getName
()
+
"."
+
body
.
getName
();
if
(
body
.
getName
().
equals
(
"METAVARID"
))
return
true
;
if
(
body
.
getName
().
equals
(
"GAP"
))
@Override
public
boolean
isBubleUpChild
(
Category
c
)
{
if
(
c
.
getName
().
equals
(
"METAVARID"
))
return
true
;
if
(
Java14Grammar
.
isTrivialRule
(
sig
))
if
(
c
.
getName
().
equals
(
"GAP"
))
return
true
;
return
false
;
}
...
...
@@ -275,13 +269,10 @@ public class EarleyParserTest {
Util
.
dumpParseResult
(
"testJava3.dot"
,
root
,
g
);
// remove trivial productions
SPPFTrivialProductionRemover
tpr
=
new
SPPFTrivialProductionRemover
(
g
)
{
@Override
public
boolean
isTrivialProduction
(
Category
head
,
Category
body
)
{
String
sig
=
head
.
getName
()
+
"."
+
body
.
getName
();
if
(
body
.
getName
().
equals
(
"METAVARID"
))
return
true
;
if
(
body
.
getName
().
equals
(
"GAP"
))
@Override
public
boolean
isBubleUpChild
(
Category
c
)
{
if
(
c
.
getName
().
equals
(
"METAVARID"
))
return
true
;
if
(
Java14Grammar
.
isTrivialRule
(
sig
))
if
(
c
.
getName
().
equals
(
"GAP"
))
return
true
;
return
false
;
}
...
...
@@ -323,11 +314,10 @@ public class EarleyParserTest {
// remove trivial productions
SPPFTrivialProductionRemover
tpr
=
new
SPPFTrivialProductionRemover
(
g
)
{
@Override
public
boolean
isTrivialProduction
(
Category
head
,
Category
body
)
{
String
sig
=
head
.
getName
()
+
"."
+
body
.
getName
();
if
(
body
.
getName
().
equals
(
"METAVARID"
))
@Override
public
boolean
isBubleUpChild
(
Category
c
)
{
if
(
c
.
getName
().
equals
(
"METAVARID"
))
return
true
;
if
(
body
.
getName
().
equals
(
"GAP"
))
if
(
c
.
getName
().
equals
(
"GAP"
))
return
true
;
return
false
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment