1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
// $Id$
package scala.runtime.matching ;
/* hedge grammar rules */
abstract class Rule extends Ordered[Rule] {
def compareTo [b >: Rule <% Ordered[b]](that: b): int = that match {
case r:Rule =>
if( rule_smaller( this, r ) )
-1
else if( rule_eq( this, r ) )
0
else
1
case _ => -(that compareTo this)
}
final def rule_smaller( r1:Rule, r2:Rule ):boolean = r1 match {
case HedgeRule( h1, _, hh1 ) => r2 match {
case HedgeRule( h2, _, hh2 ) =>
((h1 == h2)&&( hh1.i < hh2.i )) || h1.i < h2.i;
case HedgeChainRule( h2, hh2 ) =>
((h1 == h2)&&( hh1.i < hh2.i )) || h1.i < h2.i;
case _ => false;
}
case HedgeChainRule( h1, hh1 ) => r2 match {
case HedgeRule( h2, _, hh2 ) =>
((h1 == h2)&&( hh1.i < hh2.i )) || h1.i < h2.i;
case HedgeChainRule( h2, hh2 ) =>
((h1 == h2)&&( hh1.i < hh2.i )) || h1.i < h2.i;
case _ => false;
}
case TreeRule( t1, _, hh1 ) => r2 match {
case TreeRule( t2, _, hh2 ) =>
((t1 == t2 )&&(hh1.i < hh2.i )) || t1.i < t2.i;
case AnyTreeRule( t2 ) => false;
case AnyNodeRule( t2, hh2 ) =>
((t1 == t2 )&&(hh1.i < hh2.i )) || t1.i < t2.i;
case _ => true;
}
case AnyTreeRule( t1 ) => r2 match {
case TreeRule( _, _ , _ ) => true;
case AnyTreeRule( t2 ) => t1.i < t2.i;
case AnyNodeRule( t2, _ ) => true
case _ => true;
}
case AnyNodeRule( t1, hh1 ) => r2 match {
case TreeRule( t2, _, hh2 ) =>
((t1 == t2 )&&(hh1.i < hh2.i )) || t1.i < t2.i;
case AnyTreeRule( t2 ) => false;
case AnyNodeRule( t2, hh2 ) =>
((t1 == t2 )&&(hh1.i < hh2.i )) || t1.i < t2.i;
case _ => true;
}
};
final def rule_eq( r1:Rule, r2:Rule ):boolean = r1 == r2;
override def toString() = this match {
case HedgeChainRule( n, m ) =>
n.toString()+" ::= "+m.toString();
case TreeRule( n, label, n2 ) =>
(n.toString()+{ if( !n.vset.isEmpty ) n.vset.toString() else "" }+
" ::= "+label+"( "+n2.toString()+{if( n2.nullable ) "~" else ""}+" )")
case AnyTreeRule( n ) =>
n.toString()+{ if( !n.vset.isEmpty ) n.vset.toString() else "" }+" ::= _ ";
case AnyNodeRule( n, h ) =>
n.toString()+{ if( !n.vset.isEmpty ) n.vset.toString() else "" }+" ::= _ ( "+h.toString()+" )";
case HedgeRule( n, t, h ) =>
n.toString()+(
if( n.nullable ) "~" else " "
)+" ::= "+(
if( t == ANYTREE ) "_" else t.toString()
)+" "+h.toString();
}
}
abstract class TRule extends Rule;
abstract class HRule extends Rule;
/*
a tree rule is of the from A -> s(B)
where A,B are TreeNTs and s is an identifier (string).
If s is the empty string, then the node label is arbitrary
If HedgeNT is AnyHedgeNT, then the tree is arbitrary
*/
case class HedgeChainRule( n: HedgeNT, rhs: HedgeNT ) extends HRule;
case class TreeRule( n:TreeNT, test:Int, h:HedgeNT ) extends TRule {
def this(i:Int, s:Int, n:Int ) = {
this( new TreeNT(i), s, new HedgeNT(n));
}
};
case class AnyTreeRule( n:TreeNT ) extends TRule {
}
case class AnyNodeRule( n:TreeNT, h:HedgeNT ) extends TRule {
}
case class HedgeRule( n:HedgeNT, t:TreeNT, h:HedgeNT ) extends HRule;
|