From 2e19434e09b819105055ddc8e58f69db98ec8669 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 27 May 2017 15:24:25 +0200 Subject: Handle #line directives in C/C++ lexer This way the parser now reports logical rather than physical location in diagnostics. --- unit-tests/cc/lexer/char-literal.test | 2 +- unit-tests/cc/lexer/driver.cxx | 37 ++++++++++++++++++++++------- unit-tests/cc/lexer/preprocessor.test | 20 +++++++++++++++- unit-tests/cc/lexer/raw-string-literal.test | 10 ++++---- unit-tests/cc/lexer/string-literal.test | 2 +- 5 files changed, 55 insertions(+), 16 deletions(-) (limited to 'unit-tests/cc') diff --git a/unit-tests/cc/lexer/char-literal.test b/unit-tests/cc/lexer/char-literal.test index f256785..f2c6249 100644 --- a/unit-tests/cc/lexer/char-literal.test +++ b/unit-tests/cc/lexer/char-literal.test @@ -63,5 +63,5 @@ EOO : unterminated : $* <"'a" 2>>EOE != 0 -stdin:1:1: error: unterminated literal +stdin:1:1: error: unterminated character literal EOE diff --git a/unit-tests/cc/lexer/driver.cxx b/unit-tests/cc/lexer/driver.cxx index db3f516..5803a88 100644 --- a/unit-tests/cc/lexer/driver.cxx +++ b/unit-tests/cc/lexer/driver.cxx @@ -16,38 +16,59 @@ namespace build2 { namespace cc { - // Usage: argv[0] [] + // Usage: argv[0] [-l] [] // int main (int argc, char* argv[]) { + bool loc (false); + const char* file (nullptr); + + for (int i (1); i != argc; ++i) + { + string a (argv[i]); + + if (a == "-l") + loc = true; + else + { + file = argv[i]; + break; + } + } + try { istream* is; - const char* in; // Reading from file is several times faster. // ifdstream ifs; - if (argc > 1) + if (file != nullptr) { - in = argv[1]; - ifs.open (in); + ifs.open (file); is = &ifs; } else { - in = "stdin"; + file = "stdin"; cin.exceptions (istream::failbit | istream::badbit); is = &cin; } - lexer l (*is, path (in)); + lexer l (*is, path (file)); // No use printing eos since we will either get it or loop forever. // for (token t; l.next (t) != token_type::eos; ) - cout << t << endl; + { + cout << t; + + if (loc) + cout << ' ' << t.file << ':' << t.line << ':' << t.column; + + cout << endl; + } } catch (const failed&) { diff --git a/unit-tests/cc/lexer/preprocessor.test b/unit-tests/cc/lexer/preprocessor.test index e082062..a3fab9f 100644 --- a/unit-tests/cc/lexer/preprocessor.test +++ b/unit-tests/cc/lexer/preprocessor.test @@ -32,10 +32,28 @@ EOI : line : -$* <>EOO +; # 1 "test.cxx" 2 +; + ; +# 4 +; #line 8 "z:\\tmp\\test.hxx" +; +#line 10 +; +# 5 "test.cxx" +; EOI +';' stdin:1:1 +';' test.cxx:1:1 +';' test.cxx:2:3 +';' test.cxx:4:1 +';' z:\tmp\test.hxx:8:1 +';' z:\tmp\test.hxx:10:1 +';' test.cxx:5:1 +EOO : nested : diff --git a/unit-tests/cc/lexer/raw-string-literal.test b/unit-tests/cc/lexer/raw-string-literal.test index e8e8b6b..7d5b920 100644 --- a/unit-tests/cc/lexer/raw-string-literal.test +++ b/unit-tests/cc/lexer/raw-string-literal.test @@ -62,29 +62,29 @@ EOO : invalid-no-paren : $* <'R"a"' 2>>EOE != 0 -stdin:1:2: error: invalid raw literal +stdin:1:2: error: invalid raw string literal EOE : invalid-paren : $* <'R")()("' 2>>EOE != 0 -stdin:1:2: error: invalid raw literal +stdin:1:2: error: invalid raw string literal EOE : invalid-unterminated-paren : $* <'R"(abc"' 2>>EOE != 0 -stdin:1:2: error: invalid raw literal +stdin:1:2: error: invalid raw string literal EOE : invalid-unterminated-delimiter : $* <'R"X(abc)"' 2>>EOE != 0 -stdin:1:2: error: invalid raw literal +stdin:1:2: error: invalid raw string literal EOE : invalid-unterminated-quote : $* <'R"X(abc)X' 2>>EOE != 0 -stdin:1:2: error: invalid raw literal +stdin:1:2: error: invalid raw string literal EOE diff --git a/unit-tests/cc/lexer/string-literal.test b/unit-tests/cc/lexer/string-literal.test index 062d290..f726c76 100644 --- a/unit-tests/cc/lexer/string-literal.test +++ b/unit-tests/cc/lexer/string-literal.test @@ -61,5 +61,5 @@ EOO : unterminated : $* <'"ab' 2>>EOE != 0 -stdin:1:1: error: unterminated literal +stdin:1:1: error: unterminated string literal EOE -- cgit v1.1