diff --git a/compiler-access/src/main/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/BlockParser.scala b/compiler-access/src/main/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/BlockParser.scala index 67b690c0..32a3fde0 100644 --- a/compiler-access/src/main/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/BlockParser.scala +++ b/compiler-access/src/main/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/BlockParser.scala @@ -23,12 +23,12 @@ import org.alephium.ralph.lsp.access.compiler.parser.soft.ast.{SoftAST, Token} private object BlockParser { - def parseOrFail[Unknown: P]: P[SoftAST.BlockClause] = - parse(required = false) - def parse[Unknown: P]: P[SoftAST.BlockClause] = parse(required = true) + def parseOrFail[Unknown: P]: P[SoftAST.BlockClause] = + parse(required = false) + def body[Unknown: P]: P[SoftAST.BlockBody] = body() diff --git a/compiler-access/src/main/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/GroupParser.scala b/compiler-access/src/main/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/GroupParser.scala index 0c81f4f2..99358dc1 100644 --- a/compiler-access/src/main/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/GroupParser.scala +++ b/compiler-access/src/main/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/GroupParser.scala @@ -74,9 +74,9 @@ private object GroupParser { TokenParser.parse(required, open) ~ SpaceParser.parseOrFail.? ~ Index ~ - expression.? ~ + expression(open, close).? ~ SpaceParser.parseOrFail.? ~ - tail.rep ~ + tail(open, close).rep ~ TokenParser.parse(close) ~ Index } map { @@ -108,12 +108,14 @@ private object GroupParser { * * @return An instance of [[SoftAST.GroupTail]]. */ - private def tail[Unknown: P]: P[SoftAST.GroupTail] = + private def tail[Unknown: P, O <: Token, C <: Token]( + open: O, + close: C): P[SoftAST.GroupTail] = P { Index ~ TokenParser.parseOrFail(Token.Comma) ~ SpaceParser.parseOrFail.? ~ - expression ~ + expression(open, close) ~ SpaceParser.parseOrFail.? ~ Index } map { @@ -127,9 +129,12 @@ private object GroupParser { ) } - private def expression[Unknown: P]: P[SoftAST.ExpressionAST] = + private def expression[Unknown: P, O <: Token, C <: Token]( + open: O, + close: C): P[SoftAST.ExpressionAST] = P { - TypeAssignmentParser.parseOrFail | + GroupParser.parseOrFail(open, close) | + TypeAssignmentParser.parseOrFail | AssignmentParser.parseOrFail | InfixCallParser.parseOrFail | MethodCallParser.parseOrFail | diff --git a/compiler-access/src/test/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/GroupParserSpec.scala b/compiler-access/src/test/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/GroupParserSpec.scala index 866d2322..a5ff15ef 100644 --- a/compiler-access/src/test/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/GroupParserSpec.scala +++ b/compiler-access/src/test/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/GroupParserSpec.scala @@ -192,4 +192,39 @@ class GroupParserSpec extends AnyWordSpec with Matchers { bbb.tpe.toCode() shouldBe "(tuple1, tuple2)" } + "nested tuples" in { + val tuple = parseTuple("(a, (b, c))") + + tuple.headExpression.value shouldBe a[SoftAST.Identifier] + + tuple.tailExpressions should have size 1 + val lastTuple = tuple.tailExpressions.head + + lastTuple shouldBe + SoftAST.GroupTail( + index = indexOf("(a>>, (b, c)<<)"), + comma = Comma(indexOf("(a>>,<< (b, c))")), + preExpressionSpace = Some(SpaceOne(indexOf("(a,>> <<(b, c))"))), + expression = SoftAST.Group( + index = indexOf("(a, >>(b, c)<<)"), + openToken = OpenParen(indexOf("(a, >>(<>b<<, c))"), "b")), + postHeadExpressionSpace = None, + tailExpressions = Seq( + SoftAST.GroupTail( + index = indexOf("(a, (b>>, c<<))"), + comma = Comma(indexOf("(a, (b>>,<< c))")), + preExpressionSpace = Some(SpaceOne(indexOf("(a, (b,>> <>c<<))"), "c"), + postExpressionSpace = None + ) + ), + closeToken = CloseParen(indexOf("(a, (b, c>>)<<)")) + ), + postExpressionSpace = None + ) + + } + }