diff --git a/src/main/wacc/parser.scala b/src/main/wacc/parser.scala index 84ee093..c174845 100644 --- a/src/main/wacc/parser.scala +++ b/src/main/wacc/parser.scala @@ -6,7 +6,8 @@ import parsley.Parsley.{atomic, many, notFollowedBy, pure} import parsley.combinator.{countSome, sepBy} import parsley.expr.{precedence, SOps, InfixL, InfixN, InfixR, Prefix, Atoms} import parsley.errors.combinator._ -import parsley.cats.combinator.{sepBy1, some} +import parsley.syntax.zipped._ +import parsley.cats.combinator.{some} import cats.data.NonEmptyList object parser { @@ -72,12 +73,12 @@ object parser { ) private lazy val `` = (`` <**> (`` identity)) | - `` ~> ((`` <**> ``) UntypedPairType) - + `` ~> ((`` <**> ``.explain("for a pair to contain a pair type, it must be an array or erased pair")) UntypedPairType) + // TODO: better explanation here? // Statements private lazy val `` = Program( - "begin" ~> many(atomic(`` <~> `` <~ "(") <**> ``), - `` <~ "end" + "begin" ~> many(atomic(``.label("function declaration") <~> `` <~ "(") <**> ``).label("function declaration"), + ``.label("main program body") <~ "end" ) private lazy val `` = (sepBy(``, ",") <~ ")" <~ "is" <~> ``.guardAgainst { @@ -87,23 +88,28 @@ object parser { } private lazy val `` = Param(``, ``) private lazy val ``: Parsley[NonEmptyList[Stmt]] = - sepBy1(``, ";") + ( + ``.label("main program body"), + (many(";" ~> ``.label("statement after ';'"))) Nil + ).zipped(NonEmptyList.apply) + private lazy val `` = (Skip from "skip") | Read("read" ~> ``) - | Free("free" ~> ``) - | Return("return" ~> ``) - | Exit("exit" ~> ``) - | Print("print" ~> ``, pure(false)) - | Print("println" ~> ``, pure(true)) + | Free("free" ~> ``.label("a valid expression")) + | Return("return" ~> ``.label("a valid expression")) + | Exit("exit" ~> ``.label("a valid expression")) + | Print("print" ~> ``.label("a valid expression"), pure(false)) + | Print("println" ~> ``.label("a valid expression"), pure(true)) | If( - "if" ~> `` <~ "then", + "if" ~> ``.label("a valid expression") <~ "then", `` <~ "else", `` <~ "fi" ) - | While("while" ~> `` <~ "do", `` <~ "done") + | While("while" ~> ``.label("a valid expression") <~ "do", `` <~ "done") | Block("begin" ~> `` <~ "end") - | VarDecl(``, `` <~ "=", ``) + | VarDecl(``, `` <~ "=", ``.label("a valid initial value for variable")) + // TODO: Can we inline the name of the variable in the message | Assign(`` <~ "=", ``) private lazy val ``: Parsley[LValue] = `` | `` @@ -117,9 +123,10 @@ object parser { Call( "call" ~> `` <~ "(", sepBy(``, ",") <~ ")" - ) | `` + ) | ``.label("valid expression") private lazy val `` = - Fst("fst" ~> ``) | Snd("snd" ~> ``) + Fst("fst" ~> ``.label("a valid pair")) + | Snd("snd" ~> ``.label("a valid pair")) private lazy val `` = ArrayLiter( "[" ~> sepBy(``, ",") <~ "]" )