From 974c6e4f232ee9d47187898966e0887a119a0aba Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 3 Nov 2014 01:25:13 -0800 Subject: All tests pass, including first rudimentary indentation test --- .../src/main/scala/scalatex/ScalatexParser.scala | 57 +++++++++++----------- .../src/test/scala/scalatex/ParserTests.scala | 18 +++++-- 2 files changed, 43 insertions(+), 32 deletions(-) (limited to 'scalatexApi') diff --git a/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala b/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala index 721af40..dc7bf06 100644 --- a/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala +++ b/scalatexApi/src/main/scala/scalatex/ScalatexParser.scala @@ -7,19 +7,13 @@ trait Ast{ def offset: Int } object Ast{ - case class Block(parts: Seq[Block.Sub], offset: Int = 0) extends Chain.Sub{ - println("Init Block") - } + case class Block(parts: Seq[Block.Sub], offset: Int = 0) extends Chain.Sub object Block{ trait Sub - case class Text(txt: String, offset: Int = 0) extends Block.Sub{ - println("Init Text " + txt) - } + case class Text(txt: String, offset: Int = 0) extends Block.Sub } case class Code(code: String, offset: Int = 0) - case class Chain(lhs: Code, parts: Seq[Chain.Sub], offset: Int = 0) extends Block.Sub{ - println("Init Chain " + lhs) - } + case class Chain(lhs: Code, parts: Seq[Chain.Sub], offset: Int = 0) extends Block.Sub object Chain{ trait Sub case class Prop(str: String, offset: Int = 0) extends Sub @@ -27,9 +21,22 @@ object Ast{ } } class ScalatexParser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(input) { + val txt = input.sliceString(0, input.length) + val indentTable = txt.split('\n').map{ s => + if (s.trim == "") -1 + else s.takeWhile(_ == ' ').length + } + val nextIndentTable = (0 until indentTable.length).map { i => + val index = indentTable.indexWhere(_ != -1, i + 1) + if (index == -1) 100000 + else indentTable(index) + } + def cursorNextIndent() = { + nextIndentTable(txt.take(cursor).count(_ == '\n')) + } println("INDENT " + indent) def TextNot(chars: String) = rule { - capture(oneOrMore(noneOf(chars + "\n"))) ~> { + capture(oneOrMore(noneOf(chars + "\n") | "@@")) ~> { x => Ast.Block.Text(x.replace("@@", "@")) } } @@ -37,26 +44,20 @@ class ScalatexParser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(in def Code = rule { "@" ~ capture(Id | BlockExpr | ('(' ~ optional(Exprs) ~ ')')) ~> (Ast.Code(_)) } - def BlankLine = rule{ run(println("BL A " + (cursorChar.toInt, '\n'.toInt))) ~ '\n' ~ run(println("BL B")) ~ zeroOrMore(' ') ~ run(println("BL C")) ~ &('\n') ~ run(println("BL D")) } - def Indent = rule{ run(println("Indent A " + cursorChar.toInt)) ~ '\n' ~ run(println("Indent A")) ~ indent.times(' ') ~ run(println("Indent A")) ~ zeroOrMore(' ') } + def BlankLine = rule{ '\n' ~ zeroOrMore(' ') ~ &('\n') } + def Indent = rule{ '\n' ~ indent.times(' ') ~ zeroOrMore(' ') } def LoneScalaChain: Rule1[Ast.Chain] = rule { - run(println("LSC Indent")) ~ Indent ~ - run(println("LSC SC")) ~ ScalaChain ~ + Indent ~ + ScalaChain ~ zeroOrMore(BlankLine) ~ - run(println("LSC NewLine")) ~ + test(cursorNextIndent() > indent) ~ runSubParser { - new ScalatexParser(_, indent + 2).Body + new ScalatexParser(_, cursorNextIndent()).Body } ~> { (chain: Ast.Chain, body: Ast.Block) => - println("chain.copy " + body) chain.copy(parts = chain.parts :+ body) } } - def newInput(s: String, x: ParserInput): String = { - def newInput = '\n' + s + x.sliceString(0, x.length) - println(newInput.split("\n").map("|" + _ + "|").mkString("\n")) - newInput - } def ScalaChain = rule { Code ~ zeroOrMore(Extension) ~> {Ast.Chain(_, _)} } @@ -67,15 +68,13 @@ class ScalatexParser(input: ParserInput, indent: Int = 0) extends ScalaSyntax(in } def TBlock = rule{ '{' ~ Body ~ '}' } def Body = rule{ - run(println("BODY")) ~ zeroOrMore( - run(println("Body LSC")) ~ LoneScalaChain | - run(println("Body TextNot")) ~ TextNot("@}") | - run(println("Body Indent")) ~ (capture(Indent) ~> (Ast.Block.Text(_))) | - run(println("Body BlankLine")) ~ (capture(BlankLine) ~> (Ast.Block.Text(_))) -// | ScalaChain + LoneScalaChain | + TextNot("@}") | + (capture(Indent) ~> (Ast.Block.Text(_))) | + (capture(BlankLine) ~> (Ast.Block.Text(_))) | + ScalaChain ) ~> {x => - println("BODY ENDED: " + x) Ast.Block(x) } } diff --git a/scalatexApi/src/test/scala/scalatex/ParserTests.scala b/scalatexApi/src/test/scala/scalatex/ParserTests.scala index 34c6fdb..0649357 100644 --- a/scalatexApi/src/test/scala/scalatex/ParserTests.scala +++ b/scalatexApi/src/test/scala/scalatex/ParserTests.scala @@ -53,14 +53,26 @@ object ParserTests extends utest.TestSuite{ } 'Body{ - val str = + * - check( """ |@omg | @wtf | @bbq | @lol - """.stripMargin - new ScalatexParser(str).Body.run() + """.stripMargin, + _.Body.run(), + Block(Seq( + Chain(Code("omg"),Seq(Block(Seq( + Chain(Code("wtf"),Seq(Block(Seq( + Chain(Code("bbq"),Seq(Block(Seq( + Chain(Code("lol"),Seq(Block(Seq( + )))), + Ast.Block.Text("\n ") + )))) + )))) + )))) + )) + ) } } -- cgit v1.2.3