mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-07-07 20:06:39 +02:00
Pig: Promoted Pig to common.git
This commit is contained in:
parent
ab17cbb012
commit
5690fb784a
6 changed files with 1 additions and 820 deletions
|
@ -6,7 +6,6 @@ include_directories (${CMAKE_SOURCE_DIR}
|
|||
set (timew_SRCS Grammar.cpp Grammar.h
|
||||
Lexer.cpp Lexer.h
|
||||
LR0.cpp LR0.h
|
||||
Pig.cpp Pig.h
|
||||
Rules.cpp Rules.h)
|
||||
|
||||
add_library (timew STATIC ${timew_SRCS})
|
||||
|
|
500
src/Pig.cpp
500
src/Pig.cpp
|
@ -1,500 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2015 - 2016, Paul Beckingham, Federico Hernandez.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cmake.h>
|
||||
#include <Pig.h>
|
||||
#include <unicode.h>
|
||||
#include <utf8.h>
|
||||
#include <sstream>
|
||||
#include <cinttypes>
|
||||
#include <cstdlib>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Pig::Pig (const std::string& text)
|
||||
: _text {text}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::skip (int c)
|
||||
{
|
||||
if (_text[_cursor] == c)
|
||||
{
|
||||
++_cursor;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::skipN (const int quantity)
|
||||
{
|
||||
auto save = _cursor;
|
||||
|
||||
auto count = 0;
|
||||
while (count++ < quantity)
|
||||
{
|
||||
if (! utf8_next_char (_text, _cursor))
|
||||
{
|
||||
_cursor = save;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::skipWS ()
|
||||
{
|
||||
auto save = _cursor;
|
||||
|
||||
int c;
|
||||
auto prev = _cursor;
|
||||
while ((c = utf8_next_char (_text, _cursor)))
|
||||
{
|
||||
if (! unicodeWhitespace (c))
|
||||
{
|
||||
_cursor = prev;
|
||||
break;
|
||||
}
|
||||
prev = _cursor;
|
||||
}
|
||||
|
||||
return _cursor > save;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::skipLiteral (const std::string& literal)
|
||||
{
|
||||
if (_text.find (literal, _cursor) == _cursor)
|
||||
{
|
||||
_cursor += literal.length ();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::getUntilWS (std::string& result)
|
||||
{
|
||||
auto save = _cursor;
|
||||
|
||||
int c;
|
||||
auto prev = _cursor;
|
||||
while ((c = utf8_next_char (_text, _cursor)))
|
||||
{
|
||||
if (eos ())
|
||||
{
|
||||
result = _text.substr (save, _cursor - save);
|
||||
return true;
|
||||
}
|
||||
|
||||
else if (unicodeWhitespace (c))
|
||||
{
|
||||
_cursor = prev;
|
||||
result = _text.substr (save, _cursor - save);
|
||||
return true;
|
||||
}
|
||||
|
||||
prev = _cursor;
|
||||
}
|
||||
|
||||
return _cursor > save;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::getDigit (int& result)
|
||||
{
|
||||
int c = _text[_cursor];
|
||||
if (c &&
|
||||
unicodeLatinDigit (c))
|
||||
{
|
||||
result = c - '0';
|
||||
++_cursor;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::getDigit2 (int& result)
|
||||
{
|
||||
if (unicodeLatinDigit (_text[_cursor + 0]))
|
||||
{
|
||||
if (unicodeLatinDigit (_text[_cursor + 1]))
|
||||
{
|
||||
result = strtoimax (_text.substr (_cursor, 2).c_str (), NULL, 10);
|
||||
_cursor += 2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::getDigit3 (int& result)
|
||||
{
|
||||
if (unicodeLatinDigit (_text[_cursor + 0]))
|
||||
{
|
||||
if (unicodeLatinDigit (_text[_cursor + 1]))
|
||||
{
|
||||
if (unicodeLatinDigit (_text[_cursor + 2]))
|
||||
{
|
||||
result = strtoimax (_text.substr (_cursor, 3).c_str (), NULL, 10);
|
||||
_cursor += 3;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::getDigit4 (int& result)
|
||||
{
|
||||
if (unicodeLatinDigit (_text[_cursor + 0]))
|
||||
{
|
||||
if (unicodeLatinDigit (_text[_cursor + 1]))
|
||||
{
|
||||
if (unicodeLatinDigit (_text[_cursor + 2]))
|
||||
{
|
||||
if (unicodeLatinDigit (_text[_cursor + 3]))
|
||||
{
|
||||
result = strtoimax (_text.substr (_cursor, 4).c_str (), NULL, 10);
|
||||
_cursor += 4;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::getDigits (int& result)
|
||||
{
|
||||
auto save = _cursor;
|
||||
|
||||
int c;
|
||||
auto prev = _cursor;
|
||||
while ((c = utf8_next_char (_text, _cursor)))
|
||||
{
|
||||
if (! unicodeLatinDigit (c))
|
||||
{
|
||||
_cursor = prev;
|
||||
break;
|
||||
}
|
||||
|
||||
prev = _cursor;
|
||||
}
|
||||
|
||||
if (_cursor > save)
|
||||
{
|
||||
result = std::strtoimax (_text.substr (save, _cursor - save).c_str (), NULL, 10);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::getHexDigit (int& result)
|
||||
{
|
||||
int c = _text[_cursor];
|
||||
if (c &&
|
||||
unicodeHexDigit (c))
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
result = c - '0';
|
||||
++_cursor;
|
||||
return true;
|
||||
}
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
{
|
||||
result = c - 'A' + 10;
|
||||
++_cursor;
|
||||
return true;
|
||||
}
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
{
|
||||
result = c - 'a' + 10;
|
||||
++_cursor;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// number:
|
||||
// int frac? exp?
|
||||
//
|
||||
// int:
|
||||
// (-|+)? digit+
|
||||
//
|
||||
// frac:
|
||||
// . digit+
|
||||
//
|
||||
// exp:
|
||||
// e digit+
|
||||
//
|
||||
// e:
|
||||
// e|E (+|-)?
|
||||
//
|
||||
bool Pig::getNumber (std::string& result)
|
||||
{
|
||||
auto i = _cursor;
|
||||
|
||||
// [+-]?
|
||||
if (_text[i] &&
|
||||
(_text[i] == '-' ||
|
||||
_text[i] == '+'))
|
||||
++i;
|
||||
|
||||
// digit+
|
||||
if (_text[i] &&
|
||||
unicodeLatinDigit (_text[i]))
|
||||
{
|
||||
++i;
|
||||
|
||||
while (_text[i] && unicodeLatinDigit (_text[i]))
|
||||
++i;
|
||||
|
||||
// ( . digit+ )?
|
||||
if (_text[i] && _text[i] == '.')
|
||||
{
|
||||
++i;
|
||||
|
||||
while (_text[i] && unicodeLatinDigit (_text[i]))
|
||||
++i;
|
||||
}
|
||||
|
||||
// ( [eE] [+-]? digit+ )?
|
||||
if (_text[i] &&
|
||||
(_text[i] == 'e' ||
|
||||
_text[i] == 'E'))
|
||||
{
|
||||
++i;
|
||||
|
||||
if (_text[i] &&
|
||||
(_text[i] == '+' ||
|
||||
_text[i] == '-'))
|
||||
++i;
|
||||
|
||||
if (_text[i] && unicodeLatinDigit (_text[i]))
|
||||
{
|
||||
++i;
|
||||
|
||||
while (_text[i] && unicodeLatinDigit (_text[i]))
|
||||
++i;
|
||||
|
||||
result = _text.substr (_cursor, i - _cursor);
|
||||
_cursor = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
result = _text.substr (_cursor, i - _cursor);
|
||||
_cursor = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::getNumber (double& result)
|
||||
{
|
||||
std::string s;
|
||||
if (getNumber (s))
|
||||
{
|
||||
result = std::strtof (s.c_str (), NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Gets quote content: "foobar" -> foobar (for c = '"')
|
||||
// Handles escaped quotes: "foo\"bar" -> foo\"bar (for c = '"')
|
||||
// Returns false if first character is not c, or if there is no closing c.
|
||||
// Does not modify content between quotes.
|
||||
bool Pig::getQuoted (int quote, std::string& result)
|
||||
{
|
||||
if (! _text[_cursor] ||
|
||||
_text[_cursor] != quote)
|
||||
return false;
|
||||
|
||||
auto start = _cursor + utf8_sequence (quote);
|
||||
auto i = start;
|
||||
|
||||
while (_text[i])
|
||||
{
|
||||
i = _text.find (quote, i);
|
||||
if (i == std::string::npos)
|
||||
return false; // Unclosed quote. Short cut, not definitive.
|
||||
|
||||
if (i == start)
|
||||
{
|
||||
// Empty quote
|
||||
_cursor += 2 * utf8_sequence (quote); // Skip both quote chars
|
||||
result = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_text[i - 1] == '\\')
|
||||
{
|
||||
// Check for escaped backslashes. Backtracking like this is not very
|
||||
// efficient, but is only done in extreme corner cases.
|
||||
|
||||
auto j = i - 2; // Start one character further left
|
||||
bool is_escaped_quote = true;
|
||||
while (j >= start && _text[j] == '\\')
|
||||
{
|
||||
// Toggle flag for each further backslash encountered.
|
||||
is_escaped_quote = is_escaped_quote ? false : true;
|
||||
--j;
|
||||
}
|
||||
|
||||
if (is_escaped_quote)
|
||||
{
|
||||
// Keep searching
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// None of the above applied, we must have found the closing quote char.
|
||||
result.assign (_text, start, i - start);
|
||||
_cursor = i + utf8_sequence (quote); // Skip closing quote char
|
||||
return true;
|
||||
}
|
||||
|
||||
// This should never be reached. We could throw here instead.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Assumes that the options are sorted by decreasing length, so that if the
|
||||
// options contain 'fourteen' and 'four', the stream is first matched against
|
||||
// the longer entry.
|
||||
bool Pig::getOneOf (
|
||||
const std::vector <std::string>& options,
|
||||
std::string& found)
|
||||
{
|
||||
for (const auto& option : options)
|
||||
{
|
||||
if (skipLiteral (option))
|
||||
{
|
||||
found = option;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::getRemainder (std::string& result)
|
||||
{
|
||||
if (_text[_cursor])
|
||||
{
|
||||
result = _text.substr (_cursor);
|
||||
_cursor += result.length ();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Pig::eos () const
|
||||
{
|
||||
return _text[_cursor] == '\0';
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Peeks ahead - does not move cursor.
|
||||
int Pig::peek () const
|
||||
{
|
||||
return _text[_cursor];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Peeks ahead - does not move cursor.
|
||||
std::string Pig::peek (const int quantity) const
|
||||
{
|
||||
if (_text[_cursor] &&
|
||||
_cursor + quantity <= _text.length ())
|
||||
return _text.substr (_cursor, quantity);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string::size_type Pig::cursor () const
|
||||
{
|
||||
return _cursor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Note: never called internally, otherwise the client cannot rely on iṫ.
|
||||
std::string::size_type Pig::save ()
|
||||
{
|
||||
return _saved = _cursor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Note: never called internally, otherwise the client cannot rely on iṫ.
|
||||
std::string::size_type Pig::restore ()
|
||||
{
|
||||
return _cursor = _saved;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Pig::dump () const
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "≪" << _text << "≫"
|
||||
<< " l" << _text.length ()
|
||||
<< " c" << _cursor;
|
||||
|
||||
return out.str ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
73
src/Pig.h
73
src/Pig.h
|
@ -1,73 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2015 - 2016, Paul Beckingham, Federico Hernandez.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDED_PIG
|
||||
#define INCLUDED_PIG
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Pig
|
||||
{
|
||||
public:
|
||||
explicit Pig (const std::string&);
|
||||
|
||||
bool skip (int);
|
||||
bool skipN (const int quantity = 1);
|
||||
bool skipWS ();
|
||||
bool skipLiteral (const std::string&);
|
||||
|
||||
bool getUntilWS (std::string&);
|
||||
bool getDigit (int&);
|
||||
bool getDigit2 (int&);
|
||||
bool getDigit3 (int&);
|
||||
bool getDigit4 (int&);
|
||||
bool getDigits (int&);
|
||||
bool getHexDigit (int&);
|
||||
bool getNumber (std::string&);
|
||||
bool getNumber (double&);
|
||||
bool getQuoted (int, std::string&);
|
||||
bool getOneOf (const std::vector <std::string>&, std::string&);
|
||||
bool getRemainder (std::string&);
|
||||
|
||||
bool eos () const;
|
||||
int peek () const;
|
||||
std::string peek (const int) const;
|
||||
std::string::size_type cursor () const;
|
||||
std::string::size_type save ();
|
||||
std::string::size_type restore ();
|
||||
|
||||
std::string dump () const;
|
||||
|
||||
private:
|
||||
const std::string& _text;
|
||||
std::string::size_type _cursor {0};
|
||||
std::string::size_type _saved {0};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
1
test/.gitignore
vendored
1
test/.gitignore
vendored
|
@ -2,5 +2,4 @@ all.log
|
|||
grammar.t
|
||||
lexer.t
|
||||
lr0.t
|
||||
pig.t
|
||||
rules.t
|
||||
|
|
|
@ -10,7 +10,7 @@ include_directories (${CMAKE_SOURCE_DIR}
|
|||
include_directories (${CMAKE_INSTALL_PREFIX}/include)
|
||||
link_directories(${CMAKE_INSTALL_PREFIX}/lib)
|
||||
|
||||
set (test_SRCS grammar.t lexer.t lr0.t pig.t rules.t)
|
||||
set (test_SRCS grammar.t lexer.t lr0.t rules.t)
|
||||
|
||||
add_custom_target (test ./run_all --verbose
|
||||
DEPENDS ${test_SRCS}
|
||||
|
|
244
test/pig.t.cpp
244
test/pig.t.cpp
|
@ -1,244 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2015 - 2016, Paul Beckingham, Federico Hernandez.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cmake.h>
|
||||
#include <Pig.h>
|
||||
#include <test.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int, char**)
|
||||
{
|
||||
UnitTest t (117);
|
||||
|
||||
// Pig::skip
|
||||
// Pig::skipN
|
||||
Pig p0 ("12345");
|
||||
t.notok (p0.skip ('0'), "skip='0', '12345' --> false");
|
||||
t.ok (p0.skip ('1'), "skip='1', '12345' --> true");
|
||||
t.is (p0.dump (), "≪12345≫ l5 c1", "dump: " + p0.dump ());
|
||||
|
||||
t.ok (p0.skipN (3), "skipN=3 '12345' --> true");
|
||||
t.is (p0.dump (), "≪12345≫ l5 c4", "dump: " + p0.dump ());
|
||||
|
||||
t.notok (p0.skipN (2), "skipN=2 '5' --> false");
|
||||
t.is (p0.dump (), "≪12345≫ l5 c4", "dump: " + p0.dump ());
|
||||
|
||||
// Pig::skipWS
|
||||
Pig p1 (" one");
|
||||
t.ok (p1.skipWS (), "skipWS ' one' --> true");
|
||||
t.is (p1.dump (), "≪ one≫ l5 c2", "dump: " + p1.dump ());
|
||||
|
||||
t.notok (p1.skipWS (), "skipWS 'one' --> false");
|
||||
t.is (p1.dump (), "≪ one≫ l5 c2", "dump: " + p1.dump ());
|
||||
|
||||
// Pig::skipLiteral
|
||||
Pig p2 ("onetwo");
|
||||
t.notok (p2.skipLiteral ("two"), "skipLiteral=two 'onetwo' --> false");
|
||||
t.ok (p2.skipLiteral ("one"), "skipLiteral=one 'onetwo' --> true");
|
||||
t.is (p2.dump (), "≪onetwo≫ l6 c3", "dump: " + p2.dump ());
|
||||
|
||||
// Pig::getUntilWS
|
||||
Pig p3 ("one two three");
|
||||
std::string value;
|
||||
t.ok (p3.getUntilWS (value), "getUntilWS 'one two three' --> true");
|
||||
t.is (value, "one", "getUntilWS 'one two three' --> 'one'");
|
||||
t.is (p3.dump (), "≪one two three≫ l13 c3", "dump: " + p3.dump ());
|
||||
|
||||
t.ok (p3.skipWS (), "skipWS ' two three' --> true");
|
||||
|
||||
t.ok (p3.getUntilWS (value), "getUntilWS 'two three' --> true");
|
||||
t.is (value, "two", "getUntilWS 'two three' --> 'two'");
|
||||
t.is (p3.dump (), "≪one two three≫ l13 c7", "dump: " + p3.dump ());
|
||||
|
||||
t.ok (p3.skipWS (), "skipWS ' three' --> true");
|
||||
|
||||
t.ok (p3.getUntilWS (value), "getUntilWS 'three' --> true");
|
||||
t.is (value, "three", "getUntilWS 'three' --> 'three'");
|
||||
t.is (p3.dump (), "≪one two three≫ l13 c13", "dump: " + p3.dump ());
|
||||
|
||||
// Pig::getDigit
|
||||
Pig p4 (" 123");
|
||||
int n;
|
||||
t.notok (p4.getDigit (n), "getDigit ' 123' --> false");
|
||||
t.ok (p4.skipWS (), "skipWS ' 123' --> true");
|
||||
t.is (p4.dump (), "≪ 123≫ l4 c1", "dump: " + p4.dump ());
|
||||
t.ok (p4.getDigit (n), "getDigit '123' --> true");
|
||||
t.is (n, 1, "getDigit '123' --> '1'");
|
||||
t.is (p4.dump (), "≪ 123≫ l4 c2", "dump: " + p4.dump ());
|
||||
|
||||
// Pig::getDigits
|
||||
Pig p5 ("123 ");
|
||||
t.ok (p5.getDigits (n), "getDigits '123 ' --> true");
|
||||
t.is (n, 123, "getDigits '123 ' --> 123");
|
||||
t.is (p5.dump (), "≪123 ≫ l4 c3", "dump: " + p5.dump ());
|
||||
|
||||
Pig p6 ("1");
|
||||
t.notok (p6.eos (), "eos '1' --> false");
|
||||
t.ok (p6.getDigit (n), "getDigit '1' --> true");
|
||||
t.notok (p6.getDigit (n), "getDigit '' --> false");
|
||||
t.ok (p6.eos (), "eos '' --> true");
|
||||
t.is (p6.dump (), "≪1≫ l1 c1", "dump: " + p6.dump ());
|
||||
|
||||
// Pig::getNumber
|
||||
Pig p7 ("1 ");
|
||||
t.ok (p7.getNumber (value), "getNumber '1 ' --> true");
|
||||
t.is (value, "1", "getNumber '1 ' --> '1'");
|
||||
t.is (p7.dump (), "≪1 ≫ l2 c1", "dump: " + p7.dump ());
|
||||
|
||||
Pig p8 ("3.14");
|
||||
t.ok (p8.getNumber (value), "getNumber '3.14' --> true");
|
||||
t.is (value, "3.14", "getNumber '3.14' --> '3.14'");
|
||||
t.is (p8.dump (), "≪3.14≫ l4 c4", "dump: " + p8.dump ());
|
||||
|
||||
Pig p9 ("1.23e-4 ");
|
||||
t.ok (p9.getNumber (value), "getNumber '1.23e-4 ' --> true");
|
||||
t.is (value, "1.23e-4", "getNumber '1.23e-4 ' --> '1.23e-4'");
|
||||
t.is (p9.dump (), "≪1.23e-4 ≫ l8 c7", "dump: " + p9.dump ());
|
||||
|
||||
Pig p10 ("2.34e-5");
|
||||
double dvalue;
|
||||
t.ok (p10.getNumber (dvalue), "getNumber '2.34e-5' --> true");
|
||||
t.is (dvalue, 2.34e-5, 1e-6, "getNumber '2.34e-5' --> 2.34e-5 +/- 1e-6");
|
||||
t.is (p10.dump (), "≪2.34e-5≫ l7 c7", "dump: " + p10.dump ());
|
||||
|
||||
// Pig::getRemainder
|
||||
Pig p11 ("123");
|
||||
t.ok (p11.skipN (1), "skipN=1 '123' --> true");
|
||||
t.is (p11.dump (), "≪123≫ l3 c1", "dump: " + p11.dump ());
|
||||
|
||||
t.ok (p11.getRemainder (value), "getRemainder '23' --> true");
|
||||
t.is (value, "23", "getRemainder '23' --> '23'");
|
||||
t.is (p11.dump (), "≪123≫ l3 c3", "dump: " + p11.dump ());
|
||||
|
||||
t.notok (p11.getRemainder (value), "getRemainder '' --> false");
|
||||
t.is (p11.dump (), "≪123≫ l3 c3", "dump: " + p11.dump ());
|
||||
|
||||
// Pig::peek
|
||||
Pig p12 ("123");
|
||||
t.is (p12.peek (), '1', "peek '123' --> '1'");
|
||||
t.is (p12.dump (), "≪123≫ l3 c0", "dump: " + p12.dump ());
|
||||
t.is (p12.peek (2), "12", "peek=2 '123' --> '12'");
|
||||
t.is (p12.dump (), "≪123≫ l3 c0", "dump: " + p12.dump ());
|
||||
|
||||
// Pig::save, Pig::restore
|
||||
Pig p13 ("123");
|
||||
t.is ((int)p13.save (), 0, "save '123' --> 0");
|
||||
t.ok (p13.skipN (2), "skipN=2 '123' --> true");
|
||||
t.is (p13.dump (), "≪123≫ l3 c2", "dump: " + p13.dump ());
|
||||
t.is ((int)p13.cursor (), 2, "cursor '123' --> 2");
|
||||
t.is ((int)p13.restore (), 0, "restore '123' --> 0");
|
||||
t.is (p13.dump (), "≪123≫ l3 c0", "dump: " + p13.dump ());
|
||||
|
||||
// Pig::getOneOf
|
||||
Pig p14 ("fourteenfour five");
|
||||
t.ok (p14.getOneOf ({"fourteen", "four"}, value), "getOneOf={fourteen,four} 'fourteenfour five' --> true");
|
||||
t.is (value, "fourteen", "getOneOf={fourteen,four} 'fourteenfour five' --> 'fourteen'");
|
||||
t.ok (p14.getOneOf ({"fourteen", "four"}, value), "getOneOf={fourteen,four} 'fourteenfour five' --> true");
|
||||
t.is (value, "four", "getOneOf={fourteen,four} 'fourteenfour five' --> 'four'");
|
||||
t.is (p14.dump (), "≪fourteenfour five≫ l17 c12", "dump: " + p14.dump ());
|
||||
t.notok (p14.getOneOf ({"five"}, value), "getOneOf={five} 'fourteenfour five' --> false");
|
||||
t.is (p14.dump (), "≪fourteenfour five≫ l17 c12", "dump: " + p14.dump ());
|
||||
|
||||
// Pig::getHexDigit
|
||||
Pig p15 (" 9aF");
|
||||
t.notok (p15.getHexDigit (n), "getHexDigit ' 9aF' --> false");
|
||||
t.ok (p15.skipWS (), "skipWS ' 9aF' --> true");
|
||||
t.is (p15.dump (), "≪ 9aF≫ l4 c1", "dump: " + p15.dump ());
|
||||
t.ok (p15.getHexDigit (n), "getHexDigit '9aF' --> true");
|
||||
t.is (n, 9, "getHexDigit '9aF' --> '9'");
|
||||
t.is (p15.dump (), "≪ 9aF≫ l4 c2", "dump: " + p15.dump ());
|
||||
|
||||
t.ok (p15.getHexDigit (n), "getHexDigit '9aF' --> true");
|
||||
t.is (n, 10, "getHexDigit '9aF' --> '10'");
|
||||
t.is (p15.dump (), "≪ 9aF≫ l4 c3", "dump: " + p15.dump ());
|
||||
|
||||
t.ok (p15.getHexDigit (n), "getHexDigit '9aF' --> true");
|
||||
t.is (n, 15, "getHexDigit '9aF' --> '15'");
|
||||
t.is (p15.dump (), "≪ 9aF≫ l4 c4", "dump: " + p15.dump ());
|
||||
|
||||
// Pig::getQuoted
|
||||
Pig p16 ("");
|
||||
t.notok (p16.getQuoted ('"', value), " \"\" : getQuoted ('\"') --> false");
|
||||
|
||||
Pig p17 ("''");
|
||||
t.ok (p17.getQuoted ('\'', value), " \"''\" : getQuoted ('\\'') --> true");
|
||||
t.is (value, "", " \"''\" : getQuoted ('\\'') --> ''");
|
||||
|
||||
Pig p18 ("'\"'");
|
||||
t.ok (p18.getQuoted ('\'', value), " \"'\"'\" : getQuoted ('\\'') --> true");
|
||||
t.is (value, "\"", " \"'\"'\" : getQuoted ('\\'') --> '\"'");
|
||||
|
||||
Pig p19 ("'x'");
|
||||
t.ok (p19.getQuoted ('\'', value), " \"'x'\" : getQuoted ('\\'') --> true");
|
||||
t.is (value, "x", " \"'x'\" : getQuoted ('\\'') --> \"x\"");
|
||||
|
||||
Pig p20 ("'x");
|
||||
t.notok (p20.getQuoted ('\'', value), " \"'x\" : getQuoted ('\\'') --> false");
|
||||
|
||||
Pig p21 ("x");
|
||||
t.notok (p21.getQuoted ('\'', value), " 'x' : getQuoted ('\\'') --> false");
|
||||
|
||||
Pig p22 ("\"one\\\"two\"");
|
||||
t.notok (p22.getQuoted ('\'', value), " \"one\\\"two\" : getQuoted ('\\'') --> false");
|
||||
t.ok (p22.getQuoted ('"', value), " \"one\\\"two\" : getQuoted ('\"') --> true");
|
||||
t.is (value, "one\\\"two", " \"one\\\"two\" : getQuoted ('\"') --> \"one\\\"two\"");
|
||||
|
||||
Pig p23 ("\"one\\\\\"");
|
||||
t.ok (p23.getQuoted ('\"', value), " \"one\\\\\"\" : getQuoted ('\"') --> true");
|
||||
t.is (value, "one\\\\", " \"one\\\\\"\" : getQuoted ('\"') --> \"one\\\\\"");
|
||||
|
||||
// Pig::getDigit1
|
||||
// Pig::getDigit2
|
||||
// Pig::getDigit3
|
||||
// Pig::getDigit4
|
||||
// Pig::getDigits
|
||||
Pig p24 ("122333444455555555");
|
||||
t.ok (p24.getDigit (n), "getDigit '122333444455555555' --> true");
|
||||
t.is (n, 1, "getDigit '122333444455555555' --> 1");
|
||||
t.is (p24.dump (), "≪122333444455555555≫ l18 c1", "dump: " + p24.dump ());
|
||||
|
||||
t.ok (p24.getDigit2 (n), "getDigit2 '22333444455555555' --> true");
|
||||
t.is (n, 22, "getDigit2 '22333444455555555' --> 22");
|
||||
t.is (p24.dump (), "≪122333444455555555≫ l18 c3", "dump: " + p24.dump ());
|
||||
|
||||
t.ok (p24.getDigit3 (n), "getDigit3 '22333444455555555' --> true");
|
||||
t.is (n, 333, "getDigit3 '22333444455555555' --> 333");
|
||||
t.is (p24.dump (), "≪122333444455555555≫ l18 c6", "dump: " + p24.dump ());
|
||||
|
||||
t.ok (p24.getDigit4 (n), "getDigit4 '22333444455555555' --> true");
|
||||
t.is (n, 4444, "getDigit4 '22333444455555555' --> 4444");
|
||||
t.is (p24.dump (), "≪122333444455555555≫ l18 c10", "dump: " + p24.dump ());
|
||||
|
||||
t.ok (p24.getDigits (n), "getDigits '22333444455555555' --> true");
|
||||
t.is (n, 55555555, "getDigits '22333444455555555' --> 55555555");
|
||||
t.is (p24.dump (), "≪122333444455555555≫ l18 c18", "dump: " + p24.dump ());
|
||||
|
||||
t.ok (p24.eos (), "eos --> true");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
Loading…
Add table
Add a link
Reference in a new issue