From 6a5acc1052f72f14dd6ec2f897108f735fe67510 Mon Sep 17 00:00:00 2001 From: Lan Nguyen Date: Tue, 3 Jul 2018 17:08:59 -0700 Subject: [PATCH] Add line number to S-expression parser Summary: Add m_line_no private data member inside s_expr_istream Add 1 to m_line_no whenever \\n is found Attach On line : prefix to the error message Add line numbers to the test Reviewed By: justinjhendrick, arnaudvenet Differential Revision: D8719762 fbshipit-source-id: 0f80391a36254c24278eb60a8844c68fa1305006 --- sparta/include/S_Expression.h | 11 +++++++++-- sparta/test/S_ExpressionTest.cpp | 33 ++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/sparta/include/S_Expression.h b/sparta/include/S_Expression.h index 0eeb1b5de6..a6c774b58d 100644 --- a/sparta/include/S_Expression.h +++ b/sparta/include/S_Expression.h @@ -225,7 +225,7 @@ class s_expr_istream final { s_expr_istream& operator=(const s_expr_istream&) = delete; s_expr_istream(std::istream& input) - : m_input(input), m_status(Status::Good), m_what("OK") {} + : m_input(input), m_line_number(1), m_status(Status::Good), m_what("OK") {} s_expr_istream& operator>>(s_expr& expr); @@ -259,6 +259,7 @@ class s_expr_istream final { std::stack m_stack; std::istream& m_input; + size_t m_line_number; Status m_status; std::string m_what; }; @@ -803,6 +804,7 @@ inline s_expr_istream& s_expr_istream::operator>>(s_expr& expr) { } case ';': { m_input.ignore(std::numeric_limits::max(), '\n'); + ++m_line_number; break; } default: { @@ -834,6 +836,9 @@ inline void s_expr_istream::skip_white_spaces() { for (;;) { char c = m_input.peek(); if (m_input.good() && std::isspace(c)) { + if (c == '\n') { + ++m_line_number; + } m_input.get(); } else { return; @@ -844,7 +849,9 @@ inline void s_expr_istream::skip_white_spaces() { inline void s_expr_istream::set_status(Status status, const std::string& what_arg) { m_status = status; - m_what = what_arg; + std::ostringstream ss; + ss << "On line " << m_line_number << ": " << what_arg; + m_what = ss.str(); } inline s_patn::s_patn() diff --git a/sparta/test/S_ExpressionTest.cpp b/sparta/test/S_ExpressionTest.cpp index 05b17b6d6c..15811c202e 100644 --- a/sparta/test/S_ExpressionTest.cpp +++ b/sparta/test/S_ExpressionTest.cpp @@ -160,17 +160,38 @@ TEST(S_ExpressionTest, basicOperations) { std::string error; erroneous_parse("((a) b ()", 1, error); - EXPECT_EQ("Incomplete S-expression", error); + EXPECT_EQ("On line 1: Incomplete S-expression", error); + erroneous_parse("(\n(a)\nb\n()\n", 1, error); + EXPECT_EQ("On line 5: Incomplete S-expression", error); erroneous_parse("((a) b c))", 2, error); - EXPECT_EQ("Extra ')' encountered", error); + EXPECT_EQ("On line 1: Extra ')' encountered", error); + erroneous_parse(R"( + ( + (a) + b + c + )) + )", 2, error); + EXPECT_EQ("On line 6: Extra ')' encountered", error); erroneous_parse("(a b #9999999999999)", 1, error); - EXPECT_EQ("Error parsing int32_t literal", error); + EXPECT_EQ("On line 1: Error parsing int32_t literal", error); erroneous_parse("(a b #-9999999999999)", 1, error); - EXPECT_EQ("Error parsing int32_t literal", error); + EXPECT_EQ("On line 1: Error parsing int32_t literal", error); erroneous_parse("(a b \"abcdef)", 1, error); - EXPECT_EQ("Error parsing string literal", error); + EXPECT_EQ("On line 1: Error parsing string literal", error); erroneous_parse("123, (a b c)", 2, error); - EXPECT_EQ("Unexpected character encountered: ','", error); + EXPECT_EQ("On line 1: Unexpected character encountered: ','", error); + erroneous_parse(R"(;Should only take 1 endline in an inline comment\n\n\n + ( + (const-string "foo\n\bar") + 123, (a b c) + ) + )", 2, error); + EXPECT_EQ("On line 4: Unexpected character encountered: ','", error); + erroneous_parse(R"(;The error should be on line 2 + (123, (a b c) ; End of line 2 + )", 2, error); + EXPECT_EQ("On line 2: Unexpected character encountered: ','", error); } TEST(S_ExpressionTest, patternMatching) {