forked from qt-creator/qt-creator
		
	C++: clean up numeric literal parsing and add support for n3472.
Separate the messy pp-number parsing from the numeric literal parsing. The C/C++ preprocessor makes a grown man cry, but at least we have "proper" literal parsing when we want it, including C++1y binary literals. Next step is digit separators (n3781). Change-Id: Ia069eef454ed5c056f77694a5b8a595d0b76adc4 Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
This commit is contained in:
		
				
					committed by
					
						 Nikolai Kosjar
						Nikolai Kosjar
					
				
			
			
				
	
			
			
			
						parent
						
							16becbd29c
						
					
				
				
					commit
					242b3f4110
				
			| @@ -70,6 +70,10 @@ private slots: | ||||
|     void basic_data(); | ||||
|     void incremental(); | ||||
|     void incremental_data(); | ||||
|     void literals(); | ||||
|     void literals_data(); | ||||
|     void preprocessor(); | ||||
|     void preprocessor_data(); | ||||
|  | ||||
|     void bytes_and_utf16chars(); | ||||
|     void bytes_and_utf16chars_data(); | ||||
| @@ -82,7 +86,8 @@ private: | ||||
|     void run(const QByteArray &source, | ||||
|              const Tokens &expectedTokens, | ||||
|              bool preserveState, | ||||
|              TokenCompareFlags compareFlags); | ||||
|              TokenCompareFlags compareFlags, | ||||
|              bool preprocessorMode = false); | ||||
|  | ||||
|     int _state; | ||||
| }; | ||||
| @@ -103,11 +108,13 @@ Tokens tst_SimpleLexer::toTokens(const TokenKindList &tokenKinds) | ||||
| void tst_SimpleLexer::run(const QByteArray &source, | ||||
|                           const Tokens &expectedTokens, | ||||
|                           bool preserveState, | ||||
|                           TokenCompareFlags compareFlags) | ||||
|                           TokenCompareFlags compareFlags, | ||||
|                           bool preprocessorMode) | ||||
| { | ||||
|     QVERIFY(compareFlags); | ||||
|  | ||||
|     SimpleLexer lexer; | ||||
|     lexer.setPreprocessorMode(preprocessorMode); | ||||
|     const Tokens tokens = lexer(source, preserveState ? _state : 0); | ||||
|     if (preserveState) | ||||
|         _state = lexer.state(); | ||||
| @@ -140,7 +147,10 @@ void tst_SimpleLexer::run(const QByteArray &source, | ||||
|         if (compareFlags & CompareUtf16CharsEnd) | ||||
|             QCOMPARE(token.utf16charsEnd(), expectedToken.utf16charsEnd()); | ||||
|     } | ||||
|     QVERIFY2(i == expectedTokens.size(), "Less tokens than expected."); | ||||
|  | ||||
|     QString msg = QLatin1String("Less tokens than expected: got %1, expected %2."); | ||||
|     msg = msg.arg(i).arg(expectedTokens.size()); | ||||
|     QVERIFY2(i == expectedTokens.size(), msg.toUtf8().constData()); | ||||
| } | ||||
|  | ||||
| void tst_SimpleLexer::basic() | ||||
| @@ -254,6 +264,97 @@ void tst_SimpleLexer::basic_data() | ||||
|     QTest::newRow(source) << source << expectedTokenKindList; | ||||
| } | ||||
|  | ||||
| void tst_SimpleLexer::literals() | ||||
| { | ||||
|     QFETCH(QByteArray, source); | ||||
|     QFETCH(TokenKindList, expectedTokenKindList); | ||||
|  | ||||
|     run(source, toTokens(expectedTokenKindList), false, CompareKind); | ||||
| } | ||||
|  | ||||
| void tst_SimpleLexer::literals_data() | ||||
| { | ||||
|     QTest::addColumn<QByteArray>("source"); | ||||
|     QTest::addColumn<TokenKindList>("expectedTokenKindList"); | ||||
|  | ||||
|     QByteArray source; | ||||
|     TokenKindList expectedTokenKindList; | ||||
|  | ||||
|     source = | ||||
|             "1.\n" | ||||
|             "1.1\n" | ||||
|             "1.23456789\n" | ||||
|             ".1\n" | ||||
|             ".3e8\n" | ||||
|             ".3e8f\n" | ||||
|             "1e1\n" | ||||
|             "1E1\n" | ||||
|             "-1e-1\n" // the first minus sign is a separate token! | ||||
|             "1e-1\n" | ||||
|             "1e+1\n" | ||||
|             "1e1L\n" | ||||
|             "1e1l\n" | ||||
|             "1e1f\n" | ||||
|             "1e1F\n" | ||||
|             "23.45x" | ||||
|             ".45x" | ||||
|             ; | ||||
|     expectedTokenKindList = | ||||
|             TokenKindList() << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL | ||||
|                             << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL | ||||
|                             << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_MINUS | ||||
|                             << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL | ||||
|                             << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL | ||||
|                             << T_NUMERIC_LITERAL << T_ERROR << T_ERROR | ||||
|                                ; | ||||
|     QTest::newRow("float-literals") << source << expectedTokenKindList; | ||||
|  | ||||
|     source = // these are all the same | ||||
|             "42\n" | ||||
|             "0b101010u\n" | ||||
|             "052ll\n" | ||||
|             "0x2aL\n" | ||||
|             "123FOO\n" | ||||
|             "0xfOo\n" | ||||
|             "33_\n" | ||||
|             ; | ||||
|     expectedTokenKindList = | ||||
|             TokenKindList() << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL | ||||
|                             << T_NUMERIC_LITERAL << T_ERROR << T_ERROR << T_ERROR | ||||
|                                ; | ||||
|     QTest::newRow("integer-literals") << source << expectedTokenKindList; | ||||
| } | ||||
|  | ||||
| void tst_SimpleLexer::preprocessor() | ||||
| { | ||||
|     QFETCH(QByteArray, source); | ||||
|     QFETCH(TokenKindList, expectedTokenKindList); | ||||
|  | ||||
|     run(source, toTokens(expectedTokenKindList), false, CompareKind, true); | ||||
| } | ||||
|  | ||||
| void tst_SimpleLexer::preprocessor_data() | ||||
| { | ||||
|     QTest::addColumn<QByteArray>("source"); | ||||
|     QTest::addColumn<TokenKindList>("expectedTokenKindList"); | ||||
|  | ||||
|     QByteArray source; | ||||
|     TokenKindList expectedTokenKindList; | ||||
|  | ||||
|     source = // sad but true [2.10] | ||||
|             "1\n" | ||||
|             "1x.\n" | ||||
|             "1.y\n" | ||||
|             ".1_1.1.\n" | ||||
|             "1e-\n" | ||||
|             "01x1b2qWeRtty_Grumble+E-.\n" | ||||
|             ; | ||||
|     expectedTokenKindList = | ||||
|             TokenKindList() << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL | ||||
|                             << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL; | ||||
|     QTest::newRow("pp-number") << source << expectedTokenKindList; | ||||
| } | ||||
|  | ||||
| void tst_SimpleLexer::bytes_and_utf16chars() | ||||
| { | ||||
|     QFETCH(QByteArray, source); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user