diff options
-rw-r--r-- | config/list/scalac.lst | 1 | ||||
-rw-r--r-- | sources/scala/runtime/matching/Grammar.scala | 6 | ||||
-rw-r--r-- | sources/scala/runtime/matching/Matcher.scala | 86 | ||||
-rw-r--r-- | sources/scala/tools/scalac/transformer/TransMatch.scala | 9 | ||||
-rw-r--r-- | sources/scala/tools/scalac/transformer/matching/FullRegularTranslator.scala | 15 | ||||
-rw-r--r-- | sources/scala/tools/scalac/transformer/matching/MutableGrammar.scala | 4 | ||||
-rw-r--r-- | sources/scala/xml/Text.scala | 1 | ||||
-rw-r--r-- | sources/scala/xml/Utility.scala | 6 |
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 < > & and " are escaped */ |