Skip to content

Commit 6727731

Browse files
authored
Fix reserved parser keyword error reporting (#869)
* adds bug witness * fixes InformativeErrorListener to report 'proof' as a reserved word
1 parent 00dd498 commit 6727731

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

src/main/antlr4/GobraLexer.g4

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ DECIMAL_FLOAT_LIT : DECIMALS ('.'{_input.LA(1) != '.'}? DECIMALS? EXPONENT?
1717
// ->mode(NLSEMI) means line breaks directly after this token
1818
// emit a semicolon. (just like after identifiers, literals, ')}]' etc in base Go)
1919

20+
// NOTE: if you prepend a new token, do not forget to update InformativeErrorListener.FIRST_GOBRA_TOKEN
2021
TRUE : 'true' -> mode(NLSEMI);
2122
FALSE : 'false' -> mode(NLSEMI);
2223
ASSERT : 'assert';
@@ -93,4 +94,5 @@ GHOST_NOT_EQUALS : '!==';
9394
WITH : 'with';
9495
OPAQUE : 'opaque' -> mode(NLSEMI);
9596
REVEAL : 'reveal';
96-
BACKEND : '#backend';
97+
BACKEND : '#backend';
98+
// NOTE: if you append a new token, do not forget to update InformativeErrorListener.LAST_GOBRA_TOKEN

src/main/scala/viper/gobra/frontend/InformativeErrorListener.scala

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ import scala.collection.mutable.ListBuffer
2020

2121
class InformativeErrorListener(val messages: ListBuffer[ParserError], val source: Source) extends BaseErrorListener {
2222

23+
/**
24+
* First token that Gobra introduces that is not present in Go.
25+
* First refers to the order of token declarations in GobraLexer.g4
26+
* as this order is preserved by ANTLR4 when generating GobraParser.java
27+
*/
28+
private val FIRST_GOBRA_TOKEN = GobraParser.TRUE
29+
/**
30+
* Last token that Gobra introduces that is not present in Go.
31+
* Last refers to the order of token declarations in GobraLexer.g4
32+
* this order is preserved by ANTLR4 when generating GobraParser.java
33+
*/
34+
private val LAST_GOBRA_TOKEN = GobraParser.BACKEND
35+
2336
/**
2437
*
2538
* @param recognizer The recognizer that encountered the error
@@ -314,5 +327,5 @@ class InformativeErrorListener(val messages: ListBuffer[ParserError], val source
314327
}
315328

316329
// All tokens reserved by gobra, but not by Go
317-
val new_reserved = IntervalSet.of(GobraParser.TRUE, GobraParser.TRUSTED)
330+
val new_reserved = IntervalSet.of(FIRST_GOBRA_TOKEN, LAST_GOBRA_TOKEN)
318331
}

src/test/scala/viper/gobra/parsing/ParserUnitTests.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.scalatest.exceptions.TestFailedException
1111
import org.scalatest.funsuite.AnyFunSuite
1212
import org.scalatest.matchers.should.Matchers
1313
import viper.gobra.ast.frontend._
14+
import viper.gobra.reporting.ParserError
1415
import viper.gobra.util.{Decimal, Hexadecimal}
1516

1617
class ParserUnitTests extends AnyFunSuite with Matchers with Inside {
@@ -2721,4 +2722,10 @@ class ParserUnitTests extends AnyFunSuite with Matchers with Inside {
27212722
case Vector(PExplicitGhostMember(PTypeDef(PExplicitGhostStructType(PStructType(Vector(PFieldDecls(Vector(PFieldDecl(PIdnDef("Value"), PIntType())))))), PIdnDef("MyStruct")))) =>
27222723
}
27232724
}
2725+
2726+
test("Parser: should point out that 'proof' is a reserved word") {
2727+
frontend.parseMember("func test(proof ProofType)") should matchPattern {
2728+
case Left(Vector(ParserError(msg, _))) if msg contains "Unexpected reserved word proof" =>
2729+
}
2730+
}
27242731
}

0 commit comments

Comments
 (0)