Skip to content

Commit c352aa5

Browse files
authored
Merge pull request #702 from viperproject/meilers_better_parse_errors
Slightly better parse errors
2 parents ae28573 + dd7baf1 commit c352aa5

File tree

2 files changed

+29
-31
lines changed

2 files changed

+29
-31
lines changed

src/main/scala/viper/silver/frontend/SilFrontend.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,9 @@ trait SilFrontend extends DefaultFrontend {
274274
}
275275
else Fail(err_list)
276276
case fail @ Parsed.Failure(_, index, _) =>
277-
val msg = fail.trace().longAggregateMsg
277+
val msg = fail.trace().aggregateMsg
278278
val (line, col) = fp.lineCol.getPos(index)
279-
Fail(List(ParseError(s"Expected $msg", SourcePosition(file, line, col))))
279+
Fail(List(ParseError(msg, SourcePosition(file, line, col))))
280280
//? val pos = extra.input.prettyIndex(index).split(":").map(_.toInt)
281281
//? Fail(List(ParseError(s"Expected $msg", SourcePosition(file, pos(0), pos(1)))))
282282
case error: ParseError => Fail(List(error))

src/main/scala/viper/silver/parser/FastParser.scala

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -796,12 +796,12 @@ class FastParser {
796796
// and then look like an `fapp` up untill the `: type` part, after which we need to backtrack all the way back (or error if cut)
797797
def atom(implicit ctx : P[_]) : P[PExp] = P(ParserExtension.newExpAtStart(ctx) | annotatedAtom
798798
| integer | booltrue | boolfalse | nul | old
799-
| result | unExp | typedFapp
799+
| result | unExp | typedFuncApp
800800
| "(" ~ exp ~ ")" | accessPred | inhaleExhale | perm | let | quant | forperm | unfolding | applying
801801
| setTypedEmpty | explicitSetNonEmpty | multiSetTypedEmpty | explicitMultisetNonEmpty | seqTypedEmpty
802802
| size | explicitSeqNonEmpty | seqRange
803803
| mapTypedEmpty | explicitMapNonEmpty | mapDomain | mapRange
804-
| fapp | idnuse | ParserExtension.newExpAtEnd(ctx))
804+
| funcApp | idnuse | ParserExtension.newExpAtEnd(ctx))
805805

806806
def stringLiteral[$: P]: P[String] = P("\"" ~ CharsWhile(_ != '\"').! ~ "\"")
807807

@@ -829,7 +829,7 @@ class FastParser {
829829

830830
def annotationIdentifier[$: P]: P[String] = (CharIn("A-Z", "a-z", "$_") ~~ CharIn("0-9", "A-Z", "a-z", "$_.").repX).!
831831

832-
def ident[$: P]: P[String] = identifier.!.filter(a => !keywords.contains(a)).opaque("invalid identifier (could be a keyword)")
832+
def ident[$: P]: P[String] = identifier.!.filter(a => !keywords.contains(a)).opaque("identifier")
833833

834834
def idnuse[$: P]: P[PIdnUse] = FP(ident).map { case (pos, id) => PIdnUse(id)(pos) }
835835

@@ -851,7 +851,7 @@ class FastParser {
851851
case (pos, (a, b)) => PMagicWandExp(a, b)(pos)
852852
}
853853

854-
def implExp[$: P]: P[PExp] = FP(magicWandExp ~~~ (StringIn("==>").! ~ implExp).lw.?).map {
854+
def implExp[$: P]: P[PExp] = FP(magicWandExp ~~~ ("==>".! ~ implExp).lw.?).map {
855855
case (pos, (a, b)) => b match {
856856
case Some(c) => PBinExp(a, c._1, c._2)(pos)
857857
case None => a
@@ -959,7 +959,7 @@ class FastParser {
959959
case other => sys.error(s"Unexpectedly found $other")
960960
})
961961

962-
def predAcc[$: P]: P[PLocationAccess] = fapp
962+
def predAcc[$: P]: P[PLocationAccess] = funcApp
963963

964964
def actualArgList[$: P]: P[Seq[PExp]] = exp.rep(sep = ",")
965965

@@ -1096,35 +1096,35 @@ class FastParser {
10961096
case (pos, e) => PMapRange(e)(pos)
10971097
})
10981098

1099-
def fapp[$: P]: P[PCall] = FP(idnuse ~ parens(actualArgList)).map {
1099+
def funcApp[$: P]: P[PCall] = FP(idnuse ~ parens(actualArgList)).map {
11001100
case (pos, (func, args)) =>
11011101
PCall(func, args, None)(pos)
11021102
}
11031103

1104-
def typedFapp[$: P]: P[PExp] = FP(parens(idnuse ~ parens(actualArgList) ~ ":" ~ typ)).map {
1104+
def typedFuncApp[$: P]: P[PExp] = FP(parens(idnuse ~ parens(actualArgList) ~ ":" ~ typ)).map {
11051105
case (pos, (func, args, typeGiven)) => PCall(func, args, Some(typeGiven))(pos)
11061106
}
11071107

11081108
def stmt(implicit ctx : P[_]) : P[PStmt] = P(ParserExtension.newStmtAtStart(ctx) | annotatedStmt |
1109-
macroassign | fieldassign | localassign | fold | unfold | exhale | assertP |
1110-
inhale | assume | ifthnels | whle | varDecl | defineDecl | newstmt |
1111-
methodCall | goto | lbl | packageWand | applyWand | macroref | block |
1109+
macroassign | fieldassign | localassign | fold | unfold | exhale | assertStmt |
1110+
inhale | assume | ifThenElse | whileStmt | varDecl | defineDecl | newstmt |
1111+
methodCall | goto | label | packageWand | applyWand | macroref | block |
11121112
quasihavoc | quasihavocall | ParserExtension.newStmtAtEnd(ctx))
11131113

11141114
def annotatedStmt(implicit ctx : P[_]): P[PStmt] = (FP(annotation ~ stmt).map{
11151115
case (pos, (key, value, pStmt)) => PAnnotatedStmt(pStmt, (key, value))(pos)
11161116
})
11171117

1118-
def nodefinestmt(implicit ctx : P[_]) : P[PStmt] = P(ParserExtension.newStmtAtStart(ctx) | fieldassign | localassign | fold | unfold | exhale | assertP |
1119-
inhale | assume | ifthnels | whle | varDecl | newstmt |
1120-
methodCall | goto | lbl | packageWand | applyWand | macroref | block |
1118+
def nodefinestmt(implicit ctx : P[_]) : P[PStmt] = P(ParserExtension.newStmtAtStart(ctx) | fieldassign | localassign | fold | unfold | exhale | assertStmt |
1119+
inhale | assume | ifThenElse | whileStmt | varDecl | newstmt |
1120+
methodCall | goto | label | packageWand | applyWand | macroref | block |
11211121
quasihavoc | quasihavocall | ParserExtension.newStmtAtEnd(ctx))
11221122

11231123
def macroref[$: P]: P[PMacroRef] = FP(idnuse).map { case (pos, a) => PMacroRef(a)(pos) }
11241124

11251125
def fieldassign[$: P]: P[PFieldAssign] = FP(fieldAcc ~ ":=" ~ exp).map { case (pos, (a, b)) => PFieldAssign(a, b)(pos) }
11261126

1127-
def macroassign[$: P]: P[PMacroAssign] = FP(NoCut(fapp) ~ ":=" ~ exp).map { case (pos, (call, exp)) => PMacroAssign(call, exp)(pos) }
1127+
def macroassign[$: P]: P[PMacroAssign] = FP(NoCut(funcApp) ~ ":=" ~ exp).map { case (pos, (call, exp)) => PMacroAssign(call, exp)(pos) }
11281128

11291129
def localassign[$: P]: P[PVarAssign] = FP(idnuse ~ ":=" ~ exp).map { case (pos, (a, b)) => PVarAssign(a, b)(pos) }
11301130

@@ -1134,7 +1134,7 @@ class FastParser {
11341134

11351135
def exhale[$: P]: P[PExhale] = FP(keyword("exhale") ~/ exp).map{ case (pos, e) => PExhale(e)(pos) }
11361136

1137-
def assertP[$: P]: P[PAssert] = FP(keyword("assert") ~/ exp).map{ case (pos, e) => PAssert(e)(pos) }
1137+
def assertStmt[$: P]: P[PAssert] = FP(keyword("assert") ~/ exp).map{ case (pos, e) => PAssert(e)(pos) }
11381138

11391139
def inhale[$: P]: P[PInhale] = FP(keyword("inhale") ~/ exp).map{ case (pos, e) => PInhale(e)(pos) }
11401140

@@ -1162,29 +1162,29 @@ class FastParser {
11621162
case (pos, (vars, lhs, rhs)) => PQuasihavocall(vars, lhs, rhs)(pos)
11631163
}
11641164

1165-
def ifthnels[$: P]: P[PIf] = FP("if" ~ "(" ~ exp ~ ")" ~ block ~~~ elsifEls).map {
1165+
def ifThenElse[$: P]: P[PIf] = FP("if" ~ "(" ~ exp ~ ")" ~ block ~~~ elseIfOrElse).map {
11661166
case (pos, (cond, thn, ele)) => PIf(cond, thn, ele)(pos)
11671167
}
11681168

11691169
// No need for `.lw` here since we have `FP("{" ~ ... ~ "}")`
11701170
def block[$: P]: P[PSeqn] = FP("{" ~/ (stmt ~/ ";".?).rep ~ "}").map{ case (pos, e) => PSeqn(e)(pos)}
11711171

1172-
def elsifEls[$: P]: LW[PSeqn] = elsif.lw | els
1172+
def elseIfOrElse[$: P]: LW[PSeqn] = elseIf.lw | elseBlock
11731173

1174-
def elsif[$: P]: P[PSeqn] = FP("elseif" ~/ "(" ~ exp ~ ")" ~ block ~~~ elsifEls).map {
1174+
def elseIf[$: P]: P[PSeqn] = FP("elseif" ~/ "(" ~ exp ~ ")" ~ block ~~~ elseIfOrElse).map {
11751175
case (pos, (cond, thn, ele)) => PSeqn(Seq(PIf(cond, thn, ele)(pos)))(pos)
11761176
}
11771177

1178-
def els[$: P]: LW[PSeqn] = ((keyword("else") ~/ block) | FP(Pass).map {
1178+
def elseBlock[$: P]: LW[PSeqn] = ((keyword("else") ~/ block) | FP(Pass).map {
11791179
case (pos, _) => PSeqn(Nil)(pos)
11801180
}).lw
11811181

1182-
def whle[$: P]: P[PWhile] = FP(keyword("while") ~/ "(" ~ exp ~ ")" ~ inv.rep ~ block).map {
1182+
def whileStmt[$: P]: P[PWhile] = FP(keyword("while") ~/ "(" ~ exp ~ ")" ~ invariant.rep ~ block).map {
11831183
case (pos, (cond, invs, body)) =>
11841184
PWhile(cond, invs, body)(pos)
11851185
}
11861186

1187-
def inv(implicit ctx : P[_]) : P[PExp] = P((keyword("invariant") ~ exp ~~~ ";".lw.?) | ParserExtension.invSpecification(ctx))
1187+
def invariant(implicit ctx : P[_]) : P[PExp] = P((keyword("invariant") ~ exp ~~~ ";".lw.?) | ParserExtension.invSpecification(ctx))
11881188

11891189
def varDecl[$: P]: P[PLocalVarDecl] = FP(keyword("var") ~/ idndef ~ ":" ~ typ ~~~ (":=" ~ exp).lw.?).map { case (pos, (a, b, c)) => PLocalVarDecl(a, b, c)(pos) }
11901190

@@ -1210,7 +1210,7 @@ class FastParser {
12101210

12111211
def goto[$: P]: P[PGoto] = FP("goto" ~/ idnuse).map{ case (pos, e) => PGoto(e)(pos) }
12121212

1213-
def lbl[$: P]: P[PLabel] = FP(keyword("label") ~/ idndef ~~~ (keyword("invariant") ~/ exp).lw.rep).map {
1213+
def label[$: P]: P[PLabel] = FP(keyword("label") ~/ idndef ~~~ (keyword("invariant") ~/ exp).lw.rep).map {
12141214
case (pos, (name, invs)) => PLabel(name, invs)(pos) }
12151215

12161216
def packageWand[$: P]: P[PPackageWand] = FP(keyword("package") ~/ magicWandExp ~~~ block.lw.?).map {
@@ -1291,24 +1291,22 @@ class FastParser {
12911291
case (pos, (anns, a, b)) => PField(a, b)(pos, anns)
12921292
}
12931293

1294-
def functionDecl[$: P]: P[PFunction] = FP(annotation.rep(0) ~ "function" ~/ idndef ~ "(" ~ formalArgList ~ ")" ~ ":" ~ typ ~~~ pre.lw.rep ~~~
1295-
post.lw.rep ~~~ ("{" ~ exp ~ "}").lw.?).map({ case (pos, (anns, a, b, c, d, e, f)) =>
1294+
def functionDecl[$: P]: P[PFunction] = FP(annotation.rep(0) ~ "function" ~/ idndef ~ "(" ~ formalArgList ~ ")" ~ ":" ~ typ ~~~ precondition.lw.rep ~~~
1295+
postcondition.lw.rep ~~~ ("{" ~ exp ~ "}").lw.?).map({ case (pos, (anns, a, b, c, d, e, f)) =>
12961296
PFunction(a, b, c, d, e, f)(pos, anns)
12971297
})
12981298

12991299

1300-
def pre(implicit ctx : P[_]) : P[PExp] = P(("requires" ~/ exp ~~~ ";".lw.?) | ParserExtension.preSpecification(ctx))
1300+
def precondition(implicit ctx : P[_]) : P[PExp] = P(("requires" ~/ exp ~~~ ";".lw.?) | ParserExtension.preSpecification(ctx))
13011301

1302-
def post(implicit ctx : P[_]) : P[PExp] = P(("ensures" ~/ exp ~~~ ";".lw.?) | ParserExtension.postSpecification(ctx))
1303-
1304-
def decCl[$: P]: P[Seq[PExp]] = P(exp.rep(sep = ","))
1302+
def postcondition(implicit ctx : P[_]) : P[PExp] = P(("ensures" ~/ exp ~~~ ";".lw.?) | ParserExtension.postSpecification(ctx))
13051303

13061304
def predicateDecl[$: P]: P[PPredicate] = FP(annotation.rep(0) ~ keyword("predicate") ~/ idndef ~ "(" ~ formalArgList ~ ")" ~~~ ("{" ~ exp ~ "}").lw.?).map {
13071305
case (pos, (anns, a, b, c)) =>
13081306
PPredicate(a, b, c)(pos, anns)
13091307
}
13101308

1311-
def methodDecl[$: P]: P[PMethod] = FP(annotation.rep(0) ~ methodSignature ~~~/ pre.lw.rep ~~~ post.lw.rep ~~~ block.lw.?).map {
1309+
def methodDecl[$: P]: P[PMethod] = FP(annotation.rep(0) ~ methodSignature ~~~/ precondition.lw.rep ~~~ postcondition.lw.rep ~~~ block.lw.?).map {
13121310
case (pos, (anns, (name, args, rets), pres, posts, body)) =>
13131311
PMethod(name, args, rets.getOrElse(Nil), pres, posts, body)(pos, anns)
13141312
}

0 commit comments

Comments
 (0)