From bd35981febb03a4d492cd07894c095d37f2a1294 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Fri, 4 Oct 2019 17:50:55 +0200
Subject: [PATCH] ENH: stringOps::toScalar improvements

- add floor/ceil/round methods
- support evaluation of sub-strings

STYLE: add blockMeshDict1.calc, blockMeshDict1.eval test dictionaries

- useful for testing and simple demonstration of equivalence
---
 .../test/dictionary/blockMeshDict1.calc       |  117 ++
 .../test/dictionary/blockMeshDict1.eval       |  117 ++
 .../strings/parsing/genericRagelLemonDriver.C |   74 +-
 .../strings/parsing/genericRagelLemonDriver.H |   38 +-
 .../stringOps/toScalar/evalStringToScalar.H   |    9 +-
 .../toScalar/evalStringToScalarDriver.C       |   19 +-
 .../toScalar/evalStringToScalarDriver.H       |   10 +-
 .../toScalar/evalStringToScalarLemonParser.h  |    5 +-
 .../evalStringToScalarLemonParser.lyy         |   15 +
 .../toScalar/evalStringToScalarScanner.H      |   23 +-
 .../toScalar/evalStringToScalarScanner.cc     | 1121 +++++++++--------
 .../toScalar/evalStringToScalarScanner.rl     |   90 +-
 12 files changed, 1040 insertions(+), 598 deletions(-)
 create mode 100644 applications/test/dictionary/blockMeshDict1.calc
 create mode 100644 applications/test/dictionary/blockMeshDict1.eval

diff --git a/applications/test/dictionary/blockMeshDict1.calc b/applications/test/dictionary/blockMeshDict1.calc
new file mode 100644
index 00000000000..b00fa59f12b
--- /dev/null
+++ b/applications/test/dictionary/blockMeshDict1.calc
@@ -0,0 +1,117 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v1906                                 |
+|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// incompressible/simpleFoam/pipeCyclic/system/blockMeshDict
+
+scale   1;
+
+//- Half angle of wedge in degrees
+halfAngle 45.0;
+
+//- Radius of pipe [m]
+radius  0.5;
+
+y               #calc #{ $radius*sin(degToRad($halfAngle)) #};
+minY            #calc #{ -1.0*$y #};
+z               #calc #{ $radius*cos(degToRad($halfAngle)) #};
+minZ            #calc #{ -1.0*$z #};
+
+vertices
+(
+    (0.0    0.0 0)      //0
+    (10     0.0 0)
+    (10     0.0 0)      //2
+    (0.0    0.0 0)
+
+    (0.0    $minY $z)   //4
+    (10     $minY $z)
+    (10     $y $z)      //6
+    (0.0    $y $z)
+
+);
+
+blocks
+(
+    // inlet block
+    hex (0 1 2 3  4 5 6 7) (50 5 5) simpleGrading (1 1 1)
+);
+
+edges
+(
+    arc 4 7 (0 0 $radius)
+    arc 5 6 (10 0 $radius)
+);
+
+boundary
+(
+    inlet
+    {
+        type patch;
+        faces
+        (
+            (0 4 7 3)
+        );
+    }
+
+    outlet
+    {
+        type patch;
+        faces
+        (
+            (1 2 6 5)
+        );
+    }
+
+    side1
+    {
+        type cyclicAMI;
+        neighbourPatch side2;
+        faces
+        (
+            (0 1 5 4)
+        );
+
+        transform rotational;
+        rotationAxis (1 0 0);
+        rotationCentre (0 0 0);
+    }
+
+    side2
+    {
+        type cyclicAMI;
+        neighbourPatch side1;
+        faces
+        (
+            (7 6 2 3)
+        );
+
+        transform rotational;
+        rotationAxis (1 0 0);
+        rotationCentre (0 0 0);
+    }
+
+    walls
+    {
+        type wall;
+        faces
+        (
+            (4 5 6 7)
+            (3 2 1 0)
+        );
+    }
+);
+
+
+// ************************************************************************* //
diff --git a/applications/test/dictionary/blockMeshDict1.eval b/applications/test/dictionary/blockMeshDict1.eval
new file mode 100644
index 00000000000..839aee0eccd
--- /dev/null
+++ b/applications/test/dictionary/blockMeshDict1.eval
@@ -0,0 +1,117 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  v1906                                 |
+|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// incompressible/simpleFoam/pipeCyclic/system/blockMeshDict
+
+scale   1;
+
+//- Half angle of wedge in degrees
+halfAngle 45.0;
+
+//- Radius of pipe [m]
+radius  0.5;
+
+y               #eval{ $radius*sin(degToRad($halfAngle)) };
+minY            #eval{ -1*$y };
+z               #eval{ $radius*cos(degToRad($halfAngle)) };
+minZ            #eval{ -1*$z };
+
+vertices
+(
+    (0.0    0.0 0)      //0
+    (10     0.0 0)
+    (10     0.0 0)      //2
+    (0.0    0.0 0)
+
+    (0.0    $minY $z)   //4
+    (10     $minY $z)
+    (10     $y $z)      //6
+    (0.0    $y $z)
+
+);
+
+blocks
+(
+    // inlet block
+    hex (0 1 2 3  4 5 6 7) (50 5 5) simpleGrading (1 1 1)
+);
+
+edges
+(
+    arc 4 7 (0 0 $radius)
+    arc 5 6 (10 0 $radius)
+);
+
+boundary
+(
+    inlet
+    {
+        type patch;
+        faces
+        (
+            (0 4 7 3)
+        );
+    }
+
+    outlet
+    {
+        type patch;
+        faces
+        (
+            (1 2 6 5)
+        );
+    }
+
+    side1
+    {
+        type cyclicAMI;
+        neighbourPatch side2;
+        faces
+        (
+            (0 1 5 4)
+        );
+
+        transform rotational;
+        rotationAxis (1 0 0);
+        rotationCentre (0 0 0);
+    }
+
+    side2
+    {
+        type cyclicAMI;
+        neighbourPatch side1;
+        faces
+        (
+            (7 6 2 3)
+        );
+
+        transform rotational;
+        rotationAxis (1 0 0);
+        rotationCentre (0 0 0);
+    }
+
+    walls
+    {
+        type wall;
+        faces
+        (
+            (4 5 6 7)
+            (3 2 1 0)
+        );
+    }
+);
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.C b/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.C
index 1ce3749cfde..db0bf567592 100644
--- a/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.C
+++ b/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.C
@@ -31,22 +31,84 @@ License
 
 Foam::parsing::genericRagelLemonDriver::genericRagelLemonDriver()
 :
-    content_(std::cref<std::string>(string::null)),
+    content_(std::cref<std::string>(Foam::string::null)),
+    start_(0),
+    length_(0),
     position_(0)
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void Foam::parsing::genericRagelLemonDriver::clear()
+{
+    content_ = std::cref<std::string>(Foam::string::null);
+    start_ = 0;
+    length_ = 0;
+    position_ = 0;
+}
+
+
+void Foam::parsing::genericRagelLemonDriver::content
+(
+    const std::string& s,
+    size_t pos,
+    size_t len
+)
+{
+    content_ = std::cref<std::string>(s);
+    start_ = pos;
+    length_ = len;
+    position_ = 0;
+}
+
+
+std::string::const_iterator
+Foam::parsing::genericRagelLemonDriver::cbegin() const
+{
+    const std::string& s = content_.get();
+
+    if (start_ >= s.length())
+    {
+        return s.cend();
+    }
+
+    return s.cbegin() + start_;
+}
+
+
+std::string::const_iterator
+Foam::parsing::genericRagelLemonDriver::cend() const
+{
+    const std::string& s = content_.get();
+
+    if (length_ == std::string::npos || start_ >= s.length())
+    {
+        return s.cend();
+    }
+
+    const size_t strEnd = start_ + length_;
+
+    if (strEnd >= s.length())
+    {
+        return s.cend();
+    }
+
+    return s.cbegin() + strEnd;
+}
+
+
 Foam::Ostream& Foam::parsing::genericRagelLemonDriver::printBuffer
 (
     Ostream& os
 ) const
 {
-    const std::string& s = content_.get();
+    const auto endIter = cend();
 
-    for (char c : s)
+    for (auto iter = cbegin(); iter != endIter; ++iter)
     {
+        char c(*iter);
+
         // if (!c) break;
 
         if (c == '\t')
@@ -111,9 +173,10 @@ void Foam::parsing::genericRagelLemonDriver::reportFatal
         << " in expression at position:" << long(pos) << nl
         << "<<<<\n";
 
-    const auto begIter = content().cbegin();
-    const auto endIter = content().cend();
+    const auto begIter = cbegin();
+    const auto endIter = cend();
 
+    // Position of newline(s)
     size_t newline0 = 0, newline1 = 0;
 
     auto iter = begIter;
@@ -157,6 +220,7 @@ void Foam::parsing::genericRagelLemonDriver::reportFatal
     size_t col = std::min(newline0, newline1);
     if (col < pos)
     {
+        // This still isn't quite right
         col = pos - col;
         if (col) --col;
 
diff --git a/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.H b/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.H
index b093178f165..e762a266d79 100644
--- a/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.H
+++ b/src/OpenFOAM/primitives/strings/parsing/genericRagelLemonDriver.H
@@ -26,7 +26,7 @@ Class
 
 Description
     Generic interface code for Ragel/Lemon combination
-    Subclasses should implement the process() method.
+    Subclasses should implement one or more process() methods.
 
     The scanner will often be implemented as localized lexer class.
     The parser may be embedded into the scanner as file-scope, or
@@ -64,6 +64,12 @@ protected:
         //- Reference to the input string
         std::reference_wrapper<const std::string> content_;
 
+        //- Start position within input string
+        size_t start_;
+
+        //- Length of input (sub)string
+        size_t length_;
+
         //- The last known parser position
         size_t position_;
 
@@ -96,11 +102,7 @@ public:
     // Member Functions
 
         //- Reset references
-        void clear()
-        {
-            content_ = std::cref<std::string>(string::null);
-            position_ = 0;
-        }
+        void clear();
 
         //- Get reference to the input buffer content
         const std::string& content() const
@@ -108,20 +110,28 @@ public:
             return content_.get();
         }
 
-        //- Set reference to the input buffer content
-        void content(const std::string& s)
-        {
-            content_ = std::cref<std::string>(s);
-            position_ = 0;
-        }
+        //- Set reference to the input buffer content,
+        //- which acts like a std::string_view
+        void content
+        (
+            const std::string& s,
+            size_t pos = 0,
+            size_t len = std::string::npos
+        );
+
+        //- Iterator to begin of content (sub)string
+        std::string::const_iterator cbegin() const;
+
+        //- Iterator to end of content (sub)string
+        std::string::const_iterator cend() const;
 
-        //- The last parse position
+        //- The relative parse position with the content (sub)string
         size_t parsePosition() const
         {
             return position_;
         }
 
-        //- The last parse position
+        //- The relative parse position with the content (sub)string
         size_t& parsePosition()
         {
             return position_;
diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalar.H b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalar.H
index 2415a2248c6..e04d7d2cac7 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalar.H
+++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalar.H
@@ -51,10 +51,15 @@ namespace stringOps
     //  - hyperbolic:  sinh, cosh, tanh
     //  - conversions:  degToRad, radToDeg
     //  - constants:  pi()
-    //  - misc: rand(), rand(seed)
+    //  - misc: floor, ceil, round, rand, rand(seed)
     //
     //  \note The rand() function returns a uniform scalar on [0-1] interval
-    scalar toScalar(const std::string& s);
+    scalar toScalar
+    (
+        const std::string& s,
+        size_t pos = 0,
+        size_t len = std::string::npos
+    );
 
 } // End namespace stringOps
 
diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.C b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.C
index f6bbf9be44a..ac99cccd564 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.C
+++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.C
@@ -21,10 +21,6 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-Description
-    Ragel lexer interface for lemon grammar of a simple string to
-    scalar evaluation
-
 \*---------------------------------------------------------------------------*/
 
 #include "evalStringToScalar.H"
@@ -45,12 +41,14 @@ Foam::parsing::evalStringToScalar::parseDriver::parseDriver()
 
 Foam::scalar Foam::parsing::evalStringToScalar::parseDriver::execute
 (
-    const std::string& s
+    const std::string& s,
+    size_t pos,
+    size_t len
 )
 {
     // scanner::debug = 1;
 
-    scanner().process(s, *this);
+    scanner().process(s, pos, len, *this);
 
     return value_;
 }
@@ -58,11 +56,16 @@ Foam::scalar Foam::parsing::evalStringToScalar::parseDriver::execute
 
 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
 
-Foam::scalar Foam::stringOps::toScalar(const std::string& s)
+Foam::scalar Foam::stringOps::toScalar
+(
+    const std::string& s,
+    size_t pos,
+    size_t len
+)
 {
     Foam::parsing::evalStringToScalar::parseDriver driver;
 
-    scalar val = driver.execute(s);
+    scalar val = driver.execute(s, pos, len);
     // val = driver.value();
 
     return val;
diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.H b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.H
index 58ed93e1631..fb7fddec7e8 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.H
+++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarDriver.H
@@ -89,8 +89,14 @@ public:
 
     // Member Functions
 
-        // Perform parsing on string
-        scalar execute(const std::string& s);
+        //- Perform parsing on (sub) string
+        //  \return evaluated value
+        scalar execute
+        (
+            const std::string& s,
+            size_t strPos = 0,
+            size_t strLen = std::string::npos
+        );
 
         //- Get value
         scalar value() const
diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.h b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.h
index e068ad5c1d9..e4bb0f674a9 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.h
+++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.h
@@ -32,4 +32,7 @@
 #define TOK_MAX                             32
 #define TOK_MAG                             33
 #define TOK_MAGSQR                          34
-#define TOK_RAND                            35
+#define TOK_FLOOR                           35
+#define TOK_CEIL                            36
+#define TOK_ROUND                           37
+#define TOK_RAND                            38
diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.lyy b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.lyy
index 2b89c899863..9386e0ecf6c 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.lyy
+++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarLemonParser.lyy
@@ -237,6 +237,21 @@ exp(lhs) ::= MAGSQR LPAREN exp(a) RPAREN.
     lhs = Foam::magSqr(a);
 }
 
+exp(lhs) ::= FLOOR LPAREN exp(a) RPAREN.
+{
+    lhs = std::floor(a);
+}
+
+exp(lhs) ::= CEIL LPAREN exp(a) RPAREN.
+{
+    lhs = std::ceil(a);
+}
+
+exp(lhs) ::= ROUND LPAREN exp(a) RPAREN.
+{
+    lhs = std::round(a);
+}
+
 exp(lhs) ::= RAND LPAREN RPAREN.
 {
     lhs = Foam::Random().sample01<Foam::scalar>();
diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.H b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.H
index 84e4492f338..770a6370193 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.H
+++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.H
@@ -81,10 +81,31 @@ public:
 
     // Member Functions
 
+        //- Evaluate sub-string
+        bool process
+        (
+            const std::string& str, size_t pos, size_t len,
+            parseDriver& driver
+        );
+
+        //- Evaluate sub-string
+        bool process
+        (
+            const std::string& str, size_t pos,
+            parseDriver& driver
+        )
+        {
+            return process(str, pos, std::string::npos, driver);
+        }
+
         //- Evaluate string
-        bool process(const std::string& str, parseDriver& driver);
+        bool process(const std::string& str, parseDriver& driver)
+        {
+            return process(str, 0, std::string::npos, driver);
+        }
 };
 
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace evalStringToScalar
diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.cc b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.cc
index 4548dd8dd65..473543ff779 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.cc
+++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.cc
@@ -58,11 +58,11 @@ int Foam::parsing::evalStringToScalar::scanner::debug = 0;
 
 
 #line 61 "evalStringToScalarScanner.cc"
-static const int evalScanner_start = 86;
-static const int evalScanner_first_final = 86;
+static const int evalScanner_start = 96;
+static const int evalScanner_first_final = 96;
 static const int evalScanner_error = 0;
 
-static const int evalScanner_en_main = 86;
+static const int evalScanner_en_main = 96;
 
 
 #line 60 "evalStringToScalarScanner.rl"
@@ -70,14 +70,14 @@ static const int evalScanner_en_main = 86;
 
 #define TOKEN_OF(T)         TOK_##T
 #define EMIT_TOKEN(T)                                                         \
-    /* Inform driver of last position */                                      \
-    driver.parsePosition() = (p-buf);                                         \
+    driver.parsePosition() = (ts-buf);                                        \
     DebugInfo<< "TOKEN_" #T << " at " << driver.parsePosition() << nl;        \
-    parser_->parse(TOKEN_OF(T), 0)
+    parser_->parse(TOKEN_OF(T), 0);                                           \
+    driver.parsePosition() = (p-buf);
 
 
 
-#line 163 "evalStringToScalarScanner.rl"
+#line 149 "evalStringToScalarScanner.rl"
 
 
 
@@ -92,11 +92,13 @@ Foam::parsing::evalStringToScalar::scanner::~scanner()
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 bool Foam::parsing::evalStringToScalar::scanner::process
 (
     const std::string& str,
+    size_t strBeg,
+    size_t strLen,
     parseDriver& driver
 )
 {
@@ -105,7 +107,25 @@ bool Foam::parsing::evalStringToScalar::scanner::process
         parser_ = new parser();
     }
 
-    driver.content(str);
+    driver.content(str, strBeg, strLen);
+
+    size_t strEnd = str.length();
+
+    if (strBeg > str.length())
+    {
+        strBeg = str.length();
+    }
+    else if (strLen != std::string::npos)
+    {
+        strLen += strBeg;
+
+        if (strLen < str.length())
+        {
+            strEnd = strLen;
+        }
+    }
+
+
     parser_->start(driver);
 
     // Ragel token start/end (required naming)
@@ -116,14 +136,14 @@ bool Foam::parsing::evalStringToScalar::scanner::process
     // - p, pe, eof are required Ragel naming
     // - buf is our own naming
 
-    const char* buf = &(str[0]);
-    const char* eof = &(str[str.length()]);
+    const char* buf = &(str[strBeg]);
+    const char* eof = &(str[strEnd]);
     const char* p = buf;
     const char* pe = eof;
 
     // Initialize FSM variables
     
-#line 127 "evalStringToScalarScanner.cc"
+#line 147 "evalStringToScalarScanner.cc"
 	{
 	cs = evalScanner_start;
 	ts = 0;
@@ -131,27 +151,26 @@ bool Foam::parsing::evalStringToScalar::scanner::process
 	act = 0;
 	}
 
-#line 207 "evalStringToScalarScanner.rl"
+#line 213 "evalStringToScalarScanner.rl"
    /* ^^^ FSM initialization here ^^^ */;
 
     
-#line 139 "evalStringToScalarScanner.cc"
+#line 159 "evalStringToScalarScanner.cc"
 	{
 	if ( p == pe )
 		goto _test_eof;
 	switch ( cs )
 	{
 tr2:
-#line 86 "evalStringToScalarScanner.rl"
+#line 73 "evalStringToScalarScanner.rl"
 	{{p = ((te))-1;}{
-        // Inform driver of last position
-        driver.parsePosition() = (p-buf);
+        driver.parsePosition() = (ts-buf);
 
         DebugInfo
-            << "NUMBER:" << std::string(ts, te-ts).c_str()
+            << "Number:" << std::string(ts, te-ts).c_str()
             << " at " << driver.parsePosition() << nl;
 
-        scalar val;
+        scalar val(0);
 
         if (readScalar(std::string(ts, te-ts), val))
         {
@@ -160,230 +179,243 @@ tr2:
         }
         else
         {
-            driver.reportFatal("Error reading scalar value");
+            // Catch range errors
+            driver.reportFatal("Error parsing number");
         }
-    }}
-	goto st86;
-tr5:
-#line 157 "evalStringToScalarScanner.rl"
-	{{p = ((te))-1;}}
-	goto st86;
-tr8:
-#line 74 "evalStringToScalarScanner.rl"
-	{
-        // Inform driver of last position
+
         driver.parsePosition() = (p-buf);
-    }
-#line 159 "evalStringToScalarScanner.rl"
-	{te = p+1;}
-	goto st86;
-tr14:
-#line 127 "evalStringToScalarScanner.rl"
+    }}
+	goto st96;
+tr10:
+#line 125 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(ACOS); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr17:
-#line 126 "evalStringToScalarScanner.rl"
+	goto st96;
+tr13:
+#line 124 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(ASIN); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr21:
-#line 128 "evalStringToScalarScanner.rl"
+	goto st96;
+tr17:
+#line 126 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(ATAN); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr23:
-#line 129 "evalStringToScalarScanner.rl"
+	goto st96;
+tr19:
+#line 127 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(ATAN2); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr28:
-#line 122 "evalStringToScalarScanner.rl"
+	goto st96;
+tr25:
+#line 120 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(CBRT); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
+	goto st96;
+tr28:
+#line 137 "evalStringToScalarScanner.rl"
+	{ p--; EMIT_TOKEN(CEIL); }
+#line 146 "evalStringToScalarScanner.rl"
+	{te = p+1;}
+	goto st96;
 tr31:
-#line 124 "evalStringToScalarScanner.rl"
+#line 122 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(COS); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
+	goto st96;
 tr33:
-#line 132 "evalStringToScalarScanner.rl"
+#line 130 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(COSH); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
+	goto st96;
 tr41:
-#line 114 "evalStringToScalarScanner.rl"
+#line 112 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(DEG_TO_RAD); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
+	goto st96;
 tr44:
-#line 116 "evalStringToScalarScanner.rl"
+#line 114 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(EXP); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
+	goto st96;
 tr49:
-#line 130 "evalStringToScalarScanner.rl"
+#line 136 "evalStringToScalarScanner.rl"
+	{ p--; EMIT_TOKEN(FLOOR); }
+#line 146 "evalStringToScalarScanner.rl"
+	{te = p+1;}
+	goto st96;
+tr54:
+#line 128 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(HYPOT); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr53:
-#line 117 "evalStringToScalarScanner.rl"
+	goto st96;
+tr58:
+#line 115 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(LOG); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr56:
-#line 118 "evalStringToScalarScanner.rl"
+	goto st96;
+tr61:
+#line 116 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(LOG10); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr62:
-#line 136 "evalStringToScalarScanner.rl"
+	goto st96;
+tr67:
+#line 134 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(MAG); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr66:
-#line 137 "evalStringToScalarScanner.rl"
+	goto st96;
+tr71:
+#line 135 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(MAGSQR); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr67:
-#line 135 "evalStringToScalarScanner.rl"
+	goto st96;
+tr72:
+#line 133 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(MAX); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr69:
-#line 134 "evalStringToScalarScanner.rl"
+	goto st96;
+tr74:
+#line 132 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(MIN); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr72:
-#line 113 "evalStringToScalarScanner.rl"
+	goto st96;
+tr77:
+#line 111 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(PI); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr74:
-#line 119 "evalStringToScalarScanner.rl"
+	goto st96;
+tr79:
+#line 117 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(POW); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr83:
-#line 115 "evalStringToScalarScanner.rl"
+	goto st96;
+tr89:
+#line 113 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(RAD_TO_DEG); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr85:
-#line 138 "evalStringToScalarScanner.rl"
+	goto st96;
+tr91:
+#line 139 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(RAND); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr90:
-#line 123 "evalStringToScalarScanner.rl"
+	goto st96;
+tr95:
+#line 138 "evalStringToScalarScanner.rl"
+	{ p--; EMIT_TOKEN(ROUND); }
+#line 146 "evalStringToScalarScanner.rl"
+	{te = p+1;}
+	goto st96;
+tr100:
+#line 121 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(SIN); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr92:
-#line 131 "evalStringToScalarScanner.rl"
+	goto st96;
+tr102:
+#line 129 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(SINH); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr95:
-#line 120 "evalStringToScalarScanner.rl"
+	goto st96;
+tr105:
+#line 118 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(SQR); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr97:
-#line 121 "evalStringToScalarScanner.rl"
+	goto st96;
+tr107:
+#line 119 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(SQRT); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr101:
-#line 125 "evalStringToScalarScanner.rl"
+	goto st96;
+tr111:
+#line 123 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(TAN); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr103:
-#line 133 "evalStringToScalarScanner.rl"
+	goto st96;
+tr113:
+#line 131 "evalStringToScalarScanner.rl"
 	{ p--; EMIT_TOKEN(TANH); }
-#line 156 "evalStringToScalarScanner.rl"
+#line 146 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr105:
-#line 142 "evalStringToScalarScanner.rl"
+	goto st96;
+tr115:
+#line 101 "evalStringToScalarScanner.rl"
 	{ EMIT_TOKEN(LPAREN); }
-#line 157 "evalStringToScalarScanner.rl"
+#line 145 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr106:
-#line 143 "evalStringToScalarScanner.rl"
+	goto st96;
+tr116:
+#line 102 "evalStringToScalarScanner.rl"
 	{ EMIT_TOKEN(RPAREN); }
-#line 157 "evalStringToScalarScanner.rl"
+#line 145 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr107:
-#line 146 "evalStringToScalarScanner.rl"
+	goto st96;
+tr117:
+#line 105 "evalStringToScalarScanner.rl"
 	{ EMIT_TOKEN(TIMES); }
-#line 157 "evalStringToScalarScanner.rl"
+#line 145 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr108:
-#line 144 "evalStringToScalarScanner.rl"
+	goto st96;
+tr118:
+#line 103 "evalStringToScalarScanner.rl"
 	{ EMIT_TOKEN(PLUS); }
-#line 157 "evalStringToScalarScanner.rl"
+#line 145 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr109:
-#line 148 "evalStringToScalarScanner.rl"
+	goto st96;
+tr119:
+#line 107 "evalStringToScalarScanner.rl"
 	{ EMIT_TOKEN(COMMA); }
-#line 157 "evalStringToScalarScanner.rl"
-	{te = p+1;}
-	goto st86;
-tr110:
 #line 145 "evalStringToScalarScanner.rl"
+	{te = p+1;}
+	goto st96;
+tr120:
+#line 104 "evalStringToScalarScanner.rl"
 	{ EMIT_TOKEN(MINUS); }
-#line 157 "evalStringToScalarScanner.rl"
+#line 145 "evalStringToScalarScanner.rl"
+	{te = p+1;}
+	goto st96;
+tr122:
+#line 106 "evalStringToScalarScanner.rl"
+	{ EMIT_TOKEN(DIVIDE); }
+#line 145 "evalStringToScalarScanner.rl"
 	{te = p+1;}
-	goto st86;
-tr125:
-#line 153 "evalStringToScalarScanner.rl"
+	goto st96;
+tr136:
+#line 143 "evalStringToScalarScanner.rl"
 	{te = p;p--;}
-	goto st86;
-tr126:
-#line 86 "evalStringToScalarScanner.rl"
+	goto st96;
+tr137:
+#line 73 "evalStringToScalarScanner.rl"
 	{te = p;p--;{
-        // Inform driver of last position
-        driver.parsePosition() = (p-buf);
+        driver.parsePosition() = (ts-buf);
 
         DebugInfo
-            << "NUMBER:" << std::string(ts, te-ts).c_str()
+            << "Number:" << std::string(ts, te-ts).c_str()
             << " at " << driver.parsePosition() << nl;
 
-        scalar val;
+        scalar val(0);
 
         if (readScalar(std::string(ts, te-ts), val))
         {
@@ -392,67 +424,63 @@ tr126:
         }
         else
         {
-            driver.reportFatal("Error reading scalar value");
+            // Catch range errors
+            driver.reportFatal("Error parsing number");
         }
+
+        driver.parsePosition() = (p-buf);
     }}
-	goto st86;
-tr128:
-#line 157 "evalStringToScalarScanner.rl"
-	{te = p;p--;}
-	goto st86;
-tr130:
-#line 160 "evalStringToScalarScanner.rl"
-	{te = p;p--;}
-	goto st86;
-st86:
+	goto st96;
+st96:
 #line 1 "NONE"
 	{ts = 0;}
 	if ( ++p == pe )
-		goto _test_eof86;
-case 86:
+		goto _test_eof96;
+case 96:
 #line 1 "NONE"
 	{ts = p;}
-#line 416 "evalStringToScalarScanner.cc"
+#line 443 "evalStringToScalarScanner.cc"
 	switch( (*p) ) {
-		case 32: goto st87;
-		case 40: goto tr105;
-		case 41: goto tr106;
-		case 42: goto tr107;
-		case 43: goto tr108;
-		case 44: goto tr109;
-		case 45: goto tr110;
+		case 32: goto st97;
+		case 40: goto tr115;
+		case 41: goto tr116;
+		case 42: goto tr117;
+		case 43: goto tr118;
+		case 44: goto tr119;
+		case 45: goto tr120;
 		case 46: goto st1;
-		case 47: goto tr112;
-		case 97: goto st6;
-		case 99: goto st18;
-		case 100: goto st26;
-		case 101: goto st34;
-		case 104: goto st37;
-		case 108: goto st42;
-		case 109: goto st48;
-		case 112: goto st58;
-		case 114: goto st62;
-		case 115: goto st72;
-		case 116: goto st81;
+		case 47: goto tr122;
+		case 97: goto st4;
+		case 99: goto st16;
+		case 100: goto st27;
+		case 101: goto st35;
+		case 102: goto st38;
+		case 104: goto st43;
+		case 108: goto st48;
+		case 109: goto st54;
+		case 112: goto st64;
+		case 114: goto st68;
+		case 115: goto st82;
+		case 116: goto st91;
 	}
 	if ( (*p) > 13 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr113;
+			goto tr123;
 	} else if ( (*p) >= 9 )
-		goto st87;
+		goto st97;
 	goto st0;
 st0:
 cs = 0;
 	goto _out;
-st87:
+st97:
 	if ( ++p == pe )
-		goto _test_eof87;
-case 87:
+		goto _test_eof97;
+case 97:
 	if ( (*p) == 32 )
-		goto st87;
+		goto st97;
 	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st87;
-	goto tr125;
+		goto st97;
+	goto tr136;
 st1:
 	if ( ++p == pe )
 		goto _test_eof1;
@@ -463,19 +491,19 @@ case 1:
 tr0:
 #line 1 "NONE"
 	{te = p+1;}
-	goto st88;
-st88:
+	goto st98;
+st98:
 	if ( ++p == pe )
-		goto _test_eof88;
-case 88:
-#line 472 "evalStringToScalarScanner.cc"
+		goto _test_eof98;
+case 98:
+#line 500 "evalStringToScalarScanner.cc"
 	switch( (*p) ) {
 		case 69: goto st2;
 		case 101: goto st2;
 	}
 	if ( 48 <= (*p) && (*p) <= 57 )
 		goto tr0;
-	goto tr126;
+	goto tr137;
 st2:
 	if ( ++p == pe )
 		goto _test_eof2;
@@ -485,252 +513,212 @@ case 2:
 		case 45: goto st3;
 	}
 	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st89;
+		goto st99;
 	goto tr2;
 st3:
 	if ( ++p == pe )
 		goto _test_eof3;
 case 3:
 	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st89;
+		goto st99;
 	goto tr2;
-st89:
+st99:
 	if ( ++p == pe )
-		goto _test_eof89;
-case 89:
+		goto _test_eof99;
+case 99:
 	if ( 48 <= (*p) && (*p) <= 57 )
-		goto st89;
-	goto tr126;
-tr112:
+		goto st99;
+	goto tr137;
+tr123:
 #line 1 "NONE"
 	{te = p+1;}
-#line 147 "evalStringToScalarScanner.rl"
-	{ EMIT_TOKEN(DIVIDE); }
-	goto st90;
-st90:
+	goto st100;
+st100:
 	if ( ++p == pe )
-		goto _test_eof90;
-case 90:
-#line 515 "evalStringToScalarScanner.cc"
+		goto _test_eof100;
+case 100:
+#line 541 "evalStringToScalarScanner.cc"
 	switch( (*p) ) {
-		case 42: goto st4;
-		case 47: goto st91;
+		case 46: goto tr0;
+		case 69: goto st2;
+		case 101: goto st2;
 	}
-	goto tr128;
+	if ( 48 <= (*p) && (*p) <= 57 )
+		goto tr123;
+	goto tr137;
 st4:
 	if ( ++p == pe )
 		goto _test_eof4;
 case 4:
-	if ( (*p) == 42 )
-		goto st5;
-	goto st4;
+	switch( (*p) ) {
+		case 99: goto st5;
+		case 115: goto st8;
+		case 116: goto st11;
+	}
+	goto st0;
 st5:
 	if ( ++p == pe )
 		goto _test_eof5;
 case 5:
-	switch( (*p) ) {
-		case 42: goto st5;
-		case 47: goto tr8;
-	}
-	goto st4;
-st91:
-	if ( ++p == pe )
-		goto _test_eof91;
-case 91:
-	if ( (*p) == 10 )
-		goto tr131;
-	goto st91;
-tr131:
-#line 74 "evalStringToScalarScanner.rl"
-	{
-        // Inform driver of last position
-        driver.parsePosition() = (p-buf);
-    }
-	goto st92;
-st92:
-	if ( ++p == pe )
-		goto _test_eof92;
-case 92:
-#line 555 "evalStringToScalarScanner.cc"
-	if ( (*p) == 10 )
-		goto tr131;
-	goto tr130;
-tr113:
-#line 1 "NONE"
-	{te = p+1;}
-	goto st93;
-st93:
-	if ( ++p == pe )
-		goto _test_eof93;
-case 93:
-#line 567 "evalStringToScalarScanner.cc"
-	switch( (*p) ) {
-		case 46: goto tr0;
-		case 69: goto st2;
-		case 101: goto st2;
-	}
-	if ( 48 <= (*p) && (*p) <= 57 )
-		goto tr113;
-	goto tr126;
+	if ( (*p) == 111 )
+		goto st6;
+	goto st0;
 st6:
 	if ( ++p == pe )
 		goto _test_eof6;
 case 6:
-	switch( (*p) ) {
-		case 99: goto st7;
-		case 115: goto st10;
-		case 116: goto st13;
-	}
+	if ( (*p) == 115 )
+		goto st7;
 	goto st0;
 st7:
 	if ( ++p == pe )
 		goto _test_eof7;
 case 7:
-	if ( (*p) == 111 )
-		goto st8;
+	switch( (*p) ) {
+		case 32: goto st7;
+		case 40: goto tr10;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st7;
 	goto st0;
 st8:
 	if ( ++p == pe )
 		goto _test_eof8;
 case 8:
-	if ( (*p) == 115 )
+	if ( (*p) == 105 )
 		goto st9;
 	goto st0;
 st9:
 	if ( ++p == pe )
 		goto _test_eof9;
 case 9:
-	switch( (*p) ) {
-		case 32: goto st9;
-		case 40: goto tr14;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st9;
+	if ( (*p) == 110 )
+		goto st10;
 	goto st0;
 st10:
 	if ( ++p == pe )
 		goto _test_eof10;
 case 10:
-	if ( (*p) == 105 )
-		goto st11;
+	switch( (*p) ) {
+		case 32: goto st10;
+		case 40: goto tr13;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st10;
 	goto st0;
 st11:
 	if ( ++p == pe )
 		goto _test_eof11;
 case 11:
-	if ( (*p) == 110 )
+	if ( (*p) == 97 )
 		goto st12;
 	goto st0;
 st12:
 	if ( ++p == pe )
 		goto _test_eof12;
 case 12:
-	switch( (*p) ) {
-		case 32: goto st12;
-		case 40: goto tr17;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st12;
+	if ( (*p) == 110 )
+		goto st13;
 	goto st0;
 st13:
 	if ( ++p == pe )
 		goto _test_eof13;
 case 13:
-	if ( (*p) == 97 )
+	switch( (*p) ) {
+		case 32: goto st14;
+		case 40: goto tr17;
+		case 50: goto st15;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st14;
 	goto st0;
 st14:
 	if ( ++p == pe )
 		goto _test_eof14;
 case 14:
-	if ( (*p) == 110 )
-		goto st15;
+	switch( (*p) ) {
+		case 32: goto st14;
+		case 40: goto tr17;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st14;
 	goto st0;
 st15:
 	if ( ++p == pe )
 		goto _test_eof15;
 case 15:
 	switch( (*p) ) {
-		case 32: goto st16;
-		case 40: goto tr21;
-		case 50: goto st17;
+		case 32: goto st15;
+		case 40: goto tr19;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st16;
+		goto st15;
 	goto st0;
 st16:
 	if ( ++p == pe )
 		goto _test_eof16;
 case 16:
 	switch( (*p) ) {
-		case 32: goto st16;
-		case 40: goto tr21;
+		case 98: goto st17;
+		case 101: goto st20;
+		case 111: goto st23;
 	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st16;
 	goto st0;
 st17:
 	if ( ++p == pe )
 		goto _test_eof17;
 case 17:
-	switch( (*p) ) {
-		case 32: goto st17;
-		case 40: goto tr23;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st17;
+	if ( (*p) == 114 )
+		goto st18;
 	goto st0;
 st18:
 	if ( ++p == pe )
 		goto _test_eof18;
 case 18:
-	switch( (*p) ) {
-		case 98: goto st19;
-		case 111: goto st22;
-	}
+	if ( (*p) == 116 )
+		goto st19;
 	goto st0;
 st19:
 	if ( ++p == pe )
 		goto _test_eof19;
 case 19:
-	if ( (*p) == 114 )
-		goto st20;
+	switch( (*p) ) {
+		case 32: goto st19;
+		case 40: goto tr25;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st19;
 	goto st0;
 st20:
 	if ( ++p == pe )
 		goto _test_eof20;
 case 20:
-	if ( (*p) == 116 )
+	if ( (*p) == 105 )
 		goto st21;
 	goto st0;
 st21:
 	if ( ++p == pe )
 		goto _test_eof21;
 case 21:
-	switch( (*p) ) {
-		case 32: goto st21;
-		case 40: goto tr28;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st21;
+	if ( (*p) == 108 )
+		goto st22;
 	goto st0;
 st22:
 	if ( ++p == pe )
 		goto _test_eof22;
 case 22:
-	if ( (*p) == 115 )
-		goto st23;
+	switch( (*p) ) {
+		case 32: goto st22;
+		case 40: goto tr28;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st22;
 	goto st0;
 st23:
 	if ( ++p == pe )
 		goto _test_eof23;
 case 23:
-	switch( (*p) ) {
-		case 32: goto st24;
-		case 40: goto tr31;
-		case 104: goto st25;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
+	if ( (*p) == 115 )
 		goto st24;
 	goto st0;
 st24:
@@ -738,11 +726,12 @@ st24:
 		goto _test_eof24;
 case 24:
 	switch( (*p) ) {
-		case 32: goto st24;
+		case 32: goto st25;
 		case 40: goto tr31;
+		case 104: goto st26;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st24;
+		goto st25;
 	goto st0;
 st25:
 	if ( ++p == pe )
@@ -750,7 +739,7 @@ st25:
 case 25:
 	switch( (*p) ) {
 		case 32: goto st25;
-		case 40: goto tr33;
+		case 40: goto tr31;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st25;
@@ -759,99 +748,103 @@ st26:
 	if ( ++p == pe )
 		goto _test_eof26;
 case 26:
-	if ( (*p) == 101 )
-		goto st27;
+	switch( (*p) ) {
+		case 32: goto st26;
+		case 40: goto tr33;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st26;
 	goto st0;
 st27:
 	if ( ++p == pe )
 		goto _test_eof27;
 case 27:
-	if ( (*p) == 103 )
+	if ( (*p) == 101 )
 		goto st28;
 	goto st0;
 st28:
 	if ( ++p == pe )
 		goto _test_eof28;
 case 28:
-	if ( (*p) == 84 )
+	if ( (*p) == 103 )
 		goto st29;
 	goto st0;
 st29:
 	if ( ++p == pe )
 		goto _test_eof29;
 case 29:
-	if ( (*p) == 111 )
+	if ( (*p) == 84 )
 		goto st30;
 	goto st0;
 st30:
 	if ( ++p == pe )
 		goto _test_eof30;
 case 30:
-	if ( (*p) == 82 )
+	if ( (*p) == 111 )
 		goto st31;
 	goto st0;
 st31:
 	if ( ++p == pe )
 		goto _test_eof31;
 case 31:
-	if ( (*p) == 97 )
+	if ( (*p) == 82 )
 		goto st32;
 	goto st0;
 st32:
 	if ( ++p == pe )
 		goto _test_eof32;
 case 32:
-	if ( (*p) == 100 )
+	if ( (*p) == 97 )
 		goto st33;
 	goto st0;
 st33:
 	if ( ++p == pe )
 		goto _test_eof33;
-case 33:
-	switch( (*p) ) {
-		case 32: goto st33;
-		case 40: goto tr41;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st33;
+case 33:
+	if ( (*p) == 100 )
+		goto st34;
 	goto st0;
 st34:
 	if ( ++p == pe )
 		goto _test_eof34;
 case 34:
-	if ( (*p) == 120 )
-		goto st35;
+	switch( (*p) ) {
+		case 32: goto st34;
+		case 40: goto tr41;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st34;
 	goto st0;
 st35:
 	if ( ++p == pe )
 		goto _test_eof35;
 case 35:
-	if ( (*p) == 112 )
+	if ( (*p) == 120 )
 		goto st36;
 	goto st0;
 st36:
 	if ( ++p == pe )
 		goto _test_eof36;
 case 36:
-	switch( (*p) ) {
-		case 32: goto st36;
-		case 40: goto tr44;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st36;
+	if ( (*p) == 112 )
+		goto st37;
 	goto st0;
 st37:
 	if ( ++p == pe )
 		goto _test_eof37;
 case 37:
-	if ( (*p) == 121 )
-		goto st38;
+	switch( (*p) ) {
+		case 32: goto st37;
+		case 40: goto tr44;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st37;
 	goto st0;
 st38:
 	if ( ++p == pe )
 		goto _test_eof38;
 case 38:
-	if ( (*p) == 112 )
+	if ( (*p) == 108 )
 		goto st39;
 	goto st0;
 st39:
@@ -865,62 +858,53 @@ st40:
 	if ( ++p == pe )
 		goto _test_eof40;
 case 40:
-	if ( (*p) == 116 )
+	if ( (*p) == 111 )
 		goto st41;
 	goto st0;
 st41:
 	if ( ++p == pe )
 		goto _test_eof41;
 case 41:
-	switch( (*p) ) {
-		case 32: goto st41;
-		case 40: goto tr49;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st41;
+	if ( (*p) == 114 )
+		goto st42;
 	goto st0;
 st42:
 	if ( ++p == pe )
 		goto _test_eof42;
 case 42:
-	if ( (*p) == 111 )
-		goto st43;
+	switch( (*p) ) {
+		case 32: goto st42;
+		case 40: goto tr49;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st42;
 	goto st0;
 st43:
 	if ( ++p == pe )
 		goto _test_eof43;
 case 43:
-	if ( (*p) == 103 )
+	if ( (*p) == 121 )
 		goto st44;
 	goto st0;
 st44:
 	if ( ++p == pe )
 		goto _test_eof44;
 case 44:
-	switch( (*p) ) {
-		case 32: goto st45;
-		case 40: goto tr53;
-		case 49: goto st46;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
+	if ( (*p) == 112 )
 		goto st45;
 	goto st0;
 st45:
 	if ( ++p == pe )
 		goto _test_eof45;
 case 45:
-	switch( (*p) ) {
-		case 32: goto st45;
-		case 40: goto tr53;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st45;
+	if ( (*p) == 111 )
+		goto st46;
 	goto st0;
 st46:
 	if ( ++p == pe )
 		goto _test_eof46;
 case 46:
-	if ( (*p) == 48 )
+	if ( (*p) == 116 )
 		goto st47;
 	goto st0;
 st47:
@@ -929,7 +913,7 @@ st47:
 case 47:
 	switch( (*p) ) {
 		case 32: goto st47;
-		case 40: goto tr56;
+		case 40: goto tr54;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st47;
@@ -938,19 +922,15 @@ st48:
 	if ( ++p == pe )
 		goto _test_eof48;
 case 48:
-	switch( (*p) ) {
-		case 97: goto st49;
-		case 105: goto st56;
-	}
+	if ( (*p) == 111 )
+		goto st49;
 	goto st0;
 st49:
 	if ( ++p == pe )
 		goto _test_eof49;
 case 49:
-	switch( (*p) ) {
-		case 103: goto st50;
-		case 120: goto st55;
-	}
+	if ( (*p) == 103 )
+		goto st50;
 	goto st0;
 st50:
 	if ( ++p == pe )
@@ -958,8 +938,8 @@ st50:
 case 50:
 	switch( (*p) ) {
 		case 32: goto st51;
-		case 40: goto tr62;
-		case 83: goto st52;
+		case 40: goto tr58;
+		case 49: goto st52;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st51;
@@ -970,7 +950,7 @@ st51:
 case 51:
 	switch( (*p) ) {
 		case 32: goto st51;
-		case 40: goto tr62;
+		case 40: goto tr58;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st51;
@@ -979,43 +959,48 @@ st52:
 	if ( ++p == pe )
 		goto _test_eof52;
 case 52:
-	if ( (*p) == 113 )
+	if ( (*p) == 48 )
 		goto st53;
 	goto st0;
 st53:
 	if ( ++p == pe )
 		goto _test_eof53;
 case 53:
-	if ( (*p) == 114 )
-		goto st54;
+	switch( (*p) ) {
+		case 32: goto st53;
+		case 40: goto tr61;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st53;
 	goto st0;
 st54:
 	if ( ++p == pe )
 		goto _test_eof54;
 case 54:
 	switch( (*p) ) {
-		case 32: goto st54;
-		case 40: goto tr66;
+		case 97: goto st55;
+		case 105: goto st62;
 	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st54;
 	goto st0;
 st55:
 	if ( ++p == pe )
 		goto _test_eof55;
 case 55:
 	switch( (*p) ) {
-		case 32: goto st55;
-		case 40: goto tr67;
+		case 103: goto st56;
+		case 120: goto st61;
 	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st55;
 	goto st0;
 st56:
 	if ( ++p == pe )
 		goto _test_eof56;
 case 56:
-	if ( (*p) == 110 )
+	switch( (*p) ) {
+		case 32: goto st57;
+		case 40: goto tr67;
+		case 83: goto st58;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st57;
 	goto st0;
 st57:
@@ -1024,7 +1009,7 @@ st57:
 case 57:
 	switch( (*p) ) {
 		case 32: goto st57;
-		case 40: goto tr69;
+		case 40: goto tr67;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st57;
@@ -1033,28 +1018,26 @@ st58:
 	if ( ++p == pe )
 		goto _test_eof58;
 case 58:
-	switch( (*p) ) {
-		case 105: goto st59;
-		case 111: goto st60;
-	}
+	if ( (*p) == 113 )
+		goto st59;
 	goto st0;
 st59:
 	if ( ++p == pe )
 		goto _test_eof59;
 case 59:
-	switch( (*p) ) {
-		case 32: goto st59;
-		case 40: goto tr72;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st59;
+	if ( (*p) == 114 )
+		goto st60;
 	goto st0;
 st60:
 	if ( ++p == pe )
 		goto _test_eof60;
 case 60:
-	if ( (*p) == 119 )
-		goto st61;
+	switch( (*p) ) {
+		case 32: goto st60;
+		case 40: goto tr71;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st60;
 	goto st0;
 st61:
 	if ( ++p == pe )
@@ -1062,7 +1045,7 @@ st61:
 case 61:
 	switch( (*p) ) {
 		case 32: goto st61;
-		case 40: goto tr74;
+		case 40: goto tr72;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st61;
@@ -1071,7 +1054,7 @@ st62:
 	if ( ++p == pe )
 		goto _test_eof62;
 case 62:
-	if ( (*p) == 97 )
+	if ( (*p) == 110 )
 		goto st63;
 	goto st0;
 st63:
@@ -1079,100 +1062,101 @@ st63:
 		goto _test_eof63;
 case 63:
 	switch( (*p) ) {
-		case 100: goto st64;
-		case 110: goto st70;
+		case 32: goto st63;
+		case 40: goto tr74;
 	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st63;
 	goto st0;
 st64:
 	if ( ++p == pe )
 		goto _test_eof64;
 case 64:
-	if ( (*p) == 84 )
-		goto st65;
+	switch( (*p) ) {
+		case 105: goto st65;
+		case 111: goto st66;
+	}
 	goto st0;
 st65:
 	if ( ++p == pe )
 		goto _test_eof65;
 case 65:
-	if ( (*p) == 111 )
-		goto st66;
+	switch( (*p) ) {
+		case 32: goto st65;
+		case 40: goto tr77;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st65;
 	goto st0;
 st66:
 	if ( ++p == pe )
 		goto _test_eof66;
 case 66:
-	if ( (*p) == 68 )
+	if ( (*p) == 119 )
 		goto st67;
 	goto st0;
 st67:
 	if ( ++p == pe )
 		goto _test_eof67;
 case 67:
-	if ( (*p) == 101 )
-		goto st68;
+	switch( (*p) ) {
+		case 32: goto st67;
+		case 40: goto tr79;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st67;
 	goto st0;
 st68:
 	if ( ++p == pe )
 		goto _test_eof68;
 case 68:
-	if ( (*p) == 103 )
-		goto st69;
+	switch( (*p) ) {
+		case 97: goto st69;
+		case 111: goto st78;
+	}
 	goto st0;
 st69:
 	if ( ++p == pe )
 		goto _test_eof69;
 case 69:
 	switch( (*p) ) {
-		case 32: goto st69;
-		case 40: goto tr83;
+		case 100: goto st70;
+		case 110: goto st76;
 	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st69;
 	goto st0;
 st70:
 	if ( ++p == pe )
 		goto _test_eof70;
 case 70:
-	if ( (*p) == 100 )
+	if ( (*p) == 84 )
 		goto st71;
 	goto st0;
 st71:
 	if ( ++p == pe )
 		goto _test_eof71;
 case 71:
-	switch( (*p) ) {
-		case 32: goto st71;
-		case 40: goto tr85;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st71;
+	if ( (*p) == 111 )
+		goto st72;
 	goto st0;
 st72:
 	if ( ++p == pe )
 		goto _test_eof72;
 case 72:
-	switch( (*p) ) {
-		case 105: goto st73;
-		case 113: goto st77;
-	}
+	if ( (*p) == 68 )
+		goto st73;
 	goto st0;
 st73:
 	if ( ++p == pe )
 		goto _test_eof73;
 case 73:
-	if ( (*p) == 110 )
+	if ( (*p) == 101 )
 		goto st74;
 	goto st0;
 st74:
 	if ( ++p == pe )
 		goto _test_eof74;
 case 74:
-	switch( (*p) ) {
-		case 32: goto st75;
-		case 40: goto tr90;
-		case 104: goto st76;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
+	if ( (*p) == 103 )
 		goto st75;
 	goto st0;
 st75:
@@ -1181,7 +1165,7 @@ st75:
 case 75:
 	switch( (*p) ) {
 		case 32: goto st75;
-		case 40: goto tr90;
+		case 40: goto tr89;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st75;
@@ -1190,78 +1174,66 @@ st76:
 	if ( ++p == pe )
 		goto _test_eof76;
 case 76:
-	switch( (*p) ) {
-		case 32: goto st76;
-		case 40: goto tr92;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st76;
+	if ( (*p) == 100 )
+		goto st77;
 	goto st0;
 st77:
 	if ( ++p == pe )
 		goto _test_eof77;
 case 77:
-	if ( (*p) == 114 )
-		goto st78;
+	switch( (*p) ) {
+		case 32: goto st77;
+		case 40: goto tr91;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st77;
 	goto st0;
 st78:
 	if ( ++p == pe )
 		goto _test_eof78;
 case 78:
-	switch( (*p) ) {
-		case 32: goto st79;
-		case 40: goto tr95;
-		case 116: goto st80;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
+	if ( (*p) == 117 )
 		goto st79;
 	goto st0;
 st79:
 	if ( ++p == pe )
 		goto _test_eof79;
 case 79:
-	switch( (*p) ) {
-		case 32: goto st79;
-		case 40: goto tr95;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st79;
+	if ( (*p) == 110 )
+		goto st80;
 	goto st0;
 st80:
 	if ( ++p == pe )
 		goto _test_eof80;
 case 80:
-	switch( (*p) ) {
-		case 32: goto st80;
-		case 40: goto tr97;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st80;
+	if ( (*p) == 100 )
+		goto st81;
 	goto st0;
 st81:
 	if ( ++p == pe )
 		goto _test_eof81;
 case 81:
-	if ( (*p) == 97 )
-		goto st82;
+	switch( (*p) ) {
+		case 32: goto st81;
+		case 40: goto tr95;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st81;
 	goto st0;
 st82:
 	if ( ++p == pe )
 		goto _test_eof82;
 case 82:
-	if ( (*p) == 110 )
-		goto st83;
+	switch( (*p) ) {
+		case 105: goto st83;
+		case 113: goto st87;
+	}
 	goto st0;
 st83:
 	if ( ++p == pe )
 		goto _test_eof83;
 case 83:
-	switch( (*p) ) {
-		case 32: goto st84;
-		case 40: goto tr101;
-		case 104: goto st85;
-	}
-	if ( 9 <= (*p) && (*p) <= 13 )
+	if ( (*p) == 110 )
 		goto st84;
 	goto st0;
 st84:
@@ -1269,11 +1241,12 @@ st84:
 		goto _test_eof84;
 case 84:
 	switch( (*p) ) {
-		case 32: goto st84;
-		case 40: goto tr101;
+		case 32: goto st85;
+		case 40: goto tr100;
+		case 104: goto st86;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
-		goto st84;
+		goto st85;
 	goto st0;
 st85:
 	if ( ++p == pe )
@@ -1281,25 +1254,122 @@ st85:
 case 85:
 	switch( (*p) ) {
 		case 32: goto st85;
-		case 40: goto tr103;
+		case 40: goto tr100;
 	}
 	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st85;
 	goto st0;
+st86:
+	if ( ++p == pe )
+		goto _test_eof86;
+case 86:
+	switch( (*p) ) {
+		case 32: goto st86;
+		case 40: goto tr102;
 	}
-	_test_eof86: cs = 86; goto _test_eof; 
-	_test_eof87: cs = 87; goto _test_eof; 
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st86;
+	goto st0;
+st87:
+	if ( ++p == pe )
+		goto _test_eof87;
+case 87:
+	if ( (*p) == 114 )
+		goto st88;
+	goto st0;
+st88:
+	if ( ++p == pe )
+		goto _test_eof88;
+case 88:
+	switch( (*p) ) {
+		case 32: goto st89;
+		case 40: goto tr105;
+		case 116: goto st90;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st89;
+	goto st0;
+st89:
+	if ( ++p == pe )
+		goto _test_eof89;
+case 89:
+	switch( (*p) ) {
+		case 32: goto st89;
+		case 40: goto tr105;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st89;
+	goto st0;
+st90:
+	if ( ++p == pe )
+		goto _test_eof90;
+case 90:
+	switch( (*p) ) {
+		case 32: goto st90;
+		case 40: goto tr107;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st90;
+	goto st0;
+st91:
+	if ( ++p == pe )
+		goto _test_eof91;
+case 91:
+	if ( (*p) == 97 )
+		goto st92;
+	goto st0;
+st92:
+	if ( ++p == pe )
+		goto _test_eof92;
+case 92:
+	if ( (*p) == 110 )
+		goto st93;
+	goto st0;
+st93:
+	if ( ++p == pe )
+		goto _test_eof93;
+case 93:
+	switch( (*p) ) {
+		case 32: goto st94;
+		case 40: goto tr111;
+		case 104: goto st95;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st94;
+	goto st0;
+st94:
+	if ( ++p == pe )
+		goto _test_eof94;
+case 94:
+	switch( (*p) ) {
+		case 32: goto st94;
+		case 40: goto tr111;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st94;
+	goto st0;
+st95:
+	if ( ++p == pe )
+		goto _test_eof95;
+case 95:
+	switch( (*p) ) {
+		case 32: goto st95;
+		case 40: goto tr113;
+	}
+	if ( 9 <= (*p) && (*p) <= 13 )
+		goto st95;
+	goto st0;
+	}
+	_test_eof96: cs = 96; goto _test_eof; 
+	_test_eof97: cs = 97; goto _test_eof; 
 	_test_eof1: cs = 1; goto _test_eof; 
-	_test_eof88: cs = 88; goto _test_eof; 
+	_test_eof98: cs = 98; goto _test_eof; 
 	_test_eof2: cs = 2; goto _test_eof; 
 	_test_eof3: cs = 3; goto _test_eof; 
-	_test_eof89: cs = 89; goto _test_eof; 
-	_test_eof90: cs = 90; goto _test_eof; 
+	_test_eof99: cs = 99; goto _test_eof; 
+	_test_eof100: cs = 100; goto _test_eof; 
 	_test_eof4: cs = 4; goto _test_eof; 
 	_test_eof5: cs = 5; goto _test_eof; 
-	_test_eof91: cs = 91; goto _test_eof; 
-	_test_eof92: cs = 92; goto _test_eof; 
-	_test_eof93: cs = 93; goto _test_eof; 
 	_test_eof6: cs = 6; goto _test_eof; 
 	_test_eof7: cs = 7; goto _test_eof; 
 	_test_eof8: cs = 8; goto _test_eof; 
@@ -1380,29 +1450,34 @@ case 85:
 	_test_eof83: cs = 83; goto _test_eof; 
 	_test_eof84: cs = 84; goto _test_eof; 
 	_test_eof85: cs = 85; goto _test_eof; 
+	_test_eof86: cs = 86; goto _test_eof; 
+	_test_eof87: cs = 87; goto _test_eof; 
+	_test_eof88: cs = 88; goto _test_eof; 
+	_test_eof89: cs = 89; goto _test_eof; 
+	_test_eof90: cs = 90; goto _test_eof; 
+	_test_eof91: cs = 91; goto _test_eof; 
+	_test_eof92: cs = 92; goto _test_eof; 
+	_test_eof93: cs = 93; goto _test_eof; 
+	_test_eof94: cs = 94; goto _test_eof; 
+	_test_eof95: cs = 95; goto _test_eof; 
 
 	_test_eof: {}
 	if ( p == eof )
 	{
 	switch ( cs ) {
-	case 87: goto tr125;
-	case 88: goto tr126;
+	case 97: goto tr136;
+	case 98: goto tr137;
 	case 2: goto tr2;
 	case 3: goto tr2;
-	case 89: goto tr126;
-	case 90: goto tr128;
-	case 4: goto tr5;
-	case 5: goto tr5;
-	case 91: goto tr130;
-	case 92: goto tr130;
-	case 93: goto tr126;
+	case 99: goto tr137;
+	case 100: goto tr137;
 	}
 	}
 
 	_out: {}
 	}
 
-#line 209 "evalStringToScalarScanner.rl"
+#line 215 "evalStringToScalarScanner.rl"
   /* ^^^ FSM execution here ^^^ */;
 
     if (0 == cs)
diff --git a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.rl b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.rl
index 5f540dee34b..e9c2ea06637 100644
--- a/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.rl
+++ b/src/OpenFOAM/primitives/strings/stringOps/toScalar/evalStringToScalarScanner.rl
@@ -61,37 +61,23 @@ int Foam::parsing::evalStringToScalar::scanner::debug = 0;
 
 #define TOKEN_OF(T)         TOK_##T
 #define EMIT_TOKEN(T)                                                         \
-    /* Inform driver of last position */                                      \
-    driver.parsePosition() = (p-buf);                                         \
+    driver.parsePosition() = (ts-buf);                                        \
     DebugInfo<< "TOKEN_" #T << " at " << driver.parsePosition() << nl;        \
-    parser_->parse(TOKEN_OF(T), 0)
+    parser_->parse(TOKEN_OF(T), 0);                                           \
+    driver.parsePosition() = (p-buf);
 
 
 %%{
     machine evalScanner;
 
-    action setPosition
-    {
-        // Inform driver of last position
-        driver.parsePosition() = (p-buf);
-    }
-
-    action truncated
-    {
-        // Inform driver of last position
-        driver.parsePosition() = 0;
-        driver.reportFatal("Truncated input");
-    }
-
     action emit_number {
-        // Inform driver of last position
-        driver.parsePosition() = (p-buf);
+        driver.parsePosition() = (ts-buf);
 
         DebugInfo
-            << "NUMBER:" << std::string(ts, te-ts).c_str()
+            << "Number:" << std::string(ts, te-ts).c_str()
             << " at " << driver.parsePosition() << nl;
 
-        scalar val;
+        scalar val(0);
 
         if (readScalar(std::string(ts, te-ts), val))
         {
@@ -100,15 +86,27 @@ int Foam::parsing::evalStringToScalar::scanner::debug = 0;
         }
         else
         {
-            driver.reportFatal("Error reading scalar value");
+            // Catch range errors
+            driver.reportFatal("Error parsing number");
         }
+
+        driver.parsePosition() = (p-buf);
     }
 
     decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
     number  = (digit+ | decimal) ([Ee][\-+]? digit+)? ;
-    dnl     = (any* -- '\n') '\n';  # Discard up to and including newline
     lfunc   = space* '(';           # Require functions to have '('
 
+    operators = (
+        '('  @{ EMIT_TOKEN(LPAREN); }
+      | ')'  @{ EMIT_TOKEN(RPAREN); }
+      | '+'  @{ EMIT_TOKEN(PLUS); }
+      | '-'  @{ EMIT_TOKEN(MINUS); }
+      | '*'  @{ EMIT_TOKEN(TIMES); }
+      | '/'  @{ EMIT_TOKEN(DIVIDE); }
+      | ','  @{ EMIT_TOKEN(COMMA); }
+    );
+
     functions = (
         'pi'         lfunc  @{ fhold; EMIT_TOKEN(PI); }
       | 'degToRad'   lfunc  @{ fhold; EMIT_TOKEN(DEG_TO_RAD); }
@@ -135,29 +133,17 @@ int Foam::parsing::evalStringToScalar::scanner::debug = 0;
       | 'max'        lfunc  @{ fhold; EMIT_TOKEN(MAX); }
       | 'mag'        lfunc  @{ fhold; EMIT_TOKEN(MAG); }
       | 'magSqr'     lfunc  @{ fhold; EMIT_TOKEN(MAGSQR); }
+      | 'floor'      lfunc  @{ fhold; EMIT_TOKEN(FLOOR); }
+      | 'ceil'       lfunc  @{ fhold; EMIT_TOKEN(CEIL); }
+      | 'round'      lfunc  @{ fhold; EMIT_TOKEN(ROUND); }
       | 'rand'       lfunc  @{ fhold; EMIT_TOKEN(RAND); }
     );
 
-    operators = (
-        '('  @{ EMIT_TOKEN(LPAREN); }
-      | ')'  @{ EMIT_TOKEN(RPAREN); }
-      | '+'  @{ EMIT_TOKEN(PLUS); }
-      | '-'  @{ EMIT_TOKEN(MINUS); }
-      | '*'  @{ EMIT_TOKEN(TIMES); }
-      | '/'  @{ EMIT_TOKEN(DIVIDE); }
-      | ','  @{ EMIT_TOKEN(COMMA); }
-    );
-
-
     main := |*
         space*;
-
         number => emit_number;
-        functions;
         operators;
-
-        '/*' any* :>> '*/' @setPosition;        # Multi-line comment
-        '//' (any* -- '\n') '\n'* @setPosition; # (sloppy) 1-line comment
+        functions;
         space*;
     *|;
 }%%
@@ -174,11 +160,13 @@ Foam::parsing::evalStringToScalar::scanner::~scanner()
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 bool Foam::parsing::evalStringToScalar::scanner::process
 (
     const std::string& str,
+    size_t strBeg,
+    size_t strLen,
     parseDriver& driver
 )
 {
@@ -187,7 +175,25 @@ bool Foam::parsing::evalStringToScalar::scanner::process
         parser_ = new parser();
     }
 
-    driver.content(str);
+    driver.content(str, strBeg, strLen);
+
+    size_t strEnd = str.length();
+
+    if (strBeg > str.length())
+    {
+        strBeg = str.length();
+    }
+    else if (strLen != std::string::npos)
+    {
+        strLen += strBeg;
+
+        if (strLen < str.length())
+        {
+            strEnd = strLen;
+        }
+    }
+
+
     parser_->start(driver);
 
     // Ragel token start/end (required naming)
@@ -198,8 +204,8 @@ bool Foam::parsing::evalStringToScalar::scanner::process
     // - p, pe, eof are required Ragel naming
     // - buf is our own naming
 
-    const char* buf = &(str[0]);
-    const char* eof = &(str[str.length()]);
+    const char* buf = &(str[strBeg]);
+    const char* eof = &(str[strEnd]);
     const char* p = buf;
     const char* pe = eof;
 
-- 
GitLab