Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Michael Schwarz
CUP Eclipse Plugin
Commits
69166194
Commit
69166194
authored
Feb 23, 2016
by
Michael Schwarz
🤔
Browse files
graph structure for reduce/reduce
parent
9b79d4cf
Changes
3
Hide whitespace changes
Inline
Side-by-side
CupPlugin/src/de/tum/in/www2/cupplugin/views/GraphHelper.java
View file @
69166194
...
...
@@ -3,10 +3,13 @@ import java.util.Collections;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.Stack
;
import
java.util.Map.Entry
;
import
de.in.tum.www2.cup.internal.terminal
;
public
class
GraphHelper
<
X
>
{
// Edges are stored in reverse order (i.e. there is a edge from a to b iff b has a explicit
// higher precedence / order in general than a
...
...
CupPlugin/src/de/tum/in/www2/cupplugin/views/PrecedenceToInsert.java
View file @
69166194
...
...
@@ -22,6 +22,7 @@ class PrecedenceToInsert extends GraphHelper<terminal>{
private
Pair
<
terminal
,
terminal
>
originalEdge
;
private
LinkedList
<
Pair
<
terminal
,
Precedence
.
Type
>>
result
;
// Exception can not be moved to GraphHelper as that is generic and because Java
class
PrecedenceCyclicException
extends
Exception
{
/**
* Every Exception is expected to have one of those
...
...
CupPlugin/src/de/tum/in/www2/cupplugin/views/ReordersToDo.java
View file @
69166194
package
de.tum.in.www2.cupplugin.views
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Stack
;
import
java.util.Map.Entry
;
import
de.in.tum.www2.cup.ast.Precedence
;
import
de.in.tum.www2.cup.internal.internal_error
;
import
de.in.tum.www2.cup.internal.lalr_item
;
import
de.in.tum.www2.cup.internal.lr_item_core
;
import
de.in.tum.www2.cup.internal.terminal
;
import
de.tum.in.www2.cupplugin.Pair
;
import
de.tum.in.www2.cupplugin.views.GraphHelper.TarjanNodeInfo
;
import
de.tum.in.www2.cupplugin.views.PrecedenceToInsert.PrecedenceCyclicException
;
public
class
ReordersToDo
extends
GraphHelper
<
lr_item_core
>{
private
LinkedList
<
lr_item_core
>
result
;
public
ReordersToDo
(){
edges
=
new
HashMap
<>();
}
class
OrderCyclicException
extends
Exception
{
/**
* Every Exception is expected to have one of those
*/
private
static
final
long
serialVersionUID
=
-
3346362877376712162L
;
private
List
<
lr_item_core
>
cycle
;
public
OrderCyclicException
(
String
s
,
List
<
lr_item_core
>
cycle
){
super
(
s
);
this
.
cycle
=
cycle
;
}
public
String
cycleToString
(){
//Works because the cycle is guaranteed to have at least 3 elements
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
cycle
.
get
(
0
).
toString
());
sb
.
append
(
" ->"
);
for
(
int
i
=
1
;
i
<
cycle
.
size
()-
1
;
i
++){
sb
.
append
(
" "
);
sb
.
append
(
cycle
.
get
(
i
).
toString
());
sb
.
append
(
" ->"
);
}
sb
.
append
(
" "
);
sb
.
append
(
cycle
.
get
(
cycle
.
size
()-
1
).
toString
());
return
sb
.
toString
();
}
}
// These crazy many overriden versions are necessary because otherwise the lalr_items will
// be put into the set, and their equals checks the lookahead set but we don't want that
...
...
@@ -49,11 +97,99 @@ public class ReordersToDo extends GraphHelper<lr_item_core>{
}
}
private
boolean
isHigher
(
lr_item_core
high
,
lr_item_core
low
){
public
void
insertOrder
(
lr_item_core
higher
,
lr_item_core
lower
)
throws
OrderCyclicException
{
boolean
addedHigher
=
false
,
addedLower
=
false
;
if
(!
edges
.
containsKey
(
higher
)){
edges
.
put
(
higher
,
new
HashSet
<>());
addedHigher
=
true
;
}
if
(!
edges
.
containsKey
(
lower
)){
edges
.
put
(
lower
,
new
HashSet
<>());
addedLower
=
true
;
}
edges
.
get
(
lower
).
add
(
higher
);
if
(!
isAcyclic
()){
//Do rollback
edges
.
get
(
lower
).
remove
(
higher
);
if
(
addedHigher
){
edges
.
remove
(
higher
);
}
if
(
addedLower
){
edges
.
remove
(
lower
);
}
throw
new
OrderCyclicException
(
""
,
cycle
);
}
}
public
void
insertOrder
(
lalr_item
higher
,
lalr_item
lower
)
throws
OrderCyclicException
{
try
{
insertOrder
(
new
lr_item_core
(
higher
.
the_production
(),
higher
.
dot_pos
()),
new
lr_item_core
(
lower
.
the_production
(),
lower
.
dot_pos
()));
}
catch
(
internal_error
e
)
{
return
;
}
}
private
boolean
isHigher
(
lr_item_core
high
,
lr_item_core
low
){
if
(!
edges
.
containsKey
(
high
)
||
!
edges
.
containsKey
(
low
)){
return
false
;
}
return
isReachable
(
low
,
high
);
}
private
void
topSort
(){
result
=
new
LinkedList
<>();
tarjanNodeInfos
=
new
HashMap
<>();
tarjanStack
=
new
Stack
<>();
for
(
lr_item_core
t
:
edges
.
keySet
()){
TarjanNodeInfo
tni
=
new
TarjanNodeInfo
();
tni
.
onStack
=
false
;
tni
.
index
=
-
1
;
tni
.
lowlink
=
-
1
;
tarjanNodeInfos
.
put
(
t
,
tni
);
}
for
(
Entry
<
lr_item_core
,
TarjanNodeInfo
>
e
:
tarjanNodeInfos
.
entrySet
()){
if
(
e
.
getValue
().
index
==
-
1
){
topSortVisit
(
e
.
getKey
());
}
}
}
private
void
topSortVisit
(
lr_item_core
t
){
if
(
tarjanNodeInfos
.
get
(
t
).
onStack
){
throw
new
IllegalStateException
(
"Expected result to be acyclic."
);
}
if
(
tarjanNodeInfos
.
get
(
t
).
index
==
-
1
){
tarjanNodeInfos
.
get
(
t
).
onStack
=
true
;
for
(
lr_item_core
succ
:
edges
.
get
(
t
)){
topSortVisit
(
succ
);
}
tarjanNodeInfos
.
get
(
t
).
index
=
1
;
tarjanNodeInfos
.
get
(
t
).
onStack
=
false
;
result
.
addFirst
(
t
);
}
}
public
List
<
lr_item_core
>
getItemsOrdered
()
throws
OrderCyclicException
{
if
(!
isAcyclic
()){
throw
new
OrderCyclicException
(
""
,
cycle
);
}
topSort
();
return
result
;
}
}
Write
Preview
Supports
Markdown
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