diff options
author | Som Snytt <som.snytt@gmail.com> | 2013-10-18 09:15:43 -0700 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2013-11-08 11:09:20 -0800 |
commit | e1fdf86438a6771ff3735a977ca85ba16a99484c (patch) | |
tree | 7e54c69cee84e8bfe427fd8d7de36ce074c4005c | |
parent | ef273e4790528f267655fff147c712941cc7ce1a (diff) | |
download | scala-e1fdf86438a6771ff3735a977ca85ba16a99484c.tar.gz scala-e1fdf86438a6771ff3735a977ca85ba16a99484c.tar.bz2 scala-e1fdf86438a6771ff3735a977ca85ba16a99484c.zip |
Parser stack reduction peekingAhead
Restores a form of the previous peekAhead bookkeeping.
Instead of tracking the current token and offset outside
of xxxAhead, peekingAhead uses `in.prev` and will push
back if the operation results in an empty tree.
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 44 | ||||
-rw-r--r-- | test/files/neg/t421.check | 2 | ||||
-rw-r--r-- | test/files/neg/t5702-neg-bad-brace.check | 11 |
3 files changed, 38 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index fa3302b125..cfa60cabc3 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -284,6 +284,25 @@ self => try body finally in copyFrom saved } + /** Perform an operation while peeking ahead. + * Pushback if the operation yields an empty tree or blows to pieces. + */ + @inline def peekingAhead(tree: =>Tree): Tree = { + @inline def peekahead() = { + in.prev copyFrom in + in.nextToken() + } + @inline def pushback() = { + in.next copyFrom in + in copyFrom in.prev + } + peekahead() + // try it, in case it is recoverable + val res = try tree catch { case e: Exception => pushback() ; throw e } + if (res.isEmpty) pushback() + res + } + class ParserTreeBuilder extends TreeBuilder { val global: self.global.type = self.global def unit = parser.unit @@ -1825,26 +1844,23 @@ self => val top = simplePattern(badPattern3) val base = opstack // See SI-3189, SI-4832 for motivation. Cf SI-3480 for counter-motivation. - def peekaheadDelim() = { - def isCloseDelim = in.token match { - case RBRACE => isXML - case RPAREN => !isXML - case _ => false - } - lookingAhead(isCloseDelim) && { in.nextToken() ; true } + def isCloseDelim = in.token match { + case RBRACE => isXML + case RPAREN => !isXML + case _ => false } - def isWildStar = top match { - case Ident(nme.WILDCARD) if isRawStar => peekaheadDelim() - case _ => false + def checkWildStar: Tree = top match { + case Ident(nme.WILDCARD) if isSequenceOK && isRawStar => peekingAhead ( + if (isCloseDelim) atPos(top.pos.start, in.prev.offset)(Star(stripParens(top))) + else EmptyTree + ) + case _ => EmptyTree } def loop(top: Tree): Tree = reducePatternStack(base, top) match { case next if isIdentExcept(raw.BAR) => pushOpInfo(next) ; loop(simplePattern(badPattern3)) case next => next } - if (isSequenceOK && isWildStar) - atPos(top.pos.start, in.prev.offset)(Star(stripParens(top))) - else - stripParens(loop(top)) + checkWildStar orElse stripParens(loop(top)) } def badPattern3(): Tree = { diff --git a/test/files/neg/t421.check b/test/files/neg/t421.check index d16e541868..dc5fa425ac 100644 --- a/test/files/neg/t421.check +++ b/test/files/neg/t421.check @@ -1,4 +1,4 @@ t421.scala:5: error: star patterns must correspond with varargs parameters case Bar("foo",_*) => sys.error("huh?"); - ^ + ^ one error found diff --git a/test/files/neg/t5702-neg-bad-brace.check b/test/files/neg/t5702-neg-bad-brace.check index a4a00814d3..503f7d95ed 100644 --- a/test/files/neg/t5702-neg-bad-brace.check +++ b/test/files/neg/t5702-neg-bad-brace.check @@ -1,7 +1,10 @@ t5702-neg-bad-brace.scala:14: error: Unmatched closing brace '}' ignored here case List(1, _*} => ^ -t5702-neg-bad-brace.scala:17: error: eof expected but '}' found. -} -^ -two errors found +t5702-neg-bad-brace.scala:14: error: illegal start of simple pattern + case List(1, _*} => + ^ +t5702-neg-bad-brace.scala:15: error: ')' expected but '}' found. + } + ^ +three errors found |