mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-25 18:22:59 +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;
|
Poco::Token::Class tokenClass() const;
|
||||||
bool start(char c, std::istream& istr);
|
bool start(char c, std::istream& istr);
|
||||||
void finish(std::istream& istr);
|
void finish(std::istream& istr);
|
||||||
|
|
||||||
int asInteger() const;
|
int asInteger() const;
|
||||||
double asFloat() 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:
|
private:
|
||||||
bool _isFloat;
|
bool _isFloat;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -513,23 +513,18 @@ void NumberLiteralToken::finish(std::istream& istr)
|
|||||||
_isFloat = false;
|
_isFloat = false;
|
||||||
if (_value[0] != '.') // starts with digit
|
if (_value[0] != '.') // starts with digit
|
||||||
{
|
{
|
||||||
if (next == 'x')
|
if (_value[0] == '0')
|
||||||
{
|
{
|
||||||
_value += (char) istr.get();
|
if (next == 'x' || next == 'X')
|
||||||
next = istr.peek();
|
|
||||||
while (std::isxdigit(next))
|
|
||||||
{
|
{
|
||||||
_value += (char) istr.get();
|
return finishHex(istr, next);
|
||||||
next = istr.peek();
|
|
||||||
}
|
}
|
||||||
while (next == 'L' || next == 'l' || next == 'U' || next == 'u')
|
else if (next == 'b' || next == 'B')
|
||||||
{
|
{
|
||||||
_value += (char) istr.get();
|
return finishBin(istr, next);
|
||||||
next = istr.peek();
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
while (next >= '0' && next <= '9')
|
while ((next >= '0' && next <= '9') || next == '\'')
|
||||||
{
|
{
|
||||||
_value += (char) istr.get();
|
_value += (char) istr.get();
|
||||||
next = istr.peek();
|
next = istr.peek();
|
||||||
@@ -562,6 +557,56 @@ void NumberLiteralToken::finish(std::istream& istr)
|
|||||||
}
|
}
|
||||||
if (next == 'e' || next == 'E')
|
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;
|
_isFloat = true;
|
||||||
_value += (char) istr.get();
|
_value += (char) istr.get();
|
||||||
next = istr.peek();
|
next = istr.peek();
|
||||||
@@ -583,7 +628,11 @@ void NumberLiteralToken::finish(std::istream& istr)
|
|||||||
std::string s(1, (char) next);
|
std::string s(1, (char) next);
|
||||||
syntaxError("digit", s);
|
syntaxError("digit", s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NumberLiteralToken::finishSuffix(std::istream& istr, int next)
|
||||||
|
{
|
||||||
if (_isFloat)
|
if (_isFloat)
|
||||||
{
|
{
|
||||||
if (next == 'L' || next == 'l' || next == 'F' || next == 'f')
|
if (next == 'L' || next == 'l' || next == 'F' || next == 'f')
|
||||||
@@ -603,7 +652,6 @@ void NumberLiteralToken::finish(std::istream& istr)
|
|||||||
int NumberLiteralToken::asInteger() const
|
int NumberLiteralToken::asInteger() const
|
||||||
{
|
{
|
||||||
return static_cast<int>(std::strtol(_value.c_str(), 0, 0));
|
return static_cast<int>(std::strtol(_value.c_str(), 0, 0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
#include "CppUnit/TestSuite.h"
|
#include "CppUnit/TestSuite.h"
|
||||||
#include "Poco/CppParser/Utility.h"
|
#include "Poco/CppParser/Utility.h"
|
||||||
#include "Poco/CppParser/Symbol.h"
|
#include "Poco/CppParser/Symbol.h"
|
||||||
|
#include "Poco/CppParser/CppToken.h"
|
||||||
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
@@ -33,6 +35,7 @@ std::string options("/I \"C:\\Program Files\\Microsoft Visual Studio 8\\VC\\INCL
|
|||||||
"/C, /P, /TP");
|
"/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");
|
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)
|
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 it = st.begin();
|
||||||
NameSpace::SymbolTable::const_iterator itEnd = st.end();
|
NameSpace::SymbolTable::const_iterator itEnd = st.end();
|
||||||
for (it; it != itEnd; ++it)
|
for (; it != itEnd; ++it)
|
||||||
{
|
{
|
||||||
std::cout << it->first << ": ";
|
std::cout << it->first << ": ";
|
||||||
Symbol* pSym = it->second;
|
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()
|
void CppParserTest::setUp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -129,6 +196,7 @@ CppUnit::Test* CppParserTest::suite()
|
|||||||
|
|
||||||
CppUnit_addTest(pSuite, CppParserTest, testParseDir);
|
CppUnit_addTest(pSuite, CppParserTest, testParseDir);
|
||||||
CppUnit_addTest(pSuite, CppParserTest, testExtractName);
|
CppUnit_addTest(pSuite, CppParserTest, testExtractName);
|
||||||
|
CppUnit_addTest(pSuite, CppParserTest, testNumberLiterals);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,16 @@ public:
|
|||||||
|
|
||||||
void testParseDir();
|
void testParseDir();
|
||||||
void testExtractName();
|
void testExtractName();
|
||||||
|
void testNumberLiterals();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|
||||||
static CppUnit::Test* suite();
|
static CppUnit::Test* suite();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void testNumberLiteral(const std::string& literal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user