Skip to content

Commit

Permalink
Merge pull request #80 from MoeOrganization/prakashk/string-literal-fix
Browse files Browse the repository at this point in the history
String Literal parsing fix
  • Loading branch information
Stevan Little committed Apr 9, 2013
2 parents 012ae35 + dfc5f2d commit 425446f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 37 deletions.
28 changes: 7 additions & 21 deletions lib/Test-More/lib/Test/More.mo
Expand Up @@ -10,26 +10,12 @@ package Test::More {
say 1, "..", $test_count;
}

# NOTE:
# The "".pad(1) silliness is because
# the parser (for some reason) does
# not like strings with just spaces
# and instead gives back an empty string
# and I can't figure it out.
#
# The chr(35) silliness is because
# our comment parser seems to like
# to sometimes gobble up quoted strings
# and again, I can't figure it out
# so I added in chr() for now.
# - SL

sub ok ($test, $msg?) is export {
$test_count = $test_count + 1;
if ($test) {
say [ "ok", $test_count, ($msg || "") ].join("".pad(1));
say [ "ok", $test_count, ($msg || "") ].join(" ");
} else {
say [ "not ok", $test_count, ($msg || "") ].join("".pad(1));
say [ "not ok", $test_count, ($msg || "") ].join(" ");
}
}

Expand All @@ -46,15 +32,15 @@ package Test::More {
}

if ($result) {
say [ "ok", $test_count, ($msg || "") ].join("".pad(1));
say [ "ok", $test_count, ($msg || "") ].join(" ");
} else {
say [ "not ok", $test_count, ($msg || "") ].join("".pad(1));
say [ "not ok", $test_count, ($msg || "") ].join(" ");
warn(
chr(35), "Failed test".pad(2), ($msg || ""),
"# Failed test", ($msg || ""),
"\n",
chr(35), "got:".pad(4).rpad(6), ~$got,
"# got: ", ~$got,
"\n",
chr(35), "expected:".pad(4).rpad(1), ~$expected
"# expected: ", ~$expected
);
}
}
Expand Down
14 changes: 8 additions & 6 deletions src/main/scala/org/moe/parser/MoeLiterals.scala
Expand Up @@ -49,13 +49,15 @@ trait MoeLiterals extends JavaTokenParsers {
// things a little)
// - SL

def doubleQuoteStringContents: Parser[StringLiteralNode] =
"""([^"\p{Cntrl}\\]|\\[\\'"bfnrt]|\\x\{[a-fA-F0-9]{4}\})*""".r ^^ { s => StringLiteralNode(formatStr(s)) }
def singleQuoteStringContents: Parser[StringLiteralNode] =
"""([^'\p{Cntrl}\\]|\\[\\'"bfnrt]|\\x\{[a-fA-F0-9]{4}\})*""".r ^^ StringLiteralNode
val doubleQuoteStringPattern = """"((?:[^"\p{Cntrl}\\]|\\[\\'"bfnrt]|\\x\{[a-fA-F0-9]{4}\})*)"""".r
def doubleQuoteString: Parser[StringLiteralNode] = doubleQuoteStringPattern ^^ {
case doubleQuoteStringPattern(s) => StringLiteralNode(formatStr(s))
}

def doubleQuoteString: Parser[StringLiteralNode] = "\"" ~> doubleQuoteStringContents <~ "\""
def singleQuoteString: Parser[StringLiteralNode] = "'" ~> singleQuoteStringContents <~ "'"
val singleQuoteStringPattern = """'((?:[^'\p{Cntrl}\\]|\\[\\'"bfnrt]|\\x\{[a-fA-F0-9]{4}\})*)'""".r
def singleQuoteString: Parser[StringLiteralNode] = singleQuoteStringPattern ^^ {
case singleQuoteStringPattern(s) => StringLiteralNode(s)
}

def string: Parser[StringLiteralNode] = doubleQuoteString | singleQuoteString

Expand Down
29 changes: 19 additions & 10 deletions src/test/scala/org/moe/parser/StringLiteralTestSuite.scala
Expand Up @@ -2,57 +2,66 @@ package org.moe.parser

import org.scalatest.FunSuite
import org.scalatest.BeforeAndAfter
import org.scalatest.matchers.ShouldMatchers

import org.moe.runtime._
import org.moe.interpreter._
import org.moe.ast._
import org.moe.parser._

class StringLiteralTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils {
class StringLiteralTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils with ShouldMatchers {

// double quotes ...

test("... basic test with a simple double-quoted string") {
val result = interpretCode(""" "hello world" """)
assert(result.unboxToString.get === "hello world")
result.unboxToString.get should equal ("hello world")
}

test("... basic test with a double-quoted string with control characters") {
val result = interpretCode(""" "foo\tbar\n" """)
assert(result.unboxToString.get === "foo\tbar\n")
result.unboxToString.get should equal ("foo\tbar\n")
}

test("... basic test with a double-quoted string with escaped quotes") {
val result = interpretCode(""" "foo\"bar\"" """)
assert(result.unboxToString.get === "foo\"bar\"")
result.unboxToString.get should equal ("foo\"bar\"")
}

//
test("... basic test with a double-quoted string with unicode escaped literals ") {
val result = interpretCode(""" "\x{03a3}" """)
assert(result.unboxToString.get === "\\x{03a3}")
result.unboxToString.get should equal ("\\x{03a3}")
}

test("... basic test with double-quoted string with leading whitespace") {
val result = interpretCode(""" " hello world" """)
result.unboxToString.get should equal (" hello world")
}

// single quotes ...

test("... basic test with a simple single-quoted string") {
val result = interpretCode("'hello world'")
assert(result.unboxToString.get === "hello world")
result.unboxToString.get should equal ("hello world")
}

test("... basic test with a single-quoted string with control characters") {
val result = interpretCode("'foo\\tbar\\n'")
assert(result.unboxToString.get === "foo\\tbar\\n")
result.unboxToString.get should equal ("foo\\tbar\\n")
}

test("... basic test with a single-quoted string with embedded double quotes") {
val result = interpretCode("'foo\"bar\"'")
assert(result.unboxToString.get === "foo\"bar\"")
result.unboxToString.get should equal ("foo\"bar\"")
}

test("... basic test with a single-quoted string with unicode escaped literals ") {
val result = interpretCode("'\\x{03a3}'")
assert(result.unboxToString.get === "\\x{03a3}")
result.unboxToString.get should equal ("\\x{03a3}")
}

test("... basic test with single-quoted string with leading whitespace") {
val result = interpretCode(""" ' hello world' """)
result.unboxToString.get should equal (" hello world")
}
}

0 comments on commit 425446f

Please sign in to comment.