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
fd6b0f25
Commit
fd6b0f25
authored
Feb 06, 2020
by
Alexandru Dura
Browse files
'Remove dotted rules' visitor implemented for SPPF
parent
bb0d0afb
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/main/java/se/lth/sep/SPPFDebinarizeVisitor.java
0 → 100644
View file @
fd6b0f25
package
se.lth.sep
;
import
java.util.HashSet
;
import
java.util.Set
;
/**
A visitor that removes the nodes that contain dottet rules.
*/
public
class
SPPFDebinarizeVisitor
implements
SPPFNodeVisitor
{
private
HashSet
<
SPPFNode
>
visitedNodes
=
new
HashSet
<>();
private
HashSet
<
SPPFNode
.
FamilyNode
>
visitedFamNodes
=
new
HashSet
<>();
public
void
visit
(
SPPFNode
.
FamilyNode
familyNode
)
{
if
(!
visitedFamNodes
.
add
(
familyNode
))
{
// node already visited
return
;
}
for
(
int
i
=
0
;
i
<
familyNode
.
getNumChildren
();
++
i
)
familyNode
.
getChild
(
i
).
accept
(
this
);
}
public
void
visit
(
SPPFNode
n
)
{
if
(!
visitedNodes
.
add
(
n
))
{
// node already visited
return
;
}
Set
<
SPPFNode
.
FamilyNode
>
children
=
n
.
getChildren
();
HashSet
<
SPPFNode
.
FamilyNode
>
newChildren
=
new
HashSet
<>();
HashSet
<
SPPFNode
.
FamilyNode
>
childrenToRemove
=
new
HashSet
<>();
for
(
SPPFNode
.
FamilyNode
f
:
children
)
{
f
.
accept
(
this
);
if
(
f
.
getNumChildren
()
==
0
)
continue
;
// only the first child can a be a node representing a dot rule
SPPFNode
firstChild
=
f
.
getChild
(
0
);
if
(!(
firstChild
.
getLabel
()
instanceof
ItemLabel
))
continue
;
// now we know this is representing a dot rule
for
(
SPPFNode
.
FamilyNode
g
:
firstChild
.
getChildren
())
{
SPPFNode
[]
childArray
=
new
SPPFNode
[
g
.
getNumChildren
()
+
f
.
getNumChildren
()
-
1
];
for
(
int
i
=
0
;
i
<
g
.
getNumChildren
();
++
i
)
{
childArray
[
i
]
=
g
.
getChild
(
i
);
}
for
(
int
i
=
1
;
i
<
f
.
getNumChildren
();
++
i
)
{
childArray
[
g
.
getNumChildren
()
+
i
-
1
]
=
f
.
getChild
(
i
);
}
newChildren
.
add
(
new
SPPFNode
.
FamilyNode
(
childArray
));
childrenToRemove
.
add
(
f
);
}
}
children
.
removeAll
(
childrenToRemove
);
children
.
addAll
(
newChildren
);
}
}
src/main/java/se/lth/sep/SPPFNode.java
View file @
fd6b0f25
package
se.lth.sep
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.Set
;
...
...
@@ -7,23 +8,42 @@ public class SPPFNode {
static
public
class
FamilyNode
{
private
SPPFNode
[]
child
;
FamilyNode
(
SPPFNode
child0
)
{
assert
child0
!=
null
;
child
=
new
SPPFNode
[
1
];
child
[
0
]
=
child0
;
}
FamilyNode
()
{
child
=
new
SPPFNode
[
0
];
}
FamilyNode
(
SPPFNode
child0
,
SPPFNode
child1
)
{
assert
child0
!=
null
||
child1
=
=
null
;
assert
child0
!=
null
||
child1
!
=
null
;
child
=
new
SPPFNode
[
2
];
child
[
0
]
=
child0
;
child
[
1
]
=
child1
;
}
FamilyNode
(
SPPFNode
children
[])
{
child
=
Arrays
.
copyOf
(
children
,
children
.
length
);
}
public
int
getNumChildren
()
{
return
child
.
length
;
}
public
SPPFNode
getChild
(
int
i
)
{
return
child
[
i
];
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
final
int
prime
=
47
;
int
result
=
1
;
result
=
prime
*
result
+
((
child
[
0
]
==
null
)
?
0
:
child
[
0
].
hashCode
());
result
=
prime
*
result
+
((
child
[
1
]
==
null
)
?
0
:
child
[
1
].
hashCode
());
for
(
int
i
=
0
;
i
<
child
.
length
;
++
i
)
{
result
=
prime
*
result
+
((
child
[
0
]
==
null
)
?
0
:
child
[
0
].
hashCode
());
}
return
result
;
}
...
...
@@ -36,16 +56,16 @@ public class SPPFNode {
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
FamilyNode
other
=
(
FamilyNode
)
obj
;
if
(
child
[
0
]
==
null
)
{
if
(
other
.
child
[
0
]
!=
null
)
return
false
;
}
else
if
(!
child
[
0
].
equals
(
other
.
child
[
0
]))
if
(
other
.
child
.
length
!=
child
.
length
)
return
false
;
if
(
child
[
1
]
==
null
)
{
if
(
other
.
child
[
1
]
!=
null
)
for
(
int
i
=
0
;
i
<
child
.
length
;
++
i
)
{
if
(
child
[
i
]
==
null
)
{
if
(
other
.
child
[
i
]
!=
null
)
return
false
;
}
else
if
(!
child
[
i
].
equals
(
other
.
child
[
i
]))
{
return
false
;
}
else
if
(!
child
[
1
].
equals
(
other
.
child
[
1
]))
return
false
;
}
}
return
true
;
}
...
...
@@ -66,7 +86,7 @@ public class SPPFNode {
}
public
void
addChild
(
SPPFNode
child
)
{
children
.
add
(
new
FamilyNode
(
child
,
null
));
children
.
add
(
new
FamilyNode
(
child
));
}
public
void
addChildren
(
SPPFNode
child0
,
SPPFNode
child1
)
{
...
...
@@ -74,7 +94,7 @@ public class SPPFNode {
}
public
void
addEpsilon
()
{
children
.
add
(
new
FamilyNode
(
null
,
null
));
children
.
add
(
new
FamilyNode
());
}
public
String
prettyPrint
(
Grammar
info
)
{
...
...
src/main/java/se/lth/sep/Util.java
View file @
fd6b0f25
...
...
@@ -47,22 +47,17 @@ class DotVisitor implements SPPFNodeVisitor {
int
currentID
=
nodeID
++;
visitedFamilies
.
put
(
f
,
currentID
);
if
(
f
.
getChild
(
0
)
==
null
)
{
if
(
f
.
get
Num
Child
ren
()
==
0
)
{
// epsilon
ps
.
print
(
currentID
+
" [label=\u03b5];\n"
);
}
else
{
ps
.
print
(
currentID
+
" [shape=circle];\n"
);
f
.
getChild
(
0
).
accept
(
this
);
if
(
f
.
getChild
(
1
)
!=
null
)
{
f
.
getChild
(
1
).
accept
(
this
);
}
for
(
int
i
=
0
;
i
<
f
.
getNumChildren
();
++
i
)
f
.
getChild
(
i
).
accept
(
this
);
}
if
(
f
.
getChild
(
0
)
!=
null
)
ps
.
print
(
currentID
+
" -> "
+
visitedNodes
.
get
(
f
.
getChild
(
0
))
+
";\n"
);
if
(
f
.
getChild
(
1
)
!=
null
)
ps
.
print
(
currentID
+
" -> "
+
visitedNodes
.
get
(
f
.
getChild
(
1
))
+
";\n"
);
for
(
int
i
=
0
;
i
<
f
.
getNumChildren
();
++
i
)
ps
.
print
(
currentID
+
" -> "
+
visitedNodes
.
get
(
f
.
getChild
(
i
))
+
";\n"
);
}
@Override
...
...
src/test/java/EarleyParserTest.java
View file @
fd6b0f25
...
...
@@ -104,6 +104,11 @@ public class EarleyParserTest {
EarleyParser
parser
=
new
EarleyParser
(
g
);
SPPFNode
root
=
parser
.
parse
(
str
,
S
);
assertNotNull
(
root
);
Util
.
dumpParseResult
(
"testParse4-bt.dot"
,
root
,
g
);
SPPFDebinarizeVisitor
dbv
=
new
SPPFDebinarizeVisitor
();
dbv
.
visit
(
root
);
Util
.
dumpParseResult
(
"testParse4.dot"
,
root
,
g
);
}
...
...
@@ -194,6 +199,9 @@ public class EarleyParserTest {
SPPFNode
root
=
parser
.
parse
(
str
,
Java14Grammar
.
n_class_declaration
);
assertNotNull
(
root
);
Util
.
dumpParseResult
(
"testJava2-bt.dot"
,
root
,
g
);
SPPFDebinarizeVisitor
dbv
=
new
SPPFDebinarizeVisitor
();
dbv
.
visit
(
root
);
Util
.
dumpParseResult
(
"testJava2.dot"
,
root
,
g
);
}
}
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