mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-24 17:30:44 +02:00
added support for C++14/17 number literals
This commit is contained in:
@@ -244,9 +244,16 @@ public:
|
||||
Poco::Token::Class tokenClass() const;
|
||||
bool start(char c, std::istream& istr);
|
||||
void finish(std::istream& istr);
|
||||
|
||||
int asInteger() const;
|
||||
double asFloat() const;
|
||||
|
||||
protected:
|
||||
void finishHex(std::istream& istr, int next);
|
||||
void finishBin(std::istream& istr, int next);
|
||||
void finishExp(std::istream& istr, int next);
|
||||
void finishSuffix(std::istream& istr, int next);
|
||||
|
||||
private:
|
||||
bool _isFloat;
|
||||
};
|
||||
|
||||
@@ -513,23 +513,18 @@ void NumberLiteralToken::finish(std::istream& istr)
|
||||
_isFloat = false;
|
||||
if (_value[0] != '.') // starts with digit
|
||||
{
|
||||
if (next == 'x')
|
||||
if (_value[0] == '0')
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
while (std::isxdigit(next))
|
||||
if (next == 'x' || next == 'X')
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
return finishHex(istr, next);
|
||||
}
|
||||
while (next == 'L' || next == 'l' || next == 'U' || next == 'u')
|
||||
else if (next == 'b' || next == 'B')
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
return finishBin(istr, next);
|
||||
}
|
||||
return;
|
||||
}
|
||||
while (next >= '0' && next <= '9')
|
||||
while ((next >= '0' && next <= '9') || next == '\'')
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
@@ -562,6 +557,56 @@ void NumberLiteralToken::finish(std::istream& istr)
|
||||
}
|
||||
if (next == 'e' || next == 'E')
|
||||
{
|
||||
_isFloat = true;
|
||||
finishExp(istr, next);
|
||||
}
|
||||
finishSuffix(istr, next);
|
||||
}
|
||||
|
||||
|
||||
void NumberLiteralToken::finishHex(std::istream& istr, int next)
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
while (std::isxdigit(next) || next == '\'')
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
}
|
||||
if (next == '.')
|
||||
{
|
||||
_isFloat = true;
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
while (std::isxdigit(next) || next == '\'')
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
}
|
||||
}
|
||||
if (next == 'p' || next == 'P')
|
||||
{
|
||||
finishExp(istr, next);
|
||||
}
|
||||
finishSuffix(istr, next);
|
||||
}
|
||||
|
||||
|
||||
void NumberLiteralToken::finishBin(std::istream& istr, int next)
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
while (next == '0' || next == '1' || next == '\'')
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
}
|
||||
finishSuffix(istr, next);
|
||||
}
|
||||
|
||||
|
||||
void NumberLiteralToken::finishExp(std::istream& istr, int next)
|
||||
{
|
||||
_isFloat = true;
|
||||
_value += (char) istr.get();
|
||||
next = istr.peek();
|
||||
@@ -583,7 +628,11 @@ void NumberLiteralToken::finish(std::istream& istr)
|
||||
std::string s(1, (char) next);
|
||||
syntaxError("digit", s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NumberLiteralToken::finishSuffix(std::istream& istr, int next)
|
||||
{
|
||||
if (_isFloat)
|
||||
{
|
||||
if (next == 'L' || next == 'l' || next == 'F' || next == 'f')
|
||||
@@ -603,7 +652,6 @@ void NumberLiteralToken::finish(std::istream& istr)
|
||||
int NumberLiteralToken::asInteger() const
|
||||
{
|
||||
return static_cast<int>(std::strtol(_value.c_str(), 0, 0));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "CppUnit/TestSuite.h"
|
||||
#include "Poco/CppParser/Utility.h"
|
||||
#include "Poco/CppParser/Symbol.h"
|
||||
#include "Poco/CppParser/CppToken.h"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -33,6 +35,7 @@ std::string options("/I \"C:\\Program Files\\Microsoft Visual Studio 8\\VC\\INCL
|
||||
"/C, /P, /TP");
|
||||
std::string path("C:\\Program Files\\Microsoft Visual Studio 8\\Common7\\IDE;C:\\Program Files\\Microsoft Visual Studio 8\\VC\\BIN;C:\\Program Files\\Microsoft Visual Studio 8\\Common7\\Tools;;C:\\Program Files\\Microsoft Visual Studio 8\\Common7\\Tools\\bin");
|
||||
|
||||
|
||||
CppParserTest::CppParserTest(const std::string& name): CppUnit::TestCase(name)
|
||||
{
|
||||
}
|
||||
@@ -55,7 +58,7 @@ void CppParserTest::testParseDir()
|
||||
|
||||
NameSpace::SymbolTable::const_iterator it = st.begin();
|
||||
NameSpace::SymbolTable::const_iterator itEnd = st.end();
|
||||
for (it; it != itEnd; ++it)
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
std::cout << it->first << ": ";
|
||||
Symbol* pSym = it->second;
|
||||
@@ -113,6 +116,70 @@ void CppParserTest::testExtractName()
|
||||
}
|
||||
|
||||
|
||||
void CppParserTest::testNumberLiterals()
|
||||
{
|
||||
testNumberLiteral("123");
|
||||
testNumberLiteral("0123");
|
||||
testNumberLiteral("0x123");
|
||||
testNumberLiteral("0XABC");
|
||||
testNumberLiteral("0b010101");
|
||||
testNumberLiteral("0B101010");
|
||||
|
||||
testNumberLiteral("123L");
|
||||
testNumberLiteral("0123L");
|
||||
testNumberLiteral("0x123L");
|
||||
testNumberLiteral("0XABCL");
|
||||
testNumberLiteral("0b010101L");
|
||||
testNumberLiteral("0B101010L");
|
||||
|
||||
testNumberLiteral("123LL");
|
||||
testNumberLiteral("0123LL");
|
||||
testNumberLiteral("0x123LL");
|
||||
testNumberLiteral("0XABCLL");
|
||||
testNumberLiteral("0b010101LL");
|
||||
testNumberLiteral("0B101010LL");
|
||||
|
||||
testNumberLiteral("123U");
|
||||
testNumberLiteral("0123U");
|
||||
testNumberLiteral("0x123U");
|
||||
testNumberLiteral("0XABCU");
|
||||
testNumberLiteral("0b010101U");
|
||||
testNumberLiteral("0B101010U");
|
||||
|
||||
testNumberLiteral("123UL");
|
||||
testNumberLiteral("0123UL");
|
||||
testNumberLiteral("0x123UL");
|
||||
testNumberLiteral("0XABCUL");
|
||||
testNumberLiteral("0b010101UL");
|
||||
testNumberLiteral("0B101010UL");
|
||||
|
||||
testNumberLiteral("1.23");
|
||||
testNumberLiteral(".123");
|
||||
testNumberLiteral("1.23e+3");
|
||||
testNumberLiteral("1.23E-3");
|
||||
|
||||
testNumberLiteral("0x1fp1");
|
||||
testNumberLiteral("0x1f.e3p+12");
|
||||
testNumberLiteral("0x1f.e3p-12");
|
||||
|
||||
testNumberLiteral("123'456");
|
||||
testNumberLiteral("1'234'567");
|
||||
testNumberLiteral("0x1234'5678");
|
||||
testNumberLiteral("0xFFFF'FFFFULL");
|
||||
}
|
||||
|
||||
|
||||
void CppParserTest::testNumberLiteral(const std::string& literal)
|
||||
{
|
||||
NumberLiteralToken tok;
|
||||
|
||||
std::istringstream istr(literal);
|
||||
assertTrue (tok.start(istr.get(), istr));
|
||||
tok.finish(istr);
|
||||
assertEquals (tok.tokenString(), literal);
|
||||
}
|
||||
|
||||
|
||||
void CppParserTest::setUp()
|
||||
{
|
||||
}
|
||||
@@ -129,6 +196,7 @@ CppUnit::Test* CppParserTest::suite()
|
||||
|
||||
CppUnit_addTest(pSuite, CppParserTest, testParseDir);
|
||||
CppUnit_addTest(pSuite, CppParserTest, testExtractName);
|
||||
CppUnit_addTest(pSuite, CppParserTest, testNumberLiterals);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
||||
@@ -26,12 +26,16 @@ public:
|
||||
|
||||
void testParseDir();
|
||||
void testExtractName();
|
||||
void testNumberLiterals();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
static CppUnit::Test* suite();
|
||||
|
||||
protected:
|
||||
void testNumberLiteral(const std::string& literal);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user