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
Dr. Michael Petter
CUP Eclipse Plugin
Commits
9b79d4cf
Commit
9b79d4cf
authored
Feb 23, 2016
by
Michael Schwarz
🤔
Browse files
Common superclass for grpah stuff
parent
88e54b1b
Changes
3
Hide whitespace changes
Inline
Side-by-side
CupPlugin/src/de/tum/in/www2/cupplugin/views/GraphHelper.java
View file @
9b79d4cf
package
de.tum.in.www2.cupplugin.views
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.LinkedList
;
import
java.util.Set
;
import
java.util.Stack
;
import
java.util.Map.Entry
;
public
class
GraphHelper
{
public
static
<
X
>
boolean
isReachable
(
HashMap
<
X
,
Set
<
X
>>
edges
,
X
from
,
X
to
){
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
protected
HashMap
<
X
,
Set
<
X
>>
edges
;
public
class
TarjanNodeInfo
{
public
int
index
;
public
boolean
onStack
;
public
int
lowlink
;
}
protected
int
tarjanIndex
;
protected
HashMap
<
X
,
TarjanNodeInfo
>
tarjanNodeInfos
;
protected
Stack
<
X
>
tarjanStack
;
protected
LinkedList
<
X
>
cycle
;
protected
boolean
isReachable
(
X
from
,
X
to
){
HashSet
<
X
>
toCheck
=
new
HashSet
<>();
if
(
edges
.
get
(
from
).
size
()
==
0
){
// if the node has no outgoing node, than nothing is reachable
...
...
@@ -30,4 +50,76 @@ public class GraphHelper {
return
false
;
}
protected
boolean
isAcyclic
(){
tarjanIndex
=
0
;
tarjanNodeInfos
=
new
HashMap
<>();
tarjanStack
=
new
Stack
<>();
for
(
X
t
:
edges
.
keySet
()){
TarjanNodeInfo
tni
=
new
TarjanNodeInfo
();
tni
.
onStack
=
false
;
tni
.
index
=
-
1
;
tni
.
lowlink
=
-
1
;
tarjanNodeInfos
.
put
(
t
,
tni
);
}
cycle
=
new
LinkedList
<>();
for
(
Entry
<
X
,
TarjanNodeInfo
>
e
:
tarjanNodeInfos
.
entrySet
()){
if
(
e
.
getValue
().
index
==
-
1
){
if
(
strongConnect
(
e
.
getKey
())){
return
false
;
}
}
}
return
true
;
}
private
boolean
strongConnect
(
X
t
){
TarjanNodeInfo
node
=
tarjanNodeInfos
.
get
(
t
);
node
.
index
=
tarjanIndex
;
node
.
lowlink
=
tarjanIndex
;
node
.
onStack
=
true
;
tarjanIndex
++;
tarjanStack
.
push
(
t
);
for
(
X
succ
:
edges
.
get
(
t
)){
if
(
tarjanNodeInfos
.
get
(
succ
).
index
==
-
1
){
if
(
strongConnect
(
succ
)){
return
true
;
}
node
.
lowlink
=
Math
.
min
(
node
.
lowlink
,
tarjanNodeInfos
.
get
(
succ
).
lowlink
);
}
else
if
(
tarjanNodeInfos
.
get
(
succ
).
onStack
){
node
.
lowlink
=
Math
.
min
(
node
.
lowlink
,
tarjanNodeInfos
.
get
(
succ
).
index
);
}
}
if
(
node
.
lowlink
==
node
.
index
){
X
w
=
tarjanStack
.
pop
();
tarjanNodeInfos
.
get
(
w
).
onStack
=
false
;
if
(!
w
.
equals
(
t
)){
// Construct cycle
cycle
.
add
(
t
);
cycle
.
add
(
w
);
do
{
w
=
tarjanStack
.
pop
();
cycle
.
add
(
w
);
}
while
(!
w
.
equals
(
t
));
//Cycle is in reverse order of what we want -> Reverse it
Collections
.
reverse
(
cycle
);
return
true
;
}
}
return
false
;
}
}
\ No newline at end of file
CupPlugin/src/de/tum/in/www2/cupplugin/views/PrecedenceToInsert.java
View file @
9b79d4cf
...
...
@@ -10,30 +10,17 @@ import java.util.Stack;
import
java.util.Map.Entry
;
import
de.in.tum.www2.cup.ast.Precedence
;
import
de.in.tum.www2.cup.ast.Precedence.Type
;
import
de.in.tum.www2.cup.internal.terminal
;
import
de.tum.in.www2.cupplugin.Pair
;
import
de.tum.in.www2.cupplugin.views.CupConflictsView.ShiftReduceDetails
;
import
de.tum.in.www2.cupplugin.views.GraphHelper.TarjanNodeInfo
;
class
PrecedenceToInsert
{
class
PrecedenceToInsert
extends
GraphHelper
<
terminal
>
{
private
HashMap
<
terminal
,
Precedence
.
Type
>
precs
=
new
HashMap
<>();
// Edges are stored in reverse order (i.e. there is a edge from a to b iff b has a explicit
// higher precedence than a
private
HashMap
<
terminal
,
Set
<
terminal
>>
edges
=
new
HashMap
<>();
// These need to be inserted whenever an edge that contains the key is to be inserted
private
Pair
<
terminal
,
terminal
>
originalEdge
;
private
int
tarjanIndex
;
private
HashMap
<
terminal
,
TarjanNodeInfo
>
tarjanNodeInfos
;
private
Stack
<
terminal
>
tarjanStack
;
private
class
TarjanNodeInfo
{
public
int
index
;
public
boolean
onStack
;
public
int
lowlink
;
}
private
LinkedList
<
Pair
<
terminal
,
Precedence
.
Type
>>
result
;
class
PrecedenceCyclicException
extends
Exception
{
/**
...
...
@@ -66,9 +53,9 @@ class PrecedenceToInsert {
}
}
p
rivate
LinkedList
<
terminal
>
cycle
;
private
LinkedList
<
Pair
<
terminal
,
Precedence
.
Type
>>
result
;
p
ublic
PrecedenceToInsert
(){
edges
=
new
HashMap
<>();
}
/**
* Returns true iff this conflict would be resolved in favor of Shift by those precs
...
...
@@ -194,77 +181,6 @@ class PrecedenceToInsert {
}
}
private
boolean
isAcyclic
(){
tarjanIndex
=
0
;
tarjanNodeInfos
=
new
HashMap
<>();
tarjanStack
=
new
Stack
<>();
for
(
terminal
t
:
precs
.
keySet
()){
TarjanNodeInfo
tni
=
new
TarjanNodeInfo
();
tni
.
onStack
=
false
;
tni
.
index
=
-
1
;
tni
.
lowlink
=
-
1
;
tarjanNodeInfos
.
put
(
t
,
tni
);
}
cycle
=
new
LinkedList
<>();
for
(
Entry
<
terminal
,
TarjanNodeInfo
>
e
:
tarjanNodeInfos
.
entrySet
()){
if
(
e
.
getValue
().
index
==
-
1
){
if
(
strongConnect
(
e
.
getKey
())){
return
false
;
}
}
}
return
true
;
}
private
boolean
strongConnect
(
terminal
t
){
TarjanNodeInfo
node
=
tarjanNodeInfos
.
get
(
t
);
node
.
index
=
tarjanIndex
;
node
.
lowlink
=
tarjanIndex
;
node
.
onStack
=
true
;
tarjanIndex
++;
tarjanStack
.
push
(
t
);
for
(
terminal
succ
:
edges
.
get
(
t
)){
if
(
tarjanNodeInfos
.
get
(
succ
).
index
==
-
1
){
if
(
strongConnect
(
succ
)){
return
true
;
}
node
.
lowlink
=
Math
.
min
(
node
.
lowlink
,
tarjanNodeInfos
.
get
(
succ
).
lowlink
);
}
else
if
(
tarjanNodeInfos
.
get
(
succ
).
onStack
){
node
.
lowlink
=
Math
.
min
(
node
.
lowlink
,
tarjanNodeInfos
.
get
(
succ
).
index
);
}
}
if
(
node
.
lowlink
==
node
.
index
){
terminal
w
=
tarjanStack
.
pop
();
tarjanNodeInfos
.
get
(
w
).
onStack
=
false
;
if
(!
w
.
equals
(
t
)){
// Construct cycle
cycle
.
add
(
t
);
cycle
.
add
(
w
);
do
{
w
=
tarjanStack
.
pop
();
cycle
.
add
(
w
);
}
while
(!
w
.
equals
(
t
));
//Cycle is in reverse order of what we want -> Reverse it
Collections
.
reverse
(
cycle
);
return
true
;
}
}
return
false
;
}
private
void
topSort
(){
result
=
new
LinkedList
<>();
tarjanNodeInfos
=
new
HashMap
<>();
...
...
@@ -361,7 +277,7 @@ class PrecedenceToInsert {
// This works because we have guarantee that the graph is a DAG
// t reachable from over -> t has higher precedence
return
GraphHelper
.
isReachable
(
edges
,
over
,
t
);
return
isReachable
(
over
,
t
);
}
/**
...
...
CupPlugin/src/de/tum/in/www2/cupplugin/views/ReordersToDo.java
View file @
9b79d4cf
package
de.tum.in.www2.cupplugin.views
;
import
java.util.HashMap
;
import
java.util.Set
;
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
;
public
class
ReordersToDo
{
private
HashMap
<
lr_item_core
,
Set
<
lr_item_core
>>
edges
=
new
HashMap
<>();
public
class
ReordersToDo
extends
GraphHelper
<
lr_item_core
>{
// 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
...
...
@@ -57,6 +54,6 @@ public class ReordersToDo {
return
false
;
}
return
GraphHelper
.
isReachable
(
edges
,
low
,
high
);
return
isReachable
(
low
,
high
);
}
}
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