summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/list/scalac.lst1
-rw-r--r--sources/scala/runtime/matching/Grammar.scala6
-rw-r--r--sources/scala/runtime/matching/Matcher.scala86
-rw-r--r--sources/scala/tools/scalac/transformer/TransMatch.scala9
-rw-r--r--sources/scala/tools/scalac/transformer/matching/FullRegularTranslator.scala15
-rw-r--r--sources/scala/tools/scalac/transformer/matching/MutableGrammar.scala4
-rw-r--r--sources/scala/xml/Text.scala1
-rw-r--r--sources/scala/xml/Utility.scala6
8 files changed, 56 insertions, 72 deletions
diff --git a/config/list/scalac.lst b/config/list/scalac.lst
index cdda5bf963..23885206ac 100644
--- a/config/list/scalac.lst
+++ b/config/list/scalac.lst
@@ -23,6 +23,7 @@ ast/printer/TextTreePrinter.scala
transformer/TransMatch.scala
transformer/TransMatchPhase.scala
transformer/matching/FullRegularTranslator.scala
+transformer/matching/GrammarPrinter.scala
transformer/matching/MutableGrammar.scala
transformer/matching/PatternTest.scala
transformer/matching/PatternInfo.scala
diff --git a/sources/scala/runtime/matching/Grammar.scala b/sources/scala/runtime/matching/Grammar.scala
index 8097efa141..89fdc0c12a 100644
--- a/sources/scala/runtime/matching/Grammar.scala
+++ b/sources/scala/runtime/matching/Grammar.scala
@@ -8,15 +8,16 @@ import scala.collection.mutable;
//val ruleOrder = new Order( rule_smaller, rule_eq );
/** runtime representation of patterns. This class treats all variable
* indices as sequence variables
+ * @caseVars an array, field i holding the number of variables in case i
*/
abstract class Grammar( theTreeTransitions:Map[Int,Set[TRule]],
theHedgeTransitions:Map[Int,Set[HRule]],
- caseVars:Array[Int] ) {
+ theVars:Array[Int] ) {
final val treeTransitions = theTreeTransitions ;
final val hedgeTransitions = theHedgeTransitions ;
/** for cases 1..n, holds max. variable index */
- final val vars = caseVars;
+ final val vars = theVars;
val treeInitials:Set[TreeNT] ;
val hedgeInitials:Set[HedgeNT] ;
@@ -24,4 +25,5 @@ abstract class Grammar( theTreeTransitions:Map[Int,Set[TRule]],
def test( test:int, inp:Any ):boolean ;
final def isSequenceType = treeInitials.isEmpty;
+
}
diff --git a/sources/scala/runtime/matching/Matcher.scala b/sources/scala/runtime/matching/Matcher.scala
index 140a1e034a..ae60f2bbd9 100644
--- a/sources/scala/runtime/matching/Matcher.scala
+++ b/sources/scala/runtime/matching/Matcher.scala
@@ -5,8 +5,11 @@ import scala.collection.Map;
import scala.collection.mutable;
import scala.collection.immutable ;
-/** this class matches input against a grammar
- */
+/** this class matches input against a grammar. A call to matchesT (matchesH)
+** returns the list of initial tree (hedge) nonterminals that generate the
+** input.
+** @author Burak Emir
+**/
class Matcher( pgram:Grammar ) {
val treeTransitions = pgram.treeTransitions;
@@ -18,63 +21,25 @@ class Matcher( pgram:Grammar ) {
/** convenience method */
def singH( H:HedgeNT ) = immutable.ListSet.Empty[HedgeNT] + H;
- /** precond: !hedgeInitials.empty
- protected def firstT( n:TreeNT ) = {
- var k = 0;
- val it = pgram.treeInitials.elements;
- var nn = it.next;
- while( it.hasNext && nn != n ) { // pitfall, don't use "for"
- k = k + 1;
- nn = it.next;
- };
- k
- }
- **/
-
- /** precond: !it.empty
- **/
- def first( ns:Iterator[NonTerm], it:Iterator[NonTerm] ):Int =
- if( !ns.hasNext )
- -1
- else {
- val n = ns.next;
- var k = 0;
- var nn = it.next;
- while( it.hasNext && nn != n ) {
- k = k + 1;
- nn = it.next;
- };
- k
- }
-
-
/** top-level call
+ ** @todo remove sanity check
** @return index of the first applicable nonterminal in initials
**/
- def matches( input:Any ):Int = if( pgram.isSequenceType ) {
- input match {
- case h:Seq[Any] =>
- val m = isApplicableHedge( pgram.hedgeInitials, h.elements ).elements;
- val it = pgram.hedgeInitials.elements ;
- first( m, it );
- case _ => error("trying to match tree against hedge grammar");
- }
- } else {
- val m = isApplicableTree( pgram.treeInitials, input ).elements;
- val it = pgram.treeInitials.elements ;
- first( m, it );
- }
+ def matchesT( input:Any ):Iterator[TreeNT] =
+ if( !pgram.isSequenceType )
+ isApplicableTree( pgram.treeInitials, input ).elements;
+ else
+ error("trying to match hedge against tree grammar");
/** top-level call
- def isApplicableTree( t:Any ):immutable.Set[TreeNT] =
- isApplicableTree( pgram.treeInitials, t );
- **/
-
- /** top-level call
- def isApplicableHedge( h:Seq[Any] ):immutable.Set[HedgeNT] =
- isApplicableHedge( pgram.hedgeInitials, h );
+ ** @todo remove sanity check
+ ** @return index of the first applicable nonterminal in initials
**/
-
+ def matchesH( h:Seq[Any] ):Iterator[HedgeNT] =
+ if( pgram.isSequenceType )
+ isApplicableHedge( pgram.hedgeInitials, h.elements ).elements;
+ else
+ error("trying to match tree against hedge grammar");
/** top-level call
**/
@@ -163,16 +128,13 @@ class Matcher( pgram:Grammar ) {
} else {
val first = it.next;
-
var treeNTs = immutable.ListSet.Empty[TreeNT];
- //val initialNTs2 = followChainRules( initialNTs, hedgeRules ); // ?!
- val initialNTs2 = initialNTs; // should work...
- for( val h <- initialNTs2 ) {
+
+ for( val h <- initialNTs ) {
for( val rule <- hedgeTransitions( h.i ) ) {
/* all non-empty rules that start with some H in initialHedgeNTs */
- val H = h;
rule match {
- case HedgeRule( H, treeNT , _ )=> {
+ case HedgeRule( _, treeNT , _ ) => {
treeNTs = treeNTs + treeNT
}
case _ =>
@@ -182,7 +144,7 @@ class Matcher( pgram:Grammar ) {
val applTreeNTs = isApplicableTree( treeNTs, first );
var nextHedgeNTs = immutable.ListSet.Empty[HedgeNT];
- for( val h <- initialNTs2;
+ for( val h <- initialNTs;
val rule <- hedgeTransitions( h.i ) ) {
/* all non-empty rules that start with some H in initialHedgeNTs */
rule match {
@@ -199,12 +161,12 @@ class Matcher( pgram:Grammar ) {
var applHedgeNTs = immutable.ListSet.Empty[HedgeNT];
for( val nH <- applNextHedgeNTs;
- val h <- initialNTs2;
+ val h <- initialNTs;
val rule <- hedgeTransitions( h.i ) ) {
/* all non-empty rules that start with some H in initialHedgeNTs */
val H = nH;
rule match {
- case HedgeRule( h, treeNT , H ) => {
+ case HedgeRule( _, treeNT , H ) => {
applHedgeNTs = applHedgeNTs + h
}
case _ =>
diff --git a/sources/scala/tools/scalac/transformer/TransMatch.scala b/sources/scala/tools/scalac/transformer/TransMatch.scala
index b541ca8682..7db465b037 100644
--- a/sources/scala/tools/scalac/transformer/TransMatch.scala
+++ b/sources/scala/tools/scalac/transformer/TransMatch.scala
@@ -21,6 +21,7 @@ import scalac.transformer.matching.PartialMatcher ;
import scalac.transformer.matching.PatternMatcher ;
import scalac.transformer.matching.TestRegTraverser ;
import scalac.transformer.matching.AlgebraicMatcher ;
+
/** A transformer for expanding match expressions into
* flat sequences of .is and .as method calls
*
@@ -29,6 +30,9 @@ import scalac.transformer.matching.AlgebraicMatcher ;
*/
package scala.tools.scalac.transformer {
+import matching.FullRegularTranslator ;
+import matching.GrammarPrinter ; //DEBUG
+
class TransMatch( global:scalac_Global )
extends scalac_transformer_OwnerTransformer( global ) {
@@ -41,7 +45,10 @@ class TransMatch( global:scalac_Global )
def transform( root:Tree, cases:Array[Tree$CaseDef], restpe:Type ):Tree = {
if( global.newMatch ) {
- throw new ApplicationError("not implemented");
+ val fm = new FullRegularTranslator( global );
+ val gram = fm.MakeGrammar( scala.Iterator.fromArray( cases ) );
+ Console.println( GrammarPrinter.toString( gram ));
+ throw new ApplicationError("not impl.");
};
var containsReg = false;
var i = 0;
diff --git a/sources/scala/tools/scalac/transformer/matching/FullRegularTranslator.scala b/sources/scala/tools/scalac/transformer/matching/FullRegularTranslator.scala
index f1ea6a9f69..8da5bec966 100644
--- a/sources/scala/tools/scalac/transformer/matching/FullRegularTranslator.scala
+++ b/sources/scala/tools/scalac/transformer/matching/FullRegularTranslator.scala
@@ -80,15 +80,16 @@ class FullRegularTranslator(global: scalac_Global) {
/**
* precondition: p.length > 0
*/
- def MakeGrammar( p:Tree* ):Grammar = {
- val it = p.elements;
+ def MakeGrammar( it:Iterator[Tree$CaseDef] ):Grammar = {
var k = 0;
cur = InitialGrammar.make;
while( it.hasNext )
- translate( it.next, { k = k + 1; k } );
+ translate( it.next.pat, { k = k + 1; k } );
cur.toGrammar;
}
+ /** p must be a pattern
+ */
protected def translate( p:Tree, k:Int ):unit = {
this.varCounter = 0;
@@ -97,7 +98,13 @@ class FullRegularTranslator(global: scalac_Global) {
MakeHedgeRule( cur.make.initialHedgeNT, EMPTYHEDGE, emptyVars, p );
} else {
this.isSequenceType = false;
- MakeTreeRule( cur.make.initialTreeNT, emptyVars, p );
+ val in = cur.make.initialTreeNT;
+ try {
+ MakeTreeRule( in, emptyVars, p );
+ } catch {
+ case _:WildcardException =>
+ cur.treeRules += new AnyTreeRule( in );
+ }
}
if( global.debug ) {
diff --git a/sources/scala/tools/scalac/transformer/matching/MutableGrammar.scala b/sources/scala/tools/scalac/transformer/matching/MutableGrammar.scala
index d8c20a3218..fa6ae97b68 100644
--- a/sources/scala/tools/scalac/transformer/matching/MutableGrammar.scala
+++ b/sources/scala/tools/scalac/transformer/matching/MutableGrammar.scala
@@ -108,8 +108,10 @@ case class MutableGrammar( treeRules:mutable.Set[TRule],
tmp.update( 0, immutable.ListSet.Empty[HRule] );
};
val theCaseVars = new Array[Int]( caseVars.size );
+ var i = 0;
for( val k <- caseVars.keys ) {
- theCaseVars( k ) = caseVars( k );
+ theCaseVars( i ) = caseVars( k );
+ i = i + 1
}
new Grammar( treeTransitions, hedgeTransitions, theCaseVars ) {
val treeInitials = make.treeInitials;
diff --git a/sources/scala/xml/Text.scala b/sources/scala/xml/Text.scala
index 4c9ecebfe6..484ef22d78 100644
--- a/sources/scala/xml/Text.scala
+++ b/sources/scala/xml/Text.scala
@@ -9,6 +9,7 @@
package scala.xml;
+
/** an XML node for text (PCDATA). Used in both non-bound and bound XML
* representations
* @author Burak Emir
diff --git a/sources/scala/xml/Utility.scala b/sources/scala/xml/Utility.scala
index a58d7b2bed..269aa983de 100644
--- a/sources/scala/xml/Utility.scala
+++ b/sources/scala/xml/Utility.scala
@@ -12,12 +12,14 @@ package scala.xml ;
import java.lang.StringBuffer ; /* Java dependency! */
import scala.collection.Map ;
-/** Utility functions for processing instances of bound and not bound XML classes,
-** as well as escaping text nodes
+/** Utility functions for processing instances of bound and not bound XML
+** classes, as well as escaping text nodes
**/
object Utility {
+ def view( s:String ):Text = Text( s );
+
/** representation of text in a string that is well-formed XML.
** the characters &lt; &gt; &amp; and &quot; are escaped
*/