diff options
author | buraq <buraq@epfl.ch> | 2003-09-12 13:28:33 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2003-09-12 13:28:33 +0000 |
commit | 9fae25787544009f3fb912b62b23167031432ca1 (patch) | |
tree | 9656e53ba9dc3848324fe7f8d5e8c15d8d82339a | |
parent | ed300578cc4cb55d737372f6e925f940130426fa (diff) | |
download | scala-9fae25787544009f3fb912b62b23167031432ca1.tar.gz scala-9fae25787544009f3fb912b62b23167031432ca1.tar.bz2 scala-9fae25787544009f3fb912b62b23167031432ca1.zip |
better checking of patterns
-rw-r--r-- | sources/scalac/ast/parser/Parser.java | 8 | ||||
-rw-r--r-- | sources/scalac/ast/parser/PatternNormalizer.java | 55 |
2 files changed, 42 insertions, 21 deletions
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java index 51d93a43cb..12eb76dd2c 100644 --- a/sources/scalac/ast/parser/Parser.java +++ b/sources/scalac/ast/parser/Parser.java @@ -1153,13 +1153,12 @@ public class Parser implements Tokens { int pos = s.pos; Tree pat = pattern(); - if( this.pN.check( pat ) ) { // reports syntax errors as side effect // normalize Tree res = pN.wrapAlternative( pN.elimSequence( pN.flattenSequence ( pat ))); return res; } - //syntaxError( pos, "invalid pattern", false ); + //syntaxError( pos, "invalid pattern", false ); done in pN.check... return make.Bad(pos); } @@ -1245,13 +1244,14 @@ public class Parser implements Tokens { } } while ((s.token == IDENTIFIER) && (s.name != BAR)) { + Name tokn = s.name; // for error message top = reduceStack( false, base, top, s.name.precedence(), s.name.isLeftAssoc()); push(top, s.pos, s.name); ident(); top = simplePattern(); if( TreeInfo.isEmptySequence( top ) ) { - syntaxError( top.pos, "empty sequence not allowed here", false); + syntaxError( top.pos, "2nd argument to binary op "+s.name+" may not be empty sequence pattern", false); } } return reduceStack(false, base, top, 0, true); @@ -1688,7 +1688,7 @@ public class Parser implements Tokens { */ Tree patDefOrDcl(int mods) { int pos = s.pos; - Tree pat = pattern(); + Tree pat = validPattern(); Tree tp; switch (pat) { case Typed(Tree pat1, Tree tp1): diff --git a/sources/scalac/ast/parser/PatternNormalizer.java b/sources/scalac/ast/parser/PatternNormalizer.java index c25f821ec9..1a358f859f 100644 --- a/sources/scalac/ast/parser/PatternNormalizer.java +++ b/sources/scalac/ast/parser/PatternNormalizer.java @@ -14,6 +14,8 @@ import scalac.util.Name; import Tree.*; import java.util.HashMap; +import scalac.util.Names; + /** contains algorithms for `checking' and `normalizing' patterns * * @author Burak Emir @@ -48,41 +50,60 @@ public class PatternNormalizer { * inSeq: flag, true if we are in a sequence '[' ... ']' * t: the tree to be checked */ - protected boolean check1( Tree t ) { + protected boolean check1( Tree t, boolean inAlt ) { switch( t ) { case Literal( _ ): return true; case Apply( _, Tree[] args ): - return check1( args ); + return check1( args, inAlt ); case Sequence( Tree[] trees ): - return check1( trees ); + return check1( trees, inAlt ); case Alternative( Tree[] trees ): - return check1( trees ); + return check1( trees, true ); case Bind( Name var, Tree tree ): - this.boundVars.put( t.symbol(), Boolean.FALSE ); - /* + if(( inAlt ) + &&( var.toString().lastIndexOf("$") == -1)) { + + unit.error( t.pos, + "variable binding not allowed under alternative"); + return false; + } + this.boundVars.put( var /*t.symbol()*/, Boolean.FALSE ); + /* boolean result = check( tree, inSeq ); if(((Boolean) this.boundVars.get( t.symbol() )) - .booleanValue()) { // occurs recursively - // do something to RESTRICT recursion + .booleanValue()) { // occurs recursively + // do something to RESTRICT recursion } - */ - return check1( tree ); + */ + return check1( tree, inAlt ); case Typed( _, _): return true; - case Ident( _ ): + case Ident( Name var ): + if(( inAlt ) + &&( var != Names.WILDCARD ) + &&( var.toString().lastIndexOf("$") == -1)) + { + unit.error( t.pos, + "variable not allowed under alternative"); + return false; + } /* System.out.println( t.symbol().toString() ); */ - if( this.boundVars.containsKey( t.symbol() )) { - this.boundVars.put( t.symbol(), Boolean.TRUE ); + if(( this.boundVars.containsKey( var /*t.symbol()*/ )) + &&( var.toString().lastIndexOf("$") == -1)) { + unit.error( t.pos, + "recursive patterns not allowed"); + + //this.boundVars.put( t.symbol(), Boolean.TRUE ); //mark recursive //System.out.println( t.symbol() + "occurs recursively"); } @@ -107,22 +128,22 @@ public class PatternNormalizer { /** checkPat for every tree in array of trees, see below */ - protected boolean check1( Tree[] trees ) { + protected boolean check1( Tree[] trees, boolean inAlt ) { for( int i = 0; i < trees.length; i++ ) - if( !check1( trees[ i ] )) + if( !check1( trees[ i ], inAlt )) return false; return true; } // if this map contains a symbol as a key, it is bound. // if this symbol is mapped to Boolean.True, it occurs recursively - HashMap boundVars; + HashMap/*Name=>Boolean*/ boundVars; /** method */ public boolean check( Tree pat ) { this.boundVars = new HashMap(); - return check1( pat ); + return check1( pat, false ); } |