From b6b4ab071d0ae54079be4bec7b9b71c961e6a962 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Thu, 10 Jun 2021 17:59:07 +0200
Subject: [PATCH] ENH: additional patch expressions (#2114)

- snGrad, internalField, neighbourField.
  Functional use as per swak: "... + internalField(T) ..."

ENH: additional volume/patch expressions

- deltaT()

STYLE: rename exprDriverWriter -> fvExprDriverWriter

- the original class name was a misnomer since it holds a reference
  to fvExprDriver

BUG: expression faceToPoint/pointToFace definitions were flipped

ENH: refactor expression hierarchy and code style

- handle TimeState reference at the top-level for simpler derivations

- unified internal search parameters (cruft)
---
 .../setExprBoundaryFields.C                   |   12 +-
 .../setExprFields/setExprFields.C             |   12 +-
 .../expressions/exprDriver/exprDriver.C       |  167 +-
 .../expressions/exprDriver/exprDriver.H       |  126 +-
 .../expressions/exprDriver/exprDriverFields.C |   15 +-
 .../expressions/exprDriver/exprDriverI.H      |   52 +-
 .../exprDriver/exprDriverTemplates.C          |   24 +-
 .../expressions/exprResult/exprResult.H       |    2 +-
 .../expressions/exprResult/exprResultI.H      |    3 +-
 .../expressions/fields/fieldExprDriver.C      |    6 -
 .../expressions/fields/fieldExprDriver.H      |   11 +-
 .../expressions/fields/fieldExprLemonParser.h |  128 +-
 .../fields/fieldExprLemonParser.lyy-m4        |    3 +-
 .../expressions/fields/fieldExprScanner.H     |    6 +-
 .../expressions/fields/fieldExprScanner.cc    |    6 +-
 .../expressions/fields/fieldExprScanner.rl    |    3 +-
 src/OpenFOAM/include/m4/lemon/rules-fields.m4 |   79 +-
 src/finiteVolume/Make/files                   |    4 +-
 .../expressions/base/fvExprDriver.C           |   60 +-
 .../expressions/base/fvExprDriver.H           |   50 +-
 .../expressions/base/fvExprDriverFields.C     |   49 -
 .../expressions/base/fvExprDriverI.H          |    2 +-
 .../expressions/base/fvExprDriverIO.C         |    8 +-
 .../expressions/base/fvExprDriverNew.C        |    2 +-
 .../expressions/base/fvExprDriverTemplates.C  |   19 +-
 ...xprDriverWriter.C => fvExprDriverWriter.C} |   16 +-
 ...xprDriverWriter.H => fvExprDriverWriter.H} |   30 +-
 .../expressions/patch/patchExprDriver.C       |   41 +-
 .../expressions/patch/patchExprDriver.H       |   51 +-
 .../expressions/patch/patchExprDriverFields.C |    9 +-
 .../patch/patchExprDriverTemplates.C          |  299 +-
 .../expressions/patch/patchExprLemonParser.h  |  168 +-
 .../patch/patchExprLemonParser.lyy-m4         |    6 +
 .../patch/patchExprLemonParserMacros.m4       |   28 +-
 .../expressions/patch/patchExprScanner.H      |    6 +-
 .../expressions/patch/patchExprScanner.cc     | 2948 ++++++++++-------
 .../expressions/patch/patchExprScanner.rl     |   20 +-
 .../expressions/volume/volumeExprDriver.C     |   36 +-
 .../expressions/volume/volumeExprDriver.H     |   10 +-
 .../volume/volumeExprDriverFields.C           |   14 +-
 .../volume/volumeExprDriverTemplates.C        |   12 +-
 .../volume/volumeExprLemonParser.h            |  183 +-
 .../volume/volumeExprLemonParser.lyy-m4       |    1 +
 .../volume/volumeExprLemonParserMacros.m4     |   17 +-
 .../expressions/volume/volumeExprScanner.H    |    6 +-
 .../expressions/volume/volumeExprScanner.cc   |  550 +--
 .../expressions/volume/volumeExprScanner.rl   |   27 +-
 47 files changed, 3235 insertions(+), 2092 deletions(-)
 delete mode 100644 src/finiteVolume/expressions/base/fvExprDriverFields.C
 rename src/finiteVolume/expressions/base/{exprDriverWriter.C => fvExprDriverWriter.C} (84%)
 rename src/finiteVolume/expressions/base/{exprDriverWriter.H => fvExprDriverWriter.H} (78%)

diff --git a/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C b/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C
index 5d63cb6769a..6c1953c18cb 100644
--- a/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C
+++ b/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C
@@ -33,8 +33,8 @@ Description
     Set boundary values using an expression
 
 Note
-    Based on funkySetBoundaryFields
-    Copyright 2006-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
+    Based on funkySetBoundaryFields from
+    Bernhard Gschaider <bgschaid@hfd-research.com>
 
 \*---------------------------------------------------------------------------*/
 
@@ -248,8 +248,12 @@ int main(int argc, char *argv[])
 
                 expressions::patchExprDriver driver(currDict, mesh);
 
-                // Search on disc
-                driver.setSearchBehaviour(cacheFields, false, true);
+                // Search files only
+                driver.setSearchBehaviour
+                (
+                    expressions::exprDriver::SEARCH_FILES,
+                    cacheFields
+                );
 
                 driver.clearVariables();
                 driver.parse(expr);
diff --git a/applications/utilities/preProcessing/setExprFields/setExprFields.C b/applications/utilities/preProcessing/setExprFields/setExprFields.C
index 983beb284c9..88cbc149b34 100644
--- a/applications/utilities/preProcessing/setExprFields/setExprFields.C
+++ b/applications/utilities/preProcessing/setExprFields/setExprFields.C
@@ -33,8 +33,8 @@ Description
     Set values on a selected set of cells/patch-faces via a dictionary.
 
 Note
-    Based on funkySetFields
-    Copyright 2006-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
+    Based on funkySetFields from
+    Bernhard Gschaider <bgschaid@hfd-research.com>
 
 \*---------------------------------------------------------------------------*/
 
@@ -310,11 +310,9 @@ void evaluate
 
     Info<< endl;
 
-    expressions::volumeExprDriver driver
-    (
-        mesh,
-        ctrl.cacheVariables
-    );
+    expressions::volumeExprDriver driver(mesh);
+
+    driver.setCaching(ctrl.cacheVariables);
 
     driver.readDict(dict);
 
diff --git a/src/OpenFOAM/expressions/exprDriver/exprDriver.C b/src/OpenFOAM/expressions/exprDriver/exprDriver.C
index c9304bd1810..123ed9f9d52 100644
--- a/src/OpenFOAM/expressions/exprDriver/exprDriver.C
+++ b/src/OpenFOAM/expressions/exprDriver/exprDriver.C
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2010-2018 Bernhard Gschaider
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,6 +29,7 @@ License
 #include "exprDriver.H"
 #include "expressionEntry.H"
 #include "stringOps.H"
+#include "TimeState.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -43,9 +44,31 @@ namespace expressions
 } // End namespace Foam
 
 
-
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
+int Foam::expressions::exprDriver::getSearchControls(const dictionary& dict)
+{
+    int val = 0;
+
+    if (dict.getOrDefault("searchInMemory", true))
+    {
+        val |= int(searchControls::SEARCH_REGISTRY);
+    }
+    if (dict.getOrDefault("searchFiles", false))
+    {
+        val |= int(searchControls::SEARCH_FILES);
+    }
+    if (dict.getOrDefault("cacheReadFields", false))
+    {
+        val |= int(searchControls::CACHE_READ_FIELDS);
+    }
+
+    return val;
+}
+
+
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
+
 namespace Foam
 {
 #if 0
@@ -78,14 +101,27 @@ static string getEntryString
 } // End namespace Foam
 
 
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void Foam::expressions::exprDriver::resetTimeReference(const TimeState* ts)
+{
+    timeStatePtr_ = ts;
+}
+
+
+void Foam::expressions::exprDriver::resetTimeReference(const TimeState& ts)
+{
+    timeStatePtr_ = &ts;
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::expressions::exprDriver::exprDriver
 (
-    bool cacheReadFields,
-    bool searchInMemory,
-    bool searchFiles,
-    const dictionary& dict
+    enum searchControls search,
+    const dictionary& dict,
+    const TimeState* ts
 )
 :
     dict_(dict),
@@ -93,6 +129,7 @@ Foam::expressions::exprDriver::exprDriver
     variableStrings_(),
     variables_(),
     arg1Value_(0),
+    timeStatePtr_(ts),
     stashedTokenId_(0),
 
     // Controls
@@ -106,9 +143,7 @@ Foam::expressions::exprDriver::exprDriver
     (
         dict.getOrDefault("prevIterIsOldTime", false)
     ),
-    cacheReadFields_(cacheReadFields),
-    searchInMemory_(searchInMemory || cacheReadFields),
-    searchFiles_(searchFiles)
+    searchCtrl_(search)
 {}
 
 
@@ -122,6 +157,7 @@ Foam::expressions::exprDriver::exprDriver
     variableStrings_(rhs.variableStrings_),
     variables_(rhs.variables_),
     arg1Value_(rhs.arg1Value_),
+    timeStatePtr_(rhs.timeStatePtr_),
     stashedTokenId_(0),
 
     debugScanner_(rhs.debugScanner_),
@@ -129,23 +165,21 @@ Foam::expressions::exprDriver::exprDriver
     allowShadowing_(rhs.allowShadowing_),
     prevIterIsOldTime_(rhs.prevIterIsOldTime_),
 
-    cacheReadFields_(rhs.cacheReadFields_),
-    searchInMemory_(rhs.searchInMemory_),
-    searchFiles_(rhs.searchFiles_)
+    searchCtrl_(rhs.searchCtrl_)
 {}
 
 
 Foam::expressions::exprDriver::exprDriver
 (
-    const dictionary& dict
+    const dictionary& dict,
+    const TimeState* ts
 )
 :
     exprDriver
     (
-        dict.getOrDefault("cacheReadFields", false),
-        dict.getOrDefault("searchInMemory", true),
-        dict.getOrDefault("searchFiles", false),
-        dict
+        searchControls(exprDriver::getSearchControls(dict)),
+        dict,
+        ts
     )
 {
     readDict(dict);
@@ -154,6 +188,32 @@ Foam::expressions::exprDriver::exprDriver
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+const Foam::TimeState* Foam::expressions::exprDriver::timeState() const
+{
+    return timeStatePtr_;
+}
+
+
+Foam::scalar Foam::expressions::exprDriver::timeValue() const
+{
+    if (timeStatePtr_)
+    {
+        return timeStatePtr_->value();
+    }
+    return 0;
+}
+
+
+Foam::scalar Foam::expressions::exprDriver::deltaT() const
+{
+    if (timeStatePtr_)
+    {
+        return timeStatePtr_->deltaT().value();
+    }
+    return 0;
+}
+
+
 bool Foam::expressions::exprDriver::readDict
 (
     const dictionary& dict
@@ -196,18 +256,6 @@ void Foam::expressions::exprDriver::clearVariables()
 }
 
 
-void Foam::expressions::exprDriver::setArgument(scalar val)
-{
-    arg1Value_ = val;
-}
-
-
-Foam::scalar Foam::expressions::exprDriver::argValue() const
-{
-    return arg1Value_;
-}
-
-
 void Foam::expressions::exprDriver::evaluateVariable
 (
     const word& varName,
@@ -383,20 +431,58 @@ void Foam::expressions::exprDriver::setDebugging
 }
 
 
+bool Foam::expressions::exprDriver::setCaching(bool on) noexcept
+{
+    int val(searchCtrl_);
+    bool old = (val & searchControls::CACHE_READ_FIELDS);
+
+    if (!on)
+    {
+        // Off
+        val &= ~(searchControls::CACHE_READ_FIELDS);
+    }
+    else if (!old)
+    {
+        // Toggled on.
+        // Caching read fields implies both registry and disk use
+        val |=
+        (
+            searchControls::SEARCH_REGISTRY
+          | searchControls::SEARCH_FILES
+          | searchControls::CACHE_READ_FIELDS
+        );
+    }
+
+    searchCtrl_ = searchControls(val);
+
+    return old;
+}
+
+
 void Foam::expressions::exprDriver::setSearchBehaviour
 (
-    bool cacheReadFields,
-    bool searchInMemory,
-    bool searchFiles
+    enum searchControls search,
+    const bool caching
 )
 {
-    searchInMemory_ = searchInMemory_ || cacheReadFields_;
+    int val(search);
+    if (caching || (val & searchControls::CACHE_READ_FIELDS))
+    {
+        // Caching read fields implies both registry and disk use
+        val |=
+        (
+            searchControls::SEARCH_REGISTRY
+          | searchControls::SEARCH_FILES
+          | searchControls::CACHE_READ_FIELDS
+        );
+    }
+    searchCtrl_ = searchControls(val);
 
     #ifdef FULLDEBUG
     Info<< "Searching "
-        << " registry:" << searchInMemory_
-        << " disk:" << searchFiles_
-        << " cache-read:" << cacheReadFields_ << nl;
+        << " registry:" << searchRegistry()
+        << " disk:" << searchFiles()
+        << " cache-read:" << cacheReadFields() << nl;
     #endif
 }
 
@@ -406,12 +492,7 @@ void Foam::expressions::exprDriver::setSearchBehaviour
     const exprDriver& rhs
 )
 {
-    setSearchBehaviour
-    (
-        rhs.cacheReadFields_,
-        rhs.searchInMemory_,
-        rhs.searchFiles_
-    );
+    searchCtrl_ = rhs.searchCtrl_;
 }
 
 
diff --git a/src/OpenFOAM/expressions/exprDriver/exprDriver.H b/src/OpenFOAM/expressions/exprDriver/exprDriver.H
index 968030cd2bf..72dcb73e52e 100644
--- a/src/OpenFOAM/expressions/exprDriver/exprDriver.H
+++ b/src/OpenFOAM/expressions/exprDriver/exprDriver.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2010-2018 Bernhard Gschaider
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -68,6 +68,10 @@ SourceFiles
 
 namespace Foam
 {
+
+// Forward Declarations
+class TimeState;
+
 namespace expressions
 {
 
@@ -77,6 +81,29 @@ namespace expressions
 
 class exprDriver
 {
+public:
+
+    // Data Types
+
+        //- Search/caching controls
+        enum searchControls
+        {
+            NO_SEARCH = 0,
+            SEARCH_REGISTRY = 1,   //!< Search registry before disk
+            SEARCH_FILES = 2,      //!< Search disk (eg, standalone app)
+            CACHE_READ_FIELDS = 4, //!< Cache fields read from disk
+            DEFAULT_SEARCH = (SEARCH_REGISTRY)
+        };
+
+
+private:
+
+    // Private Member Functions
+
+        //- Get search/caching controls from dictionary entries
+        static int getSearchControls(const dictionary& dict);
+
+
 protected:
 
     // Protected Data
@@ -98,6 +125,9 @@ protected:
         //- Special-purpose scalar reference argument
         scalar arg1Value_;
 
+        //- Reference to the time-state
+        mutable const TimeState* timeStatePtr_;
+
 
     // Controls, tracing etc.
 
@@ -116,17 +146,27 @@ protected:
         //- Use value of previous iteration when oldTime is requested
         bool prevIterIsOldTime_;
 
-        //- Keep fields read from disc in memory
-        bool cacheReadFields_;
+        //- Registry/disk/caching control
+        searchControls searchCtrl_;
+
 
-        //- Search in registry before looking on disk
-        bool searchInMemory_;
+    // Protected Member Functions
 
-        //- Search on disk (eg, for a standalone application)
-        bool searchFiles_;
+        inline bool searchRegistry() const noexcept;
+        inline bool searchFiles() const noexcept;
+        inline bool cacheReadFields() const noexcept;
 
+        //- Reset the time-state reference
+        void resetTimeReference(const TimeState* ts);
 
-    // Protected Member Functions
+        //- Reset the time-state reference
+        void resetTimeReference(const TimeState& ts);
+
+        //- Lookup field object.
+        //  \return const-ref tmp or invalid if not found
+        template<class GeoField>
+        static tmp<GeoField>
+        cfindFieldObject(const objectRegistry& obr, const word& fldName);
 
         //- Read an interpolation table
         template<typename TableType>
@@ -159,7 +199,8 @@ protected:
         //- Fill a random field
         //
         //  \param field the field to populate
-        //  \param seed the seed value.
+        //  \param seed the seed value. If zero or negative, use as an offset
+        //      to the current timeIndex (if a time-state is available)
         //  \param gaussian generate a Gaussian distribution
         void fill_random
         (
@@ -227,20 +268,23 @@ public:
 
     // Constructors
 
-        //- Null constructor, and null construct with search preferences
+        //- Default construct, and default construct with search preferences
         explicit exprDriver
         (
-            bool cacheReadFields = false,
-            bool searchInMemory = true,
-            bool searchFiles = false,
-            const dictionary& dict = dictionary::null
+            enum searchControls search = searchControls::DEFAULT_SEARCH,
+            const dictionary& dict = dictionary::null,
+            const TimeState* ts = nullptr
         );
 
         //- Copy construct
-        exprDriver(const exprDriver&);
+        exprDriver(const exprDriver& rhs);
 
         //- Construct from a dictionary
-        explicit exprDriver(const dictionary& dict);
+        explicit exprDriver
+        (
+            const dictionary& dict,
+            const TimeState* ts = nullptr
+        );
 
 
     //- Destructor
@@ -261,20 +305,30 @@ public:
             return 1;
         }
 
+        //- Reference to the current time-state (can be nullptr)
+        const TimeState* timeState() const;
+
+        //- The current time value
+        virtual scalar timeValue() const;
+
+        //- The current deltaT value
+        virtual scalar deltaT() const;
+
+
         //- The dictionary with all input data/specification
-        const dictionary& dict() const
+        const dictionary& dict() const noexcept
         {
             return dict_;
         }
 
         //- Const access to expression result
-        virtual const exprResult& result() const
+        const exprResult& result() const noexcept
         {
             return result_;
         }
 
         //- Non-const access to expression result
-        virtual exprResult& result()
+        exprResult& result() noexcept
         {
             return result_;
         }
@@ -287,28 +341,28 @@ public:
         tmp<Field<Type>> getResult(bool wantPointData=false);
 
         //- The result type as word - same as result().valueType()
-        virtual word getResultType() const
+        const word& getResultType() const noexcept
         {
             return result_.valueType();
         }
 
 
-    // Globals, Mesh Related
+    // Specials
 
-        //- Set special-purpose scalar reference argument.
+        //- Get special-purpose scalar reference argument.
         //  Typically available as \c arg() in an expression and
-        //  may corrspond to table index, time value etc.
-        scalar argValue() const;
+        //  may correspond to table index, time value etc.
+        inline scalar argValue() const noexcept;
 
 
     // General Controls
 
         //- Get "look-behind" parsing context (internal bookkeeping)
-        inline int stashedTokenId() const;
+        inline int stashedTokenId() const noexcept;
 
         //- Reset "look-behind" parsing context (mutable operation)
         //  \return the previous value
-        inline int resetStashedTokenId(int tokenId=0) const;
+        inline int resetStashedTokenId(int tokenId=0) const noexcept;
 
 
         //- Set the scanner/parser debug
@@ -317,26 +371,26 @@ public:
         //- Set the scanner/parser debug to match the input
         void setDebugging(const exprDriver& rhs);
 
-        //- Set search behaviour
+        //- Toggle CACHE_READ_FIELDS control
+        bool setCaching(bool on) noexcept;
+
+        //- Set search behaviour,
+        //- with additional CACHE_READ_FIELDS toggle on
         void setSearchBehaviour
         (
-            bool cacheReadFields,
-            bool searchInMemory,
-            bool searchFiles
+            enum searchControls search,
+            const bool caching = false
         );
 
         //- Set search behaviour to be identical to rhs
         void setSearchBehaviour(const exprDriver& rhs);
 
         //- Read access to scanner debug
-        bool debugScanner() const { return debugScanner_; }
+        inline bool debugScanner() const noexcept;
 
         //- Read access to parser debug
-        bool debugParser() const { return debugParser_; }
+        inline bool debugParser() const noexcept;
 
-        bool cacheReadFields() const { return cacheReadFields_; }
-        bool searchInMemory() const { return searchInMemory_; }
-        bool searchFiles() const { return searchFiles_; }
         bool prevIterIsOldTime() const { return prevIterIsOldTime_; }
 
 
@@ -348,7 +402,7 @@ public:
         //- Set special-purpose scalar reference argument.
         //  Typically available as \c arg() in an expression and
         //  may corrspond to table index, time value etc.
-        virtual void setArgument(const scalar val);
+        inline void setArgument(const scalar val) noexcept;
 
         //- True if named variable exists
         inline virtual bool hasVariable(const word& name) const;
diff --git a/src/OpenFOAM/expressions/exprDriver/exprDriverFields.C b/src/OpenFOAM/expressions/exprDriver/exprDriverFields.C
index 368ab87273e..6511cec7bba 100644
--- a/src/OpenFOAM/expressions/exprDriver/exprDriverFields.C
+++ b/src/OpenFOAM/expressions/exprDriver/exprDriverFields.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,6 +28,7 @@ License
 #include "exprDriver.H"
 #include "FieldOps.H"
 #include "Random.H"
+#include "TimeState.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -38,6 +39,18 @@ void Foam::expressions::exprDriver::fill_random
     const bool gaussian
 ) const
 {
+    if (seed <= 0)
+    {
+        if (timeStatePtr_)
+        {
+            seed = (timeStatePtr_->timeIndex() - seed);
+        }
+        else
+        {
+            seed = -seed;
+        }
+    }
+
     if (gaussian)
     {
         Random::gaussianGeneratorOp<scalar> gen(seed);
diff --git a/src/OpenFOAM/expressions/exprDriver/exprDriverI.H b/src/OpenFOAM/expressions/exprDriver/exprDriverI.H
index 6924af55e19..478218a5c2a 100644
--- a/src/OpenFOAM/expressions/exprDriver/exprDriverI.H
+++ b/src/OpenFOAM/expressions/exprDriver/exprDriverI.H
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2010-2018 Bernhard Gschaider
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,6 +28,18 @@ License
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+inline void Foam::expressions::exprDriver::setArgument(scalar val) noexcept
+{
+    arg1Value_ = val;
+}
+
+
+inline Foam::scalar Foam::expressions::exprDriver::argValue() const noexcept
+{
+    return arg1Value_;
+}
+
+
 inline bool Foam::expressions::exprDriver::hasVariable
 (
     const word& name
@@ -101,7 +113,7 @@ inline Type Foam::expressions::exprDriver::evaluateUniform
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-inline int Foam::expressions::exprDriver::stashedTokenId() const
+inline int Foam::expressions::exprDriver::stashedTokenId() const noexcept
 {
     return stashedTokenId_;
 }
@@ -110,12 +122,42 @@ inline int Foam::expressions::exprDriver::stashedTokenId() const
 inline int Foam::expressions::exprDriver::resetStashedTokenId
 (
     int tokenId
-) const
+) const noexcept
 {
-    const int old = stashedTokenId_;
+    int old = stashedTokenId_;
     stashedTokenId_ = tokenId;
     return old;
 }
 
 
+inline bool Foam::expressions::exprDriver::debugScanner() const noexcept
+{
+    return debugScanner_;
+}
+
+
+inline bool Foam::expressions::exprDriver::debugParser() const noexcept
+{
+    return debugParser_;
+}
+
+
+inline bool Foam::expressions::exprDriver::searchRegistry() const noexcept
+{
+    return (searchCtrl_ & searchControls::SEARCH_REGISTRY);
+}
+
+
+inline bool Foam::expressions::exprDriver::searchFiles() const noexcept
+{
+    return (searchCtrl_ & searchControls::SEARCH_FILES);
+}
+
+
+inline bool Foam::expressions::exprDriver::cacheReadFields() const noexcept
+{
+    return (searchCtrl_ & searchControls::CACHE_READ_FIELDS);
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/expressions/exprDriver/exprDriverTemplates.C b/src/OpenFOAM/expressions/exprDriver/exprDriverTemplates.C
index 1a33ecee4ae..b4e9879f07f 100644
--- a/src/OpenFOAM/expressions/exprDriver/exprDriverTemplates.C
+++ b/src/OpenFOAM/expressions/exprDriver/exprDriverTemplates.C
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2010-2018
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,7 +26,25 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+#include "objectRegistry.H"
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+template<class GeoField>
+Foam::tmp<GeoField>
+Foam::expressions::exprDriver::cfindFieldObject
+(
+    const objectRegistry& obr,
+    const word& fldName
+)
+{
+    tmp<GeoField> tfld;
+
+    tfld.cref(obr.cfindObject<GeoField>(fldName));
+
+    return tfld;
+}
+
 
 template<class TableType>
 bool Foam::expressions::exprDriver::readTable
diff --git a/src/OpenFOAM/expressions/exprResult/exprResult.H b/src/OpenFOAM/expressions/exprResult/exprResult.H
index 7e66ceaef6a..66c28e93c1c 100644
--- a/src/OpenFOAM/expressions/exprResult/exprResult.H
+++ b/src/OpenFOAM/expressions/exprResult/exprResult.H
@@ -388,7 +388,7 @@ public:
         inline bool hasValue() const;
 
         //- Basic type for the field or single value
-        inline const word& valueType() const;
+        inline const word& valueType() const noexcept;
 
         //- True if representing point data,
         //- or test for same value as wantPointData argument
diff --git a/src/OpenFOAM/expressions/exprResult/exprResultI.H b/src/OpenFOAM/expressions/exprResult/exprResultI.H
index a8246355d4a..c4ee1b783e9 100644
--- a/src/OpenFOAM/expressions/exprResult/exprResultI.H
+++ b/src/OpenFOAM/expressions/exprResult/exprResultI.H
@@ -240,7 +240,8 @@ inline bool Foam::expressions::exprResult::hasValue() const
 }
 
 
-inline const Foam::word& Foam::expressions::exprResult::valueType() const
+inline const Foam::word&
+Foam::expressions::exprResult::valueType() const noexcept
 {
     return valType_;
 }
diff --git a/src/OpenFOAM/expressions/fields/fieldExprDriver.C b/src/OpenFOAM/expressions/fields/fieldExprDriver.C
index 91ab582f170..5959596d0c2 100644
--- a/src/OpenFOAM/expressions/fields/fieldExprDriver.C
+++ b/src/OpenFOAM/expressions/fields/fieldExprDriver.C
@@ -49,12 +49,6 @@ defineTypeNameAndDebug(parseDriver, 0);
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::expressions::fieldExpr::parseDriver::parseDriver()
-:
-    parseDriver(1)
-{}
-
-
 Foam::expressions::fieldExpr::parseDriver::parseDriver
 (
     const label len
diff --git a/src/OpenFOAM/expressions/fields/fieldExprDriver.H b/src/OpenFOAM/expressions/fields/fieldExprDriver.H
index 29bfbdbd543..74078773508 100644
--- a/src/OpenFOAM/expressions/fields/fieldExprDriver.H
+++ b/src/OpenFOAM/expressions/fields/fieldExprDriver.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,7 +36,7 @@ Description
     Functions
     \table
         Function    | Description                      | Number of arguments |
-        rand        | Random field                          | 0/1 |
+        rand        | Random field                     | 0/1 |
     \endtable
 
 Note
@@ -98,11 +98,8 @@ public:
 
     // Constructors
 
-        //- Default construct - uses size = 1
-        parseDriver();
-
-        //- Construct with specified size
-        explicit parseDriver(const label len);
+        //- Default construct (size=1), or with specified size
+        explicit parseDriver(const label len = 1);
 
         //- Construct for specified size with given dictionary
         parseDriver(const label len, const dictionary& dict);
diff --git a/src/OpenFOAM/expressions/fields/fieldExprLemonParser.h b/src/OpenFOAM/expressions/fields/fieldExprLemonParser.h
index e27e88ba5a5..3624697ee51 100644
--- a/src/OpenFOAM/expressions/fields/fieldExprLemonParser.h
+++ b/src/OpenFOAM/expressions/fields/fieldExprLemonParser.h
@@ -26,66 +26,68 @@
 #define TOK_DEG_TO_RAD                      26
 #define TOK_RAD_TO_DEG                      27
 #define TOK_ARG                             28
-#define TOK_SCALAR_ID                       29
-#define TOK_MIN                             30
-#define TOK_COMMA                           31
-#define TOK_MAX                             32
-#define TOK_SUM                             33
-#define TOK_AVERAGE                         34
-#define TOK_EXP                             35
-#define TOK_LOG                             36
-#define TOK_LOG10                           37
-#define TOK_SQR                             38
-#define TOK_SQRT                            39
-#define TOK_CBRT                            40
-#define TOK_SIN                             41
-#define TOK_COS                             42
-#define TOK_TAN                             43
-#define TOK_ASIN                            44
-#define TOK_ACOS                            45
-#define TOK_ATAN                            46
-#define TOK_SINH                            47
-#define TOK_COSH                            48
-#define TOK_TANH                            49
-#define TOK_POW                             50
-#define TOK_ATAN2                           51
-#define TOK_POS                             52
-#define TOK_NEG                             53
-#define TOK_POS0                            54
-#define TOK_NEG0                            55
-#define TOK_SIGN                            56
-#define TOK_FLOOR                           57
-#define TOK_CEIL                            58
-#define TOK_ROUND                           59
-#define TOK_HYPOT                           60
-#define TOK_RAND                            61
-#define TOK_VECTOR_ID                       62
-#define TOK_SPH_TENSOR_ID                   63
-#define TOK_SYM_TENSOR_ID                   64
-#define TOK_IDENTITY_TENSOR                 65
-#define TOK_TENSOR_ID                       66
-#define TOK_LTRUE                           67
-#define TOK_LFALSE                          68
-#define TOK_BOOL                            69
-#define TOK_BOOL_ID                         70
-#define TOK_MAG                             71
-#define TOK_MAGSQR                          72
-#define TOK_VECTOR                          73
-#define TOK_TENSOR                          74
-#define TOK_SYM_TENSOR                      75
-#define TOK_SPH_TENSOR                      76
-#define TOK_CMPT_X                          77
-#define TOK_CMPT_Y                          78
-#define TOK_CMPT_Z                          79
-#define TOK_CMPT_XX                         80
-#define TOK_CMPT_XY                         81
-#define TOK_CMPT_XZ                         82
-#define TOK_CMPT_YX                         83
-#define TOK_CMPT_YY                         84
-#define TOK_CMPT_YZ                         85
-#define TOK_CMPT_ZX                         86
-#define TOK_CMPT_ZY                         87
-#define TOK_CMPT_ZZ                         88
-#define TOK_CMPT_II                         89
-#define TOK_TRANSPOSE                       90
-#define TOK_DIAG                            91
+#define TOK_TIME                            29
+#define TOK_DELTA_T                         30
+#define TOK_SCALAR_ID                       31
+#define TOK_MIN                             32
+#define TOK_COMMA                           33
+#define TOK_MAX                             34
+#define TOK_SUM                             35
+#define TOK_AVERAGE                         36
+#define TOK_EXP                             37
+#define TOK_LOG                             38
+#define TOK_LOG10                           39
+#define TOK_SQR                             40
+#define TOK_SQRT                            41
+#define TOK_CBRT                            42
+#define TOK_SIN                             43
+#define TOK_COS                             44
+#define TOK_TAN                             45
+#define TOK_ASIN                            46
+#define TOK_ACOS                            47
+#define TOK_ATAN                            48
+#define TOK_SINH                            49
+#define TOK_COSH                            50
+#define TOK_TANH                            51
+#define TOK_POW                             52
+#define TOK_ATAN2                           53
+#define TOK_POS                             54
+#define TOK_NEG                             55
+#define TOK_POS0                            56
+#define TOK_NEG0                            57
+#define TOK_SIGN                            58
+#define TOK_FLOOR                           59
+#define TOK_CEIL                            60
+#define TOK_ROUND                           61
+#define TOK_HYPOT                           62
+#define TOK_RAND                            63
+#define TOK_VECTOR_ID                       64
+#define TOK_SPH_TENSOR_ID                   65
+#define TOK_SYM_TENSOR_ID                   66
+#define TOK_IDENTITY_TENSOR                 67
+#define TOK_TENSOR_ID                       68
+#define TOK_LTRUE                           69
+#define TOK_LFALSE                          70
+#define TOK_BOOL                            71
+#define TOK_BOOL_ID                         72
+#define TOK_MAG                             73
+#define TOK_MAGSQR                          74
+#define TOK_VECTOR                          75
+#define TOK_TENSOR                          76
+#define TOK_SYM_TENSOR                      77
+#define TOK_SPH_TENSOR                      78
+#define TOK_CMPT_X                          79
+#define TOK_CMPT_Y                          80
+#define TOK_CMPT_Z                          81
+#define TOK_CMPT_XX                         82
+#define TOK_CMPT_XY                         83
+#define TOK_CMPT_XZ                         84
+#define TOK_CMPT_YX                         85
+#define TOK_CMPT_YY                         86
+#define TOK_CMPT_YZ                         87
+#define TOK_CMPT_ZX                         88
+#define TOK_CMPT_ZY                         89
+#define TOK_CMPT_ZZ                         90
+#define TOK_CMPT_II                         91
+#define TOK_TRANSPOSE                       92
+#define TOK_DIAG                            93
diff --git a/src/OpenFOAM/expressions/fields/fieldExprLemonParser.lyy-m4 b/src/OpenFOAM/expressions/fields/fieldExprLemonParser.lyy-m4
index 2c5784cc045..a7797b50edc 100644
--- a/src/OpenFOAM/expressions/fields/fieldExprLemonParser.lyy-m4
+++ b/src/OpenFOAM/expressions/fields/fieldExprLemonParser.lyy-m4
@@ -166,7 +166,8 @@ svalue (lhs) ::= PI LPAREN RPAREN . { lhs = Foam::constant::mathematical::pi; }
 svalue (lhs) ::= DEG_TO_RAD LPAREN RPAREN . { lhs = Foam::degToRad(); }
 svalue (lhs) ::= RAD_TO_DEG LPAREN RPAREN . { lhs = Foam::radToDeg(); }
 svalue (lhs) ::= ARG LPAREN RPAREN . { lhs = driver->argValue(); }
-dnl svalue (lhs) ::= TIME LPAREN RPAREN . { lhs = driver->timeValue(); }
+svalue (lhs) ::= TIME LPAREN RPAREN . { lhs = driver->timeValue(); }
+svalue (lhs) ::= DELTA_T LPAREN RPAREN . { lhs = driver->deltaT(); }
 
 
 /* * * * * * * * * * * * * * * * * * Fields  * * * * * * * * * * * * * * * * *\
diff --git a/src/OpenFOAM/expressions/fields/fieldExprScanner.H b/src/OpenFOAM/expressions/fields/fieldExprScanner.H
index 6c010698642..2c7b877ec1b 100644
--- a/src/OpenFOAM/expressions/fields/fieldExprScanner.H
+++ b/src/OpenFOAM/expressions/fields/fieldExprScanner.H
@@ -57,7 +57,7 @@ union scanToken
     Foam::scalar svalue;
     Foam::word*  name;
 
-    //- Null construct, bit-wise zero for union content
+    //- Default construct, bit-wise zero for union content
     scanToken() : ivalue(0) {}
 };
 
@@ -73,7 +73,7 @@ class scanner
         //- Wrapped lemon parser
         parser* parser_;
 
-        // Ragel code state, action
+        //- Ragel code state, action
         int cs, act;
 
 
@@ -104,7 +104,7 @@ public:
 
     // Constructors
 
-        //- Construct null, optionally setting debugging
+        //- Default construct, optionally setting debugging
         explicit scanner(bool withDebug = false)
         :
             parser_(nullptr),
diff --git a/src/OpenFOAM/expressions/fields/fieldExprScanner.cc b/src/OpenFOAM/expressions/fields/fieldExprScanner.cc
index caf34d2e115..fb34d6ec33b 100644
--- a/src/OpenFOAM/expressions/fields/fieldExprScanner.cc
+++ b/src/OpenFOAM/expressions/fields/fieldExprScanner.cc
@@ -171,7 +171,7 @@ static const int fieldExpr_error = 0;
 static const int fieldExpr_en_main = 11;
 
 
-#line 304 "fieldExprScanner.rl"
+#line 305 "fieldExprScanner.rl"
 
 
 
@@ -411,7 +411,7 @@ bool Foam::expressions::fieldExpr::scanner::process
 	act = 0;
 	}
 
-#line 534 "fieldExprScanner.rl"
+#line 535 "fieldExprScanner.rl"
    /* ^^^ FSM initialization here ^^^ */;
 
     
@@ -3385,7 +3385,7 @@ case 10:
 	_out: {}
 	}
 
-#line 536 "fieldExprScanner.rl"
+#line 537 "fieldExprScanner.rl"
    /* ^^^ FSM execution here ^^^ */;
 
     if (0 == cs)
diff --git a/src/OpenFOAM/expressions/fields/fieldExprScanner.rl b/src/OpenFOAM/expressions/fields/fieldExprScanner.rl
index 2a0b5bbee1d..e2377ac5bc0 100644
--- a/src/OpenFOAM/expressions/fields/fieldExprScanner.rl
+++ b/src/OpenFOAM/expressions/fields/fieldExprScanner.rl
@@ -212,7 +212,7 @@ static int driverTokenType
 
     number => emit_number;
 
-    ## operators
+    ## Operators
     '!'  =>{ EMIT_TOKEN(NOT); };
     '%'  =>{ EMIT_TOKEN(PERCENT); };
     '('  =>{ EMIT_TOKEN(LPAREN); };
@@ -292,6 +292,7 @@ static int driverTokenType
     "tensor::I" =>{ EMIT_TOKEN(IDENTITY_TENSOR); };
     "arg"       =>{ EMIT_TOKEN(ARG); };
 ##    "time"      =>{ EMIT_TOKEN(TIME); };
+##    "deltaT"    =>{ EMIT_TOKEN(DELTA_T); };
 
     ## Identifier (field, etc - error if unknown)
     ## Handle 'bare' names and single/double quoted ones
diff --git a/src/OpenFOAM/include/m4/lemon/rules-fields.m4 b/src/OpenFOAM/include/m4/lemon/rules-fields.m4
index 178e91e6c6f..2f2faf2169f 100644
--- a/src/OpenFOAM/include/m4/lemon/rules-fields.m4
+++ b/src/OpenFOAM/include/m4/lemon/rules-fields.m4
@@ -6,11 +6,10 @@ divert(-1)dnl
 #     \\  /    A nd           | www.openfoam.com
 #      \\/     M anipulation  |
 #------------------------------------------------------------------------------
-#     Copyright (C) 2019 OpenCFD Ltd.
+#     Copyright (C) 2019-2021 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, distributed under GNU General Public
-#     License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Description
 #     Field handling m4/lemon macros.
@@ -47,7 +46,8 @@ divert(-1)dnl
 #------------------------------------------------------------------------------
 
 define([declare_field],
-[define([_value_type_]$1, [$3])dnl
+[dnl
+define([_value_type_]$1, [$3])dnl
 define([_new_]$1, [driver->$4<$3>($][1).ptr()])dnl
 define([_get_]$1, [driver->$5<$3>($][1).ptr()])dnl
 %type $1 { $2* }])
@@ -92,11 +92,7 @@ define([rule_get_field],
 #------------------------------------------------------------------------------
 
 define([rule_driver_select],
-[$1 (lhs) ::= $2 LPAREN IDENTIFIER (ident) RPAREN .
-{
-    lhs = driver->$3(make_obj(ident->name)).ptr();
-}]
-)
+[rule_driver_unary_named($1, $2, IDENTIFIER, $3)])
 
 
 #------------------------------------------------------------------------------
@@ -129,13 +125,13 @@ define([rule_field_from_value],
 
 
 #------------------------------------------------------------------------------
-# rule_negate_op(target, valType)
+# rule_negate_op(target)
 #
 # Description
 #     Production rules for field negation
 #
 # Example
-#     rule_negate_op(sfield, Foam::scalar)
+#     rule_negate_op(sfield)
 #------------------------------------------------------------------------------
 
 define([rule_negate_op],
@@ -167,7 +163,8 @@ define([rule_binary_op],
 [$1 (lhs) ::= $2 (a) $4 $3 (b) .
 {
     lhs = (make_tmp(a) $5 make_tmp(b)).ptr();
-}])
+}]
+)
 
 
 #------------------------------------------------------------------------------
@@ -263,7 +260,7 @@ define([rule_const_multiply],
 
 
 #------------------------------------------------------------------------------
-# rule_scalar_divide(out, in1, in2, [valType])
+# rule_scalar_divide(out, in1, in2, [value_type])
 #
 # Description
 #     Production rule for division by scalar operation
@@ -332,8 +329,8 @@ define([rule_scalar_modulo],
 # rule_unary_assign(out, in, tok, function)
 #
 # Description
-#     Production rule for a unary function, using FieldOps::assign for the
-#     implementation.
+#     Production rule for a unary function,
+#     using FieldOps::assign for the implementation.
 #
 # Example
 # rule_unary_assign(sfield, sfield, FLOOR, Foam::floorOp<Foam::scalar>())
@@ -353,8 +350,8 @@ define([rule_unary_assign],
 # rule_binary_assign(out, in1, in2, tok, function)
 #
 # Description
-#     Production rule for a binary function, using FieldOps::assign for the
-#     implementation.
+#     Production rule for a binary function,
+#     using FieldOps::assign for the implementation.
 #
 # Example
 # rule_binary_assign(sfield, sfield, sfield, HYPOT, Foam::hypot)
@@ -374,7 +371,7 @@ define([rule_binary_assign],
 # rule_driver_nullary(out, tok, func)
 #
 # Description
-#     Production rule for driver-specific field reduction
+#     Production rule for driver-specific nullary method.
 #
 # Example
 # rule_driver_nullary(vfield, POS, field_cellCentre)
@@ -393,10 +390,11 @@ define([rule_driver_nullary],
 
 
 #------------------------------------------------------------------------------
-# rule_driver_inplace_unary(inOut, tok, func)
+# rule_driver_inplace_unary(inOut, tok, method)
 #
 # Description
-#     Production rule for driver-specific field reduction
+#     Production rule for a driver-specific unary method
+#     modifying the field inplace.
 #
 # Example
 # rule_driver_inplace_unary(sfield, WEIGHTED_AVERAGE, volAverage)
@@ -416,10 +414,10 @@ define([rule_driver_inplace_unary],
 
 
 #------------------------------------------------------------------------------
-# rule_driver_unary(out, in, tok, func)
+# rule_driver_unary(out, in, tok, method, [value_type])
 #
 # Description
-#     Production rule for driver-specific field reduction
+#     Production rule for a driver-specific unary method
 #
 # Example
 # rule_driver_unary(sfield, psfield, POINT_TO_CELL, pointToCell)
@@ -433,7 +431,42 @@ define([rule_driver_inplace_unary],
 define([rule_driver_unary],
 [$1 (lhs) ::= $3 LPAREN $2 (a) RPAREN .
 {
-    lhs = driver->$4(make_obj(a)).ptr();
+    lhs = driver->$4[]dnl       # The method call
+ifelse($5,[],[],[<$5>])dnl      # Optional template parameter (value_type)
+(make_obj(a)).ptr();
+}]
+)
+
+
+#------------------------------------------------------------------------------
+# rule_driver_unary_named(out, tok, identType, method, [value_type])
+#
+# Description
+#     Production rule for a driver-specific unary method
+#
+# Example
+#     rule_driver_unary_named
+#     (
+#        sfield,
+#        SN_GRAD,
+#        SCALAR_ID,
+#        patchNormalField,
+#        Foam::scalar
+#    )
+#
+# sfield(lhs) ::= SN_GRAD LPAREN SCALAR_ID (ident) RPAREN .
+# {
+#     lhs = driver->patchNormalField<Foam::scalar>(make_obj(ident->name)).ptr();
+# }
+#
+#------------------------------------------------------------------------------
+
+define([rule_driver_unary_named],
+[$1 (lhs) ::= $2 LPAREN $3 (ident) RPAREN .
+{
+    lhs = driver->$4[]dnl       # The method call
+ifelse($5,[],[],[<$5>])dnl      # Optional template parameter (value_type)
+(make_obj(ident->name)).ptr();
 }]
 )
 
diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files
index a251a1fe4f4..be371512455 100644
--- a/src/finiteVolume/Make/files
+++ b/src/finiteVolume/Make/files
@@ -269,12 +269,10 @@ fields/volFields/volFields.C
 fields/surfaceFields/surfaceFields.C
 
 expr = expressions
-$(expr)/base/exprDriverWriter.C
-
 $(expr)/base/fvExprDriver.C
-$(expr)/base/fvExprDriverFields.C
 $(expr)/base/fvExprDriverIO.C
 $(expr)/base/fvExprDriverNew.C
+$(expr)/base/fvExprDriverWriter.C
 
 patchExpr = $(expr)/patch
 $(patchExpr)/patchExpr.C
diff --git a/src/finiteVolume/expressions/base/fvExprDriver.C b/src/finiteVolume/expressions/base/fvExprDriver.C
index a73c38986bf..a31ea14268f 100644
--- a/src/finiteVolume/expressions/base/fvExprDriver.C
+++ b/src/finiteVolume/expressions/base/fvExprDriver.C
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2010-2018 Bernhard Gschaider
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,7 +27,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "fvExprDriver.H"
-#include "exprDriverWriter.H"
+#include "fvExprDriverWriter.H"
 #include "expressionEntry.H"
 #include "exprResultGlobals.H"
 
@@ -94,19 +94,12 @@ const Foam::fvMesh* Foam::expressions::fvExprDriver::resetDefaultMesh
 
 Foam::expressions::fvExprDriver::fvExprDriver
 (
-    bool cacheReadFields,
-    bool searchInMemory,
-    bool searchFiles,
-    const dictionary& dict
+    enum exprDriver::searchControls search,
+    const dictionary& dict,
+    const TimeState* ts
 )
 :
-    expressions::exprDriver
-    (
-        cacheReadFields,
-        searchInMemory,
-        searchFiles,
-        dict
-    ),
+    expressions::exprDriver(search, dict, ts),
     globalScopes_(),
     delayedVariables_(),
     storedVariables_(),
@@ -133,16 +126,17 @@ Foam::expressions::fvExprDriver::fvExprDriver
 
 Foam::expressions::fvExprDriver::fvExprDriver
 (
-    const dictionary& dict
+    const dictionary& dict,
+    const TimeState* ts
 )
 :
-    fvExprDriver
-    (
-        dict.getOrDefault("cacheReadFields", false),
-        dict.getOrDefault("searchInMemory", true),
-        dict.getOrDefault("searchFiles", false),
-        dict
-    )
+    expressions::exprDriver(dict, ts),
+    globalScopes_(),
+    delayedVariables_(),
+    storedVariables_(),
+    specialVariablesIndex_(-1),
+    otherMeshName_(),
+    writer_(nullptr)
 {
     readDict(dict);
 }
@@ -168,7 +162,7 @@ bool Foam::expressions::fvExprDriver::readDict
     // {
     //     for (const fileName& libName : plugins)
     //     {
-    //         this->runTime().libs().open
+    //         this->mesh().time().libs().open
     //         (
     //             "libswak" + libName + "FunctionPlugin"  // verbose = true
     //         );
@@ -244,24 +238,6 @@ bool Foam::expressions::fvExprDriver::readDict
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-const Foam::Time& Foam::expressions::fvExprDriver::runTime() const
-{
-    return this->mesh().time();
-}
-
-
-Foam::word Foam::expressions::fvExprDriver::timeName() const
-{
-    return runTime().timeName();
-}
-
-
-Foam::scalar Foam::expressions::fvExprDriver::timeValue() const
-{
-    return runTime().value();
-}
-
-
 void Foam::expressions::fvExprDriver::updateSpecialVariables(bool force)
 {
     const bool updated = this->update();
@@ -594,7 +570,7 @@ Foam::word Foam::expressions::fvExprDriver::getFieldClassName
     const word& name
 ) const
 {
-    if (searchInMemory())
+    if (searchRegistry())
     {
         const regIOobject* ioptr = this->mesh().findObject<regIOobject>(name);
 
diff --git a/src/finiteVolume/expressions/base/fvExprDriver.H b/src/finiteVolume/expressions/base/fvExprDriver.H
index fe49ba05a50..3d38ab6b975 100644
--- a/src/finiteVolume/expressions/base/fvExprDriver.H
+++ b/src/finiteVolume/expressions/base/fvExprDriver.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2010-2018 Bernhard Gschaider
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -53,7 +53,6 @@ Description
 SourceFiles
     fvExprDriverI.H
     fvExprDriver.C
-    fvExprDriverFields.C
     fvExprDriverIO.C
     fvExprDriverNew.C
     fvExprDriverTemplates.C
@@ -79,7 +78,7 @@ namespace expressions
 {
 
 // Forward Declarations
-class exprDriverWriter;
+class fvExprDriverWriter;
 
 /*---------------------------------------------------------------------------*\
                          Class fvExprDriver Declaration
@@ -118,7 +117,7 @@ class fvExprDriver
         word otherMeshName_;
 
         //- Writing and restoring
-        autoPtr<exprDriverWriter> writer_;
+        autoPtr<fvExprDriverWriter> writer_;
 
 
     // Private Member Functions
@@ -268,19 +267,6 @@ protected:
             const MeshRef& meshRef
         );
 
-        //- Create a random field
-        //
-        //  \param field the field to populate
-        //  \param seed the seed value. If zero or negative, use as an offset
-        //      to the current timeIndex
-        //  \param gaussian generate a Gaussian distribution
-        void fill_random
-        (
-            scalarField& field,
-            label seed = 0,
-            const bool gaussian = false
-        ) const;
-
 
     // Sets
 
@@ -325,7 +311,7 @@ protected:
 public:
 
     // Friends
-    friend class exprDriverWriter;
+    friend class fvExprDriverWriter;
 
 
     // Static Member Functions
@@ -374,20 +360,24 @@ public:
 
     // Constructors
 
-        //- Null constructor, and null construct with search preferences
+        //- Default construct, and default construct with search preferences
         explicit fvExprDriver
         (
-            bool cacheReadFields = false,
-            bool searchInMemory = true,
-            bool searchFiles = false,
-            const dictionary& dict = dictionary::null
+            enum exprDriver::searchControls search =
+                exprDriver::searchControls::DEFAULT_SEARCH,
+            const dictionary& dict = dictionary::null,
+            const TimeState* ts = nullptr
         );
 
         //- Copy construct
         fvExprDriver(const fvExprDriver&);
 
         //- Construct from a dictionary
-        explicit fvExprDriver(const dictionary& dict);
+        explicit fvExprDriver
+        (
+            const dictionary& dict,
+            const TimeState* ts = nullptr
+        );
 
 
         //- Return a reference to the selected value driver
@@ -428,18 +418,6 @@ public:
         virtual label pointSize() const = 0;
 
 
-    // Globals, Mesh Related
-
-        //- The Time associated with the mesh
-        const Time& runTime() const;
-
-        //- The current time name
-        virtual word timeName() const;
-
-        //- The current time value
-        virtual scalar timeValue() const;
-
-
     // General Controls
 
         //- Status of cache-sets (static variable)
diff --git a/src/finiteVolume/expressions/base/fvExprDriverFields.C b/src/finiteVolume/expressions/base/fvExprDriverFields.C
deleted file mode 100644
index d2610385a81..00000000000
--- a/src/finiteVolume/expressions/base/fvExprDriverFields.C
+++ /dev/null
@@ -1,49 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | www.openfoam.com
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
-    Copyright (C) 2019 OpenCFD Ltd.
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "fvExprDriver.H"
-#include "Time.H"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::expressions::fvExprDriver::fill_random
-(
-    scalarField& field,
-    label seed,
-    const bool gaussian
-) const
-{
-    exprDriver::fill_random
-    (
-        field, (seed <= 0 ? (runTime().timeIndex() - seed) : seed),
-        gaussian
-    );
-}
-
-
-// ************************************************************************* //
diff --git a/src/finiteVolume/expressions/base/fvExprDriverI.H b/src/finiteVolume/expressions/base/fvExprDriverI.H
index 5ad3c395f3e..949f58f1e99 100644
--- a/src/finiteVolume/expressions/base/fvExprDriverI.H
+++ b/src/finiteVolume/expressions/base/fvExprDriverI.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
+    Copyright (C) 2010-2018 Bernhard Gschaider
     Copyright (C) 2019-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
diff --git a/src/finiteVolume/expressions/base/fvExprDriverIO.C b/src/finiteVolume/expressions/base/fvExprDriverIO.C
index 93a64e1a2a7..33c5f1dff6c 100644
--- a/src/finiteVolume/expressions/base/fvExprDriverIO.C
+++ b/src/finiteVolume/expressions/base/fvExprDriverIO.C
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2010-2018 Bernhard Gschaider
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,7 +27,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "fvExprDriver.H"
-#include "exprDriverWriter.H"
+#include "fvExprDriverWriter.H"
 #include "cellSet.H"
 #include "faceSet.H"
 #include "pointSet.H"
@@ -263,7 +263,7 @@ void Foam::expressions::fvExprDriver::createWriterAndRead(const word& name)
 {
     if (!writer_ && hasDataToWrite())
     {
-        writer_.reset(new exprDriverWriter(name + "_" + this->type(), *this));
+        writer_.reset(new fvExprDriverWriter(name + "_" + this->type(), *this));
     }
 }
 
diff --git a/src/finiteVolume/expressions/base/fvExprDriverNew.C b/src/finiteVolume/expressions/base/fvExprDriverNew.C
index f2abd79e7be..98c5fae422b 100644
--- a/src/finiteVolume/expressions/base/fvExprDriverNew.C
+++ b/src/finiteVolume/expressions/base/fvExprDriverNew.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
+    Copyright (C) 2010-2018 Bernhard Gschaider
     Copyright (C) 2019 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
diff --git a/src/finiteVolume/expressions/base/fvExprDriverTemplates.C b/src/finiteVolume/expressions/base/fvExprDriverTemplates.C
index 2ee53ed84e2..dc00ffebceb 100644
--- a/src/finiteVolume/expressions/base/fvExprDriverTemplates.C
+++ b/src/finiteVolume/expressions/base/fvExprDriverTemplates.C
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2010-2018 Bernhard Gschaider
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -29,6 +29,7 @@ License
 #include "surfaceMesh.H"
 #include "fvsPatchField.H"
 #include "pointPatchField.H"
+#include "typeInfo.H"
 
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
@@ -141,16 +142,16 @@ bool Foam::expressions::fvExprDriver::foundField
     {
         Info<< "fvExprDriver::foundField. Name: " << name
             << " Type: " << Type::typeName
-            << " registry:" << searchInMemory()
+            << " registry:" << searchRegistry()
             << " disk:" << searchFiles() << endl;
     }
 
     // if (std::is_void<Type>::value) ...
 
-    if (searchInMemory())
+    if (searchRegistry())
     {
         const regIOobject* ioptr =
-            this->mesh().findObject<regIOobject>(name);
+            this->mesh().cfindObject<regIOobject>(name);
 
         if (this->mesh().foundObject<Type>(name))
         {
@@ -332,7 +333,7 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
 
     if
     (
-        searchInMemory()
+        searchRegistry()
      && (origFldPtr = obr.cfindObject<GeomField>(name)) != nullptr
     )
     {
@@ -494,7 +495,7 @@ Foam::autoPtr<T> Foam::expressions::fvExprDriver::getTopoSet
     }
     else
     {
-        const T* ptr = mesh.thisDb().findObject<T>(name);
+        const T* ptr = mesh.thisDb().cfindObject<T>(name);
 
         if (ptr)
         {
@@ -534,7 +535,7 @@ bool Foam::expressions::fvExprDriver::updateSet
     const label oldSize = setPtr->size();
 
     bool updated = false;
-    const polyMesh& mesh = dynamic_cast<const polyMesh&>(setPtr->db());
+    const auto& mesh = dynamicCast<const polyMesh>(setPtr->db());
 
     if (debug)
     {
@@ -582,7 +583,7 @@ bool Foam::expressions::fvExprDriver::updateSet
 
             word sName = name;
 
-            const T* ptr = mesh.thisDb().findObject<T>(name);
+            const T* ptr = mesh.thisDb().template cfindObject<T>(name);
 
             if (ptr)
             {
diff --git a/src/finiteVolume/expressions/base/exprDriverWriter.C b/src/finiteVolume/expressions/base/fvExprDriverWriter.C
similarity index 84%
rename from src/finiteVolume/expressions/base/exprDriverWriter.C
rename to src/finiteVolume/expressions/base/fvExprDriverWriter.C
index eb2aa82b82b..20a3b27e374 100644
--- a/src/finiteVolume/expressions/base/exprDriverWriter.C
+++ b/src/finiteVolume/expressions/base/fvExprDriverWriter.C
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2010-2018 Bernhard Gschaider
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,7 +26,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "exprDriverWriter.H"
+#include "fvExprDriverWriter.H"
 #include "fvExprDriver.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@@ -36,7 +36,7 @@ namespace Foam
 namespace expressions
 {
 
-    defineTypeName(exprDriverWriter);
+defineTypeName(fvExprDriverWriter);
 
 } // namespace expressions
 } // namespace Foam
@@ -44,7 +44,7 @@ namespace expressions
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::expressions::exprDriverWriter::exprDriverWriter
+Foam::expressions::fvExprDriverWriter::fvExprDriverWriter
 (
     const word& name,
     fvExprDriver& driver
@@ -66,14 +66,14 @@ Foam::expressions::exprDriverWriter::exprDriverWriter
 {
     if (headerOk())
     {
-        readData(readStream("exprDriverWriter", true));
+        readData(readStream("fvExprDriverWriter", true));
     }
 }
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-bool Foam::expressions::exprDriverWriter::readData(Istream& is)
+bool Foam::expressions::fvExprDriverWriter::readData(Istream& is)
 {
     dictionary dict(is);
 
@@ -85,7 +85,7 @@ bool Foam::expressions::exprDriverWriter::readData(Istream& is)
 }
 
 
-bool Foam::expressions::exprDriverWriter::writeData(Ostream& os) const
+bool Foam::expressions::fvExprDriverWriter::writeData(Ostream& os) const
 {
     // driver_.writeDict(os);
 
diff --git a/src/finiteVolume/expressions/base/exprDriverWriter.H b/src/finiteVolume/expressions/base/fvExprDriverWriter.H
similarity index 78%
rename from src/finiteVolume/expressions/base/exprDriverWriter.H
rename to src/finiteVolume/expressions/base/fvExprDriverWriter.H
index 10fe296e1f3..7553251c316 100644
--- a/src/finiteVolume/expressions/base/exprDriverWriter.H
+++ b/src/finiteVolume/expressions/base/fvExprDriverWriter.H
@@ -5,8 +5,8 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2011-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2011-2018 Bernhard Gschaider
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,18 +25,18 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::expressions::exprDriverWriter
+    Foam::expressions::fvExprDriverWriter
 
 Description
     Registered input/output for an expressions::fvExprDriver
 
 SourceFiles
-    exprDriverWriter.C
+    fvExprDriverWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef expressions_exprDriverWriter_H
-#define expressions_exprDriverWriter_H
+#ifndef expressions_fvExprDriverWriter_H
+#define expressions_fvExprDriverWriter_H
 
 #include "fvExprDriver.H"
 #include "regIOobject.H"
@@ -49,10 +49,10 @@ namespace expressions
 {
 
 /*---------------------------------------------------------------------------*\
-                      Class exprDriverWriter Declaration
+                     Class fvExprDriverWriter Declaration
 \*---------------------------------------------------------------------------*/
 
-class exprDriverWriter
+class fvExprDriverWriter
 :
     public regIOobject
 {
@@ -64,30 +64,30 @@ class exprDriverWriter
 
     // Private Member Functions
 
-        //- No null constructor
-        exprDriverWriter() = delete;
+        //- No default construct
+        fvExprDriverWriter() = delete;
 
         //- No copy construct
-        exprDriverWriter(const exprDriverWriter&) = delete;
+        fvExprDriverWriter(const fvExprDriverWriter&) = delete;
 
         //- No copy assignment
-        void operator=(const exprDriverWriter&) = delete;
+        void operator=(const fvExprDriverWriter&) = delete;
 
 
 public:
 
     //- Runtime type information
-    TypeNameNoDebug("exprDriverWriter");
+    TypeNameNoDebug("fvExprDriverWriter");
 
 
     // Constructors
 
         //- Construct for named driver
-        exprDriverWriter(const word& name, fvExprDriver& driver);
+        fvExprDriverWriter(const word& name, fvExprDriver& driver);
 
 
     //- Destructor
-    virtual ~exprDriverWriter() = default;
+    virtual ~fvExprDriverWriter() = default;
 
 
     // Member Functions
diff --git a/src/finiteVolume/expressions/patch/patchExprDriver.C b/src/finiteVolume/expressions/patch/patchExprDriver.C
index a3ae3a79013..c5587163091 100644
--- a/src/finiteVolume/expressions/patch/patchExprDriver.C
+++ b/src/finiteVolume/expressions/patch/patchExprDriver.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -69,14 +69,23 @@ addNamedToRunTimeSelectionTable
 
 namespace Foam
 {
-    static inline const fvPatch& lookupFvPatch
-    (
-        const fvMesh& mesh,
-        const word& patchName
-    )
-    {
-        return mesh.boundary()[patchName];
-    }
+
+static inline const TimeState* lookupTimeState
+(
+    const fvPatch& p
+)
+{
+    return &static_cast<const TimeState&>(p.boundaryMesh().mesh().time());
+}
+
+static inline const fvPatch& lookupFvPatch
+(
+    const fvMesh& mesh,
+    const word& patchName
+)
+{
+    return mesh.boundary()[patchName];
+}
 
 } // End namespace Foam
 
@@ -99,14 +108,6 @@ const Foam::fvPatch& Foam::expressions::patchExpr::parseDriver::getFvPatch
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::expressions::patchExpr::parseDriver::parseDriver(const fvPatch& p)
-:
-    parsing::genericRagelLemonDriver(),
-    expressions::fvExprDriver(),
-    patch_(p)
-{}
-
-
 Foam::expressions::patchExpr::parseDriver::parseDriver
 (
     const fvPatch& p,
@@ -114,7 +115,7 @@ Foam::expressions::patchExpr::parseDriver::parseDriver
 )
 :
     parsing::genericRagelLemonDriver(),
-    expressions::fvExprDriver(dict),
+    expressions::fvExprDriver(dict, lookupTimeState(p)),
     patch_(p)
 {}
 
@@ -122,11 +123,11 @@ Foam::expressions::patchExpr::parseDriver::parseDriver
 Foam::expressions::patchExpr::parseDriver::parseDriver
 (
     const fvPatch& p,
-    const parseDriver& driver_
+    const parseDriver& rhs
 )
 :
     parsing::genericRagelLemonDriver(),
-    expressions::fvExprDriver(driver_),
+    expressions::fvExprDriver(rhs),
     patch_(p)
 {}
 
diff --git a/src/finiteVolume/expressions/patch/patchExprDriver.H b/src/finiteVolume/expressions/patch/patchExprDriver.H
index 919030ba06e..55a907ffa3b 100644
--- a/src/finiteVolume/expressions/patch/patchExprDriver.H
+++ b/src/finiteVolume/expressions/patch/patchExprDriver.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -46,6 +46,9 @@ Description
         faceToPoint | Interpolate face values onto points   | 1 |
         pointToFace | Interpolate point values onto faces   | 1 |
         rand        | Random field                          | 0/1 |
+        snGrad      | Surface normal field                  | 0 |
+        internalField | Internal field next to patch        | 0 |
+        neighbourField | patch field on opposite side of coupled patch | 0 |
     \endtable
 
 Note
@@ -120,14 +123,15 @@ public:
 
     // Constructors
 
-        //- Construct for specified patch
-        explicit parseDriver(const fvPatch& p);
-
-        //- Construct for specified patch with given dictionary
-        parseDriver(const fvPatch& p, const dictionary& dict);
+        //- Construct for specified patch, with dictionary information
+        explicit parseDriver
+        (
+            const fvPatch& p,
+            const dictionary& dict = dictionary::null
+        );
 
         //- Construct for specified patch with copy of driver context
-        parseDriver(const fvPatch& p, const parseDriver& driver_);
+        parseDriver(const fvPatch& p, const parseDriver& driver);
 
         //- Construct with patchName for the given mesh
         parseDriver(const word& patchName, const fvMesh& mesh);
@@ -136,6 +140,7 @@ public:
         //- specified in dictionary
         parseDriver(const dictionary& dict, const fvMesh& mesh);
 
+
         //- Clone
         virtual autoPtr<expressions::fvExprDriver> clone() const
         {
@@ -189,9 +194,7 @@ public:
         );
 
 
-    // Field Information
-
-    // Fields
+    // General
 
         //- Set result
         template<class Type>
@@ -206,24 +209,36 @@ public:
         template<class Type>
         tmp<Field<Type>> getVariableIfAvailable(const word& fldName) const;
 
+
+    // Field Retrieval
+
+        //- Return named field
+        template<class Type>
+        tmp<Field<Type>> getField(const word& fldName);
+
         //- Retrieve field (vol field)
         template<class Type>
-        tmp<Field<Type>>
-        getVolField(const word& fldName);
+        tmp<Field<Type>> getVolField(const word& fldName);
 
         //- Retrieve field (surface field)
         template<class Type>
-        tmp<Field<Type>>
-        getSurfaceField(const word& fldName);
+        tmp<Field<Type>> getSurfaceField(const word& fldName);
 
         //- Retrieve field (point field)
         template<class Type>
-        tmp<Field<Type>>
-        getPointField(const word& fldName);
+        tmp<Field<Type>> getPointField(const word& fldName);
 
-        //- Return named field
+        //- Return internal field next to patch
         template<class Type>
-        tmp<Field<Type>> getField(const word& fldName);
+        tmp<Field<Type>> patchInternalField(const word& fldName);
+
+        //- Return patchField on the opposite patch of a coupled patch
+        template<class Type>
+        tmp<Field<Type>> patchNeighbourField(const word& fldName);
+
+        //- Return surface normal field (snGrad)
+        template<class Type>
+        tmp<Field<Type>> patchNormalField(const word& fldName);
 
 
     // Field "shape" conversions
diff --git a/src/finiteVolume/expressions/patch/patchExprDriverFields.C b/src/finiteVolume/expressions/patch/patchExprDriverFields.C
index 690a4c23761..cf537f8e68e 100644
--- a/src/finiteVolume/expressions/patch/patchExprDriverFields.C
+++ b/src/finiteVolume/expressions/patch/patchExprDriverFields.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -90,10 +90,11 @@ Foam::expressions::patchExpr::parseDriver::field_rand
     bool gaussian
 ) const
 {
-    auto tresult = tmp<scalarField>::New(this->size());
-    fill_random(tresult.ref(), seed, gaussian);
+    auto tfld = tmp<scalarField>::New(this->size());
 
-    return tresult;
+    exprDriver::fill_random(tfld.ref(), seed, gaussian);
+
+    return tfld;
 }
 
 
diff --git a/src/finiteVolume/expressions/patch/patchExprDriverTemplates.C b/src/finiteVolume/expressions/patch/patchExprDriverTemplates.C
index 1fe151c0794..1cfc35d1fe9 100644
--- a/src/finiteVolume/expressions/patch/patchExprDriverTemplates.C
+++ b/src/finiteVolume/expressions/patch/patchExprDriverTemplates.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -114,80 +114,313 @@ Foam::expressions::patchExpr::parseDriver::getField(const word& name)
         return tfield;
     }
 
+    const objectRegistry& obr = this->mesh().thisDb();
+    const label patchIndex = patch_.index();
+
+
+    // Field types
 
     typedef GeometricField<Type, fvPatchField, volMesh> vfieldType;
     typedef GeometricField<Type, fvsPatchField, surfaceMesh> sfieldType;
     typedef GeometricField<Type, pointPatchField, pointMesh> pfieldType;
 
-    const objectRegistry& obr = this->mesh().thisDb();
-
-    const vfieldType* vfield = obr.findObject<vfieldType>(name);
-    const sfieldType* sfield = obr.findObject<sfieldType>(name);
-    const pfieldType* pfield = obr.findObject<pfieldType>(name);
+    // Local, temporary storage and/or lookup values
+    bool findField = true;
+    tmp<vfieldType> vfield;
+    tmp<sfieldType> sfield;
+    tmp<pfieldType> pfield;
 
-    // Local, temporary storage
-    tmp<vfieldType> t_vfield;
-    tmp<sfieldType> t_sfield;
-    tmp<pfieldType> t_pfield;
+    if (findField)
+    {
+        vfield = exprDriver::cfindFieldObject<vfieldType>(obr, name);
+        findField = !vfield.valid();
+    }
+    if (findField)
+    {
+        sfield = exprDriver::cfindFieldObject<sfieldType>(obr, name);
+        findField = !sfield.valid();
+    }
+    if (findField)
+    {
+        pfield = exprDriver::cfindFieldObject<pfieldType>(obr, name);
+        findField = !pfield.valid();
+    }
 
-    if (searchFiles() && !vfield && !sfield && !pfield)
+    if (findField && searchFiles())
     {
         const word fldType = this->getTypeOfField(name);
 
         if (fldType == vfieldType::typeName)
         {
-            t_vfield = this->readAndRegister<vfieldType>(name, mesh());
-            vfield = t_vfield.get();
+            vfield = this->readAndRegister<vfieldType>(name, mesh());
         }
         else if (fldType == sfieldType::typeName)
         {
-            t_sfield = this->readAndRegister<sfieldType>(name, mesh());
-            sfield = t_sfield.get();
+            sfield = this->readAndRegister<sfieldType>(name, mesh());
         }
         else if (fldType == pfieldType::typeName)
         {
-            t_pfield = this->readAndRegister<pfieldType>
+            pfield = this->readAndRegister<pfieldType>
             (
                 name,
                 pointMesh::New(mesh())
             );
-            pfield = t_pfield.get();
         }
-     }
+    }
 
-    const label patchIndex = patch_.index();
 
-    if (vfield)
+    if (vfield.valid())
     {
         return tmp<Field<Type>>::New
         (
-            vfield->boundaryField()[patchIndex]
+            vfield().boundaryField()[patchIndex]
         );
     }
-
-    if (sfield)
+    if (sfield.valid())
     {
         return tmp<Field<Type>>::New
         (
-            sfield->boundaryField()[patchIndex]
+            sfield().boundaryField()[patchIndex]
         );
     }
-
-    if (pfield)
+    if (pfield.valid())
     {
-        return pfield->boundaryField()[patchIndex].patchInternalField();
+        return pfield().boundaryField()[patchIndex].patchInternalField();
     }
 
 
     FatalErrorInFunction
         << "No field '" << name << "' of type "
-        << pTraits<Type>::typeName << nl << nl
+        << pTraits<Type>::typeName << nl << nl;
+
+    FatalError
         << vfieldType::typeName << " Fields: "
-        << flatOutput(obr.sortedNames<vfieldType>()) << nl
+        << flatOutput(obr.sortedNames<vfieldType>()) << nl;
+
+    FatalError
         << sfieldType::typeName << " Fields: "
-        << flatOutput(obr.sortedNames<sfieldType>()) << nl
+        << flatOutput(obr.sortedNames<sfieldType>()) << nl;
+
+    FatalError
+        << pfieldType::typeName << " Fields: "
+        << flatOutput(obr.sortedNames<pfieldType>()) << nl;
+
+    FatalError
+        << exit(FatalError);
+
+    return tmp<Field<Type>>::New();
+}
+
+
+template<class Type>
+Foam::tmp<Foam::Field<Type>>
+Foam::expressions::patchExpr::parseDriver::patchInternalField
+(
+    const word& name
+)
+{
+    tmp<Field<Type>> tfield = getVariableIfAvailable<Type>(name);
+
+    if (tfield.valid())
+    {
+        return tfield;
+    }
+
+    const objectRegistry& obr = this->mesh().thisDb();
+    const label patchIndex = patch_.index();
+
+
+    // Field types
+
+    typedef GeometricField<Type, fvPatchField, volMesh> vfieldType;
+    typedef GeometricField<Type, pointPatchField, pointMesh> pfieldType;
+
+    // Local, temporary storage and/or lookup values
+    bool findField = true;
+    tmp<vfieldType> vfield;
+    tmp<pfieldType> pfield;
+
+    if (findField)
+    {
+        vfield = exprDriver::cfindFieldObject<vfieldType>(obr, name);
+        findField = !vfield.valid();
+    }
+    if (findField)
+    {
+        pfield = exprDriver::cfindFieldObject<pfieldType>(obr, name);
+        findField = !pfield.valid();
+    }
+
+    if (findField && searchFiles())
+    {
+        const word fldType = this->getTypeOfField(name);
+
+        if (fldType == vfieldType::typeName)
+        {
+            vfield = this->readAndRegister<vfieldType>(name, mesh());
+        }
+        else if (fldType == pfieldType::typeName)
+        {
+            pfield = this->readAndRegister<pfieldType>
+            (
+                name,
+                pointMesh::New(mesh())
+            );
+        }
+    }
+
+
+    if (vfield.valid())
+    {
+        return vfield().boundaryField()[patchIndex].patchInternalField();
+    }
+    if (pfield.valid())
+    {
+        return pfield().boundaryField()[patchIndex].patchInternalField();
+    }
+
+
+    FatalErrorInFunction
+        << "No field '" << name << "' of type "
+        << pTraits<Type>::typeName << nl << nl;
+
+    FatalError
+        << vfieldType::typeName << " Fields: "
+        << flatOutput(obr.sortedNames<vfieldType>()) << nl;
+
+    FatalError
         << pfieldType::typeName << " Fields: "
-        << flatOutput(obr.sortedNames<pfieldType>()) << nl
+        << flatOutput(obr.sortedNames<pfieldType>()) << nl;
+
+    FatalError
+        << exit(FatalError);
+
+    return tmp<Field<Type>>::New();
+}
+
+
+template<class Type>
+Foam::tmp<Foam::Field<Type>>
+Foam::expressions::patchExpr::parseDriver::patchNeighbourField
+(
+    const word& name
+)
+{
+    tmp<Field<Type>> tfield = getVariableIfAvailable<Type>(name);
+
+    if (tfield.valid())
+    {
+        return tfield;
+    }
+
+    const objectRegistry& obr = this->mesh().thisDb();
+    const label patchIndex = patch_.index();
+
+
+    // Field types
+
+    typedef GeometricField<Type, fvPatchField, volMesh> vfieldType;
+
+    // Local, temporary storage and/or lookup values
+    bool findField = true;
+    tmp<vfieldType> vfield;
+
+    if (findField)
+    {
+        vfield = exprDriver::cfindFieldObject<vfieldType>(obr, name);
+        findField = !vfield.valid();
+    }
+
+    if (findField && searchFiles())
+    {
+        const word fldType = this->getTypeOfField(name);
+
+        if (fldType == vfieldType::typeName)
+        {
+            vfield = this->readAndRegister<vfieldType>(name, mesh());
+        }
+    }
+
+
+    if (vfield.valid())
+    {
+        return vfield().boundaryField()[patchIndex].patchNeighbourField();
+    }
+
+
+    FatalErrorInFunction
+        << "No field '" << name << "' of type "
+        << pTraits<Type>::typeName << nl << nl;
+
+    FatalError
+        << vfieldType::typeName << " Fields: "
+        << flatOutput(obr.sortedNames<vfieldType>()) << nl;
+
+    FatalError
+        << exit(FatalError);
+
+    return tmp<Field<Type>>::New();
+}
+
+
+template<class Type>
+Foam::tmp<Foam::Field<Type>>
+Foam::expressions::patchExpr::parseDriver::patchNormalField
+(
+    const word& name
+)
+{
+    tmp<Field<Type>> tfield = getVariableIfAvailable<Type>(name);
+
+    if (tfield.valid())
+    {
+        return tfield;
+    }
+
+    const objectRegistry& obr = this->mesh().thisDb();
+    const label patchIndex = patch_.index();
+
+
+    // Field types
+
+    typedef GeometricField<Type, fvPatchField, volMesh> vfieldType;
+
+    // Local, temporary storage and/or lookup values
+    tmp<vfieldType> vfield;
+    bool findField = true;
+
+    if (findField)
+    {
+        vfield = exprDriver::cfindFieldObject<vfieldType>(obr, name);
+        findField = !vfield.valid();
+    }
+
+    if (findField && searchFiles())
+    {
+        const word fldType = this->getTypeOfField(name);
+
+        if (fldType == vfieldType::typeName)
+        {
+            vfield = this->readAndRegister<vfieldType>(name, mesh());
+        }
+    }
+
+
+    if (vfield.valid())
+    {
+        return vfield().boundaryField()[patchIndex].snGrad();
+    }
+
+
+    FatalErrorInFunction
+        << "No field '" << name << "' of type "
+        << pTraits<Type>::typeName << nl << nl;
+
+    FatalError
+        << vfieldType::typeName << " Fields: "
+        << flatOutput(obr.sortedNames<vfieldType>()) << nl;
+
+    FatalError
         << exit(FatalError);
 
     return tmp<Field<Type>>::New();
@@ -203,7 +436,7 @@ Foam::expressions::patchExpr::parseDriver::faceToPoint
 {
     primitivePatchInterpolation interp(patch_.patch());
 
-    return interp.pointToFaceInterpolate(field);
+    return interp.faceToPointInterpolate(field);
 }
 
 
@@ -216,7 +449,7 @@ Foam::expressions::patchExpr::parseDriver::pointToFace
 {
     primitivePatchInterpolation interp(patch_.patch());
 
-    return interp.faceToPointInterpolate(field);
+    return interp.pointToFaceInterpolate(field);
 }
 
 
diff --git a/src/finiteVolume/expressions/patch/patchExprLemonParser.h b/src/finiteVolume/expressions/patch/patchExprLemonParser.h
index d67aea0065e..c57d09d1190 100644
--- a/src/finiteVolume/expressions/patch/patchExprLemonParser.h
+++ b/src/finiteVolume/expressions/patch/patchExprLemonParser.h
@@ -27,85 +27,89 @@
 #define TOK_RAD_TO_DEG                      27
 #define TOK_ARG                             28
 #define TOK_TIME                            29
-#define TOK_SCALAR_ID                       30
-#define TOK_SSCALAR_ID                      31
-#define TOK_MIN                             32
-#define TOK_COMMA                           33
-#define TOK_MAX                             34
-#define TOK_SUM                             35
-#define TOK_AVERAGE                         36
-#define TOK_EXP                             37
-#define TOK_LOG                             38
-#define TOK_LOG10                           39
-#define TOK_SQR                             40
-#define TOK_SQRT                            41
-#define TOK_CBRT                            42
-#define TOK_SIN                             43
-#define TOK_COS                             44
-#define TOK_TAN                             45
-#define TOK_ASIN                            46
-#define TOK_ACOS                            47
-#define TOK_ATAN                            48
-#define TOK_SINH                            49
-#define TOK_COSH                            50
-#define TOK_TANH                            51
-#define TOK_POW                             52
-#define TOK_ATAN2                           53
-#define TOK_POS                             54
-#define TOK_NEG                             55
-#define TOK_POS0                            56
-#define TOK_NEG0                            57
-#define TOK_SIGN                            58
-#define TOK_FLOOR                           59
-#define TOK_CEIL                            60
-#define TOK_ROUND                           61
-#define TOK_HYPOT                           62
-#define TOK_RAND                            63
-#define TOK_VECTOR_ID                       64
-#define TOK_SVECTOR_ID                      65
-#define TOK_SPH_TENSOR_ID                   66
-#define TOK_SSPH_TENSOR_ID                  67
-#define TOK_SYM_TENSOR_ID                   68
-#define TOK_SSYM_TENSOR_ID                  69
-#define TOK_IDENTITY_TENSOR                 70
-#define TOK_TENSOR_ID                       71
-#define TOK_STENSOR_ID                      72
-#define TOK_LTRUE                           73
-#define TOK_LFALSE                          74
-#define TOK_BOOL                            75
-#define TOK_SBOOL_ID                        76
-#define TOK_FACE_AREA                       77
-#define TOK_FACE_EXPR                       78
-#define TOK_WEIGHT_AVERAGE                  79
-#define TOK_WEIGHT_SUM                      80
-#define TOK_POINT_EXPR                      81
-#define TOK_PSCALAR_ID                      82
-#define TOK_PVECTOR_ID                      83
-#define TOK_PSPH_TENSOR_ID                  84
-#define TOK_PSYM_TENSOR_ID                  85
-#define TOK_PTENSOR_ID                      86
-#define TOK_PBOOL_ID                        87
-#define TOK_POINTS                          88
-#define TOK_MAG                             89
-#define TOK_MAGSQR                          90
-#define TOK_VECTOR                          91
-#define TOK_TENSOR                          92
-#define TOK_SYM_TENSOR                      93
-#define TOK_SPH_TENSOR                      94
-#define TOK_CMPT_X                          95
-#define TOK_CMPT_Y                          96
-#define TOK_CMPT_Z                          97
-#define TOK_CMPT_XX                         98
-#define TOK_CMPT_XY                         99
-#define TOK_CMPT_XZ                        100
-#define TOK_CMPT_YX                        101
-#define TOK_CMPT_YY                        102
-#define TOK_CMPT_YZ                        103
-#define TOK_CMPT_ZX                        104
-#define TOK_CMPT_ZY                        105
-#define TOK_CMPT_ZZ                        106
-#define TOK_CMPT_II                        107
-#define TOK_TRANSPOSE                      108
-#define TOK_DIAG                           109
-#define TOK_POINT_TO_FACE                  110
-#define TOK_FACE_TO_POINT                  111
+#define TOK_DELTA_T                         30
+#define TOK_SCALAR_ID                       31
+#define TOK_SSCALAR_ID                      32
+#define TOK_INTERNAL_FIELD                  33
+#define TOK_NEIGHBOUR_FIELD                 34
+#define TOK_SN_GRAD                         35
+#define TOK_MIN                             36
+#define TOK_COMMA                           37
+#define TOK_MAX                             38
+#define TOK_SUM                             39
+#define TOK_AVERAGE                         40
+#define TOK_EXP                             41
+#define TOK_LOG                             42
+#define TOK_LOG10                           43
+#define TOK_SQR                             44
+#define TOK_SQRT                            45
+#define TOK_CBRT                            46
+#define TOK_SIN                             47
+#define TOK_COS                             48
+#define TOK_TAN                             49
+#define TOK_ASIN                            50
+#define TOK_ACOS                            51
+#define TOK_ATAN                            52
+#define TOK_SINH                            53
+#define TOK_COSH                            54
+#define TOK_TANH                            55
+#define TOK_POW                             56
+#define TOK_ATAN2                           57
+#define TOK_POS                             58
+#define TOK_NEG                             59
+#define TOK_POS0                            60
+#define TOK_NEG0                            61
+#define TOK_SIGN                            62
+#define TOK_FLOOR                           63
+#define TOK_CEIL                            64
+#define TOK_ROUND                           65
+#define TOK_HYPOT                           66
+#define TOK_RAND                            67
+#define TOK_VECTOR_ID                       68
+#define TOK_SVECTOR_ID                      69
+#define TOK_SPH_TENSOR_ID                   70
+#define TOK_SSPH_TENSOR_ID                  71
+#define TOK_SYM_TENSOR_ID                   72
+#define TOK_SSYM_TENSOR_ID                  73
+#define TOK_IDENTITY_TENSOR                 74
+#define TOK_TENSOR_ID                       75
+#define TOK_STENSOR_ID                      76
+#define TOK_LTRUE                           77
+#define TOK_LFALSE                          78
+#define TOK_BOOL                            79
+#define TOK_SBOOL_ID                        80
+#define TOK_FACE_AREA                       81
+#define TOK_FACE_EXPR                       82
+#define TOK_WEIGHT_AVERAGE                  83
+#define TOK_WEIGHT_SUM                      84
+#define TOK_POINT_EXPR                      85
+#define TOK_PSCALAR_ID                      86
+#define TOK_PVECTOR_ID                      87
+#define TOK_PSPH_TENSOR_ID                  88
+#define TOK_PSYM_TENSOR_ID                  89
+#define TOK_PTENSOR_ID                      90
+#define TOK_PBOOL_ID                        91
+#define TOK_POINTS                          92
+#define TOK_MAG                             93
+#define TOK_MAGSQR                          94
+#define TOK_VECTOR                          95
+#define TOK_TENSOR                          96
+#define TOK_SYM_TENSOR                      97
+#define TOK_SPH_TENSOR                      98
+#define TOK_CMPT_X                          99
+#define TOK_CMPT_Y                         100
+#define TOK_CMPT_Z                         101
+#define TOK_CMPT_XX                        102
+#define TOK_CMPT_XY                        103
+#define TOK_CMPT_XZ                        104
+#define TOK_CMPT_YX                        105
+#define TOK_CMPT_YY                        106
+#define TOK_CMPT_YZ                        107
+#define TOK_CMPT_ZX                        108
+#define TOK_CMPT_ZY                        109
+#define TOK_CMPT_ZZ                        110
+#define TOK_CMPT_II                        111
+#define TOK_TRANSPOSE                      112
+#define TOK_DIAG                           113
+#define TOK_POINT_TO_FACE                  114
+#define TOK_FACE_TO_POINT                  115
diff --git a/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4 b/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4
index d2e7684e9b5..fe4d6067ef0 100644
--- a/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4
+++ b/src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4
@@ -121,6 +121,7 @@ svalue (lhs) ::= DEG_TO_RAD LPAREN RPAREN . { lhs = Foam::degToRad(); }
 svalue (lhs) ::= RAD_TO_DEG LPAREN RPAREN . { lhs = Foam::radToDeg(); }
 svalue (lhs) ::= ARG LPAREN RPAREN .  { lhs = driver->argValue(); }
 svalue (lhs) ::= TIME LPAREN RPAREN . { lhs = driver->timeValue(); }
+svalue (lhs) ::= DELTA_T LPAREN RPAREN . { lhs = driver->deltaT(); }
 
 
 /* * * * * * * * * * * * * * * * * Face Fields * * * * * * * * * * * * * * * *\
@@ -147,6 +148,7 @@ evaluate ::= _target_ (a) . { driver->setResult(a); }
 rule_field_from_value(_target_, svalue)
 rule_get_field(_target_, SCALAR_ID)
 rule_get_field(_target_, SSCALAR_ID)
+rule_get_patchfields(_target_, _value_type_, SCALAR_ID)
 
 rules_standard(_target_, _value_type_, _logic_)
 rules_inplace_gUnary(_target_)
@@ -188,6 +190,7 @@ evaluate ::= _target_ (a) . { driver->setResult(a); }
 
 rule_get_field(_target_, VECTOR_ID)
 rule_get_field(_target_, SVECTOR_ID)
+rule_get_patchfields(_target_, _value_type_, VECTOR_ID)
 
 rules_standard(_target_, _value_type_, _logic_)
 rules_inplace_gUnary(_target_)
@@ -207,6 +210,7 @@ evaluate ::= _target_ (a) . { driver->setResult(a); }
 
 rule_get_field(_target_, SPH_TENSOR_ID)
 rule_get_field(_target_, SSPH_TENSOR_ID)
+rule_get_patchfields(_target_, _value_type_, SPH_TENSOR_ID)
 
 rules_standard(_target_, _value_type_, _logic_)
 rules_inplace_gUnary(_target_)
@@ -226,6 +230,7 @@ evaluate ::= _target_ (a) . { driver->setResult(a); }
 
 rule_get_field(_target_, SYM_TENSOR_ID)
 rule_get_field(_target_, SSYM_TENSOR_ID)
+rule_get_patchfields(_target_, _value_type_, SYM_TENSOR_ID)
 
 rules_standard(_target_, _value_type_, _logic_)
 rules_inplace_gUnary(_target_)
@@ -246,6 +251,7 @@ tfield (lhs) ::= IDENTITY_TENSOR . { lhs = _new_tfield(Foam::tensor::I); }
 
 rule_get_field(_target_, TENSOR_ID)
 rule_get_field(_target_, STENSOR_ID)
+rule_get_patchfields(_target_, _value_type_, TENSOR_ID)
 
 rules_standard(_target_, _value_type_, _logic_)
 rules_inplace_gUnary(_target_)
diff --git a/src/finiteVolume/expressions/patch/patchExprLemonParserMacros.m4 b/src/finiteVolume/expressions/patch/patchExprLemonParserMacros.m4
index aa183dfeb63..6e77e033c05 100644
--- a/src/finiteVolume/expressions/patch/patchExprLemonParserMacros.m4
+++ b/src/finiteVolume/expressions/patch/patchExprLemonParserMacros.m4
@@ -6,11 +6,10 @@ divert(-1)dnl
 #     \\  /    A nd           | www.openfoam.com
 #      \\/     M anipulation  |
 #------------------------------------------------------------------------------
-#     Copyright (C) 2019 OpenCFD Ltd.
+#     Copyright (C) 2019-2021 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, licensed under GNU General Public License
-#     <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Description
 #     Driver-specific m4/lemon macros for patch expressions.
@@ -31,6 +30,29 @@ divert(-1)dnl
 
 use_bool_logic()dnl     # Use boolField directly
 
+
+#------------------------------------------------------------------------------
+# Patch-specific driver rules
+
+#------------------------------------------------------------------------------
+# rule_get_patchfields(out, valType, ident)
+#
+# Description
+#     Production rules to get patch internal field
+#     and patch neighbour field
+#
+# Example
+#     rule_get_patchfields(sfield, Foam::scalar, SCALAR_ID)
+#------------------------------------------------------------------------------
+
+define([rule_get_patchfields],
+[dnl
+rule_driver_unary_named($1, INTERNAL_FIELD, $3, patchInternalField, $2)dnl
+rule_driver_unary_named($1, NEIGHBOUR_FIELD, $3, patchNeighbourField, $2)dnl
+rule_driver_unary_named($1, SN_GRAD, $3, patchNormalField, $2)dnl
+])
+
+
 #-------------------------------------------------------------------------------
 # Driver rules
 #-------------------------------------------------------------------------------
diff --git a/src/finiteVolume/expressions/patch/patchExprScanner.H b/src/finiteVolume/expressions/patch/patchExprScanner.H
index 3003b749bfe..aa991d41946 100644
--- a/src/finiteVolume/expressions/patch/patchExprScanner.H
+++ b/src/finiteVolume/expressions/patch/patchExprScanner.H
@@ -57,7 +57,7 @@ union scanToken
     Foam::scalar svalue;
     Foam::word*  name;
 
-    //- Null construct, bit-wise zero for union content
+    //- Default construct, bit-wise zero for union content
     scanToken() : ivalue(0) {}
 };
 
@@ -73,7 +73,7 @@ class scanner
         //- Wrapped lemon parser
         parser* parser_;
 
-        // Ragel code state, action
+        //- Ragel code state, action
         int cs, act;
 
 
@@ -104,7 +104,7 @@ public:
 
     // Constructors
 
-        //- Construct null, optionally setting debugging
+        //- Default construct, optionally setting debugging
         explicit scanner(bool withDebug = false)
         :
             parser_(nullptr),
diff --git a/src/finiteVolume/expressions/patch/patchExprScanner.cc b/src/finiteVolume/expressions/patch/patchExprScanner.cc
index 41a5ccb4f83..4507003dcfe 100644
--- a/src/finiteVolume/expressions/patch/patchExprScanner.cc
+++ b/src/finiteVolume/expressions/patch/patchExprScanner.cc
@@ -188,12 +188,12 @@ static int driverTokenType
 
         switch (lookBehind)
         {
-            case TOK_CSET : good = driver_.isCellSet(ident); break;
-            case TOK_FSET : good = driver_.isFaceSet(ident); break;
-            case TOK_PSET : good = driver_.isPointSet(ident); break;
-            case TOK_CZONE : good = driver_.isCellZone(ident); break;
-            case TOK_FZONE : good = driver_.isFaceZone(ident); break;
-            case TOK_PZONE : good = driver_.isPointZone(ident); break;
+            case TOK_CELL_SET : good = driver_.isCellSet(ident); break;
+            case TOK_FACE_SET : good = driver_.isFaceSet(ident); break;
+            case TOK_POINT_SET : good = driver_.isPointSet(ident); break;
+            case TOK_CELL_ZONE : good = driver_.isCellZone(ident); break;
+            case TOK_FACE_ZONE : good = driver_.isFaceZone(ident); break;
+            case TOK_POINT_ZONE : good = driver_.isPointZone(ident); break;
         }
 
         if (good)
@@ -295,7 +295,7 @@ static const int patchExpr_error = 0;
 static const int patchExpr_en_main = 11;
 
 
-#line 430 "patchExprScanner.rl"
+#line 436 "patchExprScanner.rl"
 
 
 
@@ -535,7 +535,7 @@ bool Foam::expressions::patchExpr::scanner::process
 	act = 0;
 	}
 
-#line 660 "patchExprScanner.rl"
+#line 666 "patchExprScanner.rl"
    /* ^^^ FSM initialization here ^^^ */;
 
     
@@ -590,11 +590,11 @@ tr8:
 	{te = p+1;{ EMIT_TOKEN(EQUAL); }}
 	goto st11;
 tr9:
-#line 410 "patchExprScanner.rl"
+#line 415 "patchExprScanner.rl"
 	{{p = ((te))-1;}{ EMIT_TOKEN(TENSOR); }}
 	goto st11;
 tr11:
-#line 418 "patchExprScanner.rl"
+#line 423 "patchExprScanner.rl"
 	{te = p+1;{ EMIT_TOKEN(IDENTITY_TENSOR); }}
 	goto st11;
 tr12:
@@ -645,31 +645,31 @@ tr35:
 #line 362 "patchExprScanner.rl"
 	{te = p+1;{ EMIT_TOKEN(BIT_XOR); }}
 	goto st11;
-tr52:
+tr53:
 #line 335 "patchExprScanner.rl"
 	{te = p;p--;}
 	goto st11;
-tr53:
+tr54:
 #line 340 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(NOT); }}
 	goto st11;
-tr54:
+tr55:
 #line 357 "patchExprScanner.rl"
 	{te = p+1;{ EMIT_TOKEN(NOT_EQUAL); }}
 	goto st11;
-tr55:
+tr56:
 #line 360 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(BIT_AND); }}
 	goto st11;
-tr56:
+tr57:
 #line 358 "patchExprScanner.rl"
 	{te = p+1;{ EMIT_TOKEN(LAND); }}
 	goto st11;
-tr57:
+tr58:
 #line 348 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(DOT); }}
 	goto st11;
-tr60:
+tr61:
 #line 291 "patchExprScanner.rl"
 	{te = p;p--;{
         driver_.parsePosition() = (ts-buf);
@@ -693,7 +693,7 @@ tr60:
         driver_.parsePosition() = (p-buf);
     }}
 	goto st11;
-tr62:
+tr63:
 #line 319 "patchExprScanner.rl"
 	{te = p;p--;{
         // Tokenized ".method" - dispatch '.' and "method" separately
@@ -702,23 +702,23 @@ tr62:
         driver_.parsePosition() = (p-buf);
     }}
 	goto st11;
-tr63:
+tr64:
 #line 352 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(LESS); }}
 	goto st11;
-tr64:
+tr65:
 #line 353 "patchExprScanner.rl"
 	{te = p+1;{ EMIT_TOKEN(LESS_EQ); }}
 	goto st11;
-tr65:
+tr66:
 #line 354 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(GREATER); }}
 	goto st11;
-tr66:
+tr67:
 #line 355 "patchExprScanner.rl"
 	{te = p+1;{ EMIT_TOKEN(GREATER_EQ); }}
 	goto st11;
-tr67:
+tr68:
 #line 313 "patchExprScanner.rl"
 	{te = p;p--;{
         driver_.parsePosition() = (ts-buf);
@@ -726,7 +726,7 @@ tr67:
         driver_.parsePosition() = (p-buf);
     }}
 	goto st11;
-tr69:
+tr70:
 #line 1 "NONE"
 	{	switch( act ) {
 	case 26:
@@ -805,33 +805,45 @@ tr69:
 	{{p = ((te))-1;} EMIT_TOKEN(RAND); }
 	break;
 	case 60:
-	{{p = ((te))-1;} EMIT_TOKEN(BOOL); }
+	{{p = ((te))-1;} EMIT_TOKEN(SN_GRAD); }
 	break;
 	case 61:
-	{{p = ((te))-1;} EMIT_TOKEN(VECTOR); }
+	{{p = ((te))-1;} EMIT_TOKEN(INTERNAL_FIELD); }
+	break;
+	case 62:
+	{{p = ((te))-1;} EMIT_TOKEN(NEIGHBOUR_FIELD); }
 	break;
 	case 63:
-	{{p = ((te))-1;} EMIT_TOKEN(SYM_TENSOR); }
+	{{p = ((te))-1;} EMIT_TOKEN(BOOL); }
 	break;
 	case 64:
+	{{p = ((te))-1;} EMIT_TOKEN(VECTOR); }
+	break;
+	case 66:
+	{{p = ((te))-1;} EMIT_TOKEN(SYM_TENSOR); }
+	break;
+	case 67:
 	{{p = ((te))-1;} EMIT_TOKEN(SPH_TENSOR); }
 	break;
-	case 65:
+	case 68:
 	{{p = ((te))-1;} EMIT_TOKEN(ZERO); }
 	break;
-	case 66:
+	case 69:
 	{{p = ((te))-1;} EMIT_TOKEN(LTRUE); }
 	break;
-	case 67:
+	case 70:
 	{{p = ((te))-1;} EMIT_TOKEN(LFALSE); }
 	break;
-	case 69:
+	case 72:
 	{{p = ((te))-1;} EMIT_TOKEN(ARG); }
 	break;
-	case 70:
+	case 73:
 	{{p = ((te))-1;} EMIT_TOKEN(TIME); }
 	break;
-	case 71:
+	case 74:
+	{{p = ((te))-1;} EMIT_TOKEN(DELTA_T); }
+	break;
+	case 75:
 	{{p = ((te))-1;}
         driver_.parsePosition() = (ts-buf);
         dispatch_ident(driver_, scanTok, word(ts, te-ts, false));
@@ -841,44 +853,44 @@ tr69:
 	}
 	}
 	goto st11;
-tr85:
+tr86:
 #line 384 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(ATAN); }}
 	goto st11;
-tr100:
+tr101:
 #line 380 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(COS); }}
 	goto st11;
-tr117:
+tr134:
 #line 373 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(LOG); }}
 	goto st11;
-tr124:
+tr141:
 #line 389 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(MAG); }}
 	goto st11;
-tr131:
+tr149:
 #line 393 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(NEG); }}
 	goto st11;
-tr137:
+tr166:
 #line 392 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(POS); }}
 	goto st11;
-tr156:
+tr186:
 #line 379 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(SIN); }}
 	goto st11;
-tr172:
+tr206:
 #line 376 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(SQR); }}
 	goto st11;
-tr188:
+tr222:
 #line 381 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(TAN); }}
 	goto st11;
-tr194:
-#line 410 "patchExprScanner.rl"
+tr228:
+#line 415 "patchExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(TENSOR); }}
 	goto st11;
 st11:
@@ -889,7 +901,7 @@ st11:
 case 11:
 #line 1 "NONE"
 	{ts = p;}
-#line 893 "patchExprScanner.cc"
+#line 905 "patchExprScanner.cc"
 	switch( (*p) ) {
 		case 32: goto st12;
 		case 33: goto st13;
@@ -917,17 +929,18 @@ case 11:
 		case 98: goto st41;
 		case 99: goto st44;
 		case 100: goto st49;
-		case 101: goto st56;
-		case 102: goto st58;
-		case 108: goto st62;
-		case 109: goto st66;
-		case 110: goto st72;
-		case 112: goto st75;
-		case 114: goto st78;
-		case 115: goto st86;
-		case 116: goto st114;
-		case 118: goto st126;
-		case 119: goto st131;
+		case 101: goto st59;
+		case 102: goto st61;
+		case 105: goto st65;
+		case 108: goto st77;
+		case 109: goto st81;
+		case 110: goto st87;
+		case 112: goto st101;
+		case 114: goto st104;
+		case 115: goto st112;
+		case 116: goto st144;
+		case 118: goto st156;
+		case 119: goto st161;
 		case 124: goto st10;
 	}
 	if ( (*p) < 48 ) {
@@ -953,14 +966,14 @@ case 12:
 		goto st12;
 	if ( 9 <= (*p) && (*p) <= 13 )
 		goto st12;
-	goto tr52;
+	goto tr53;
 st13:
 	if ( ++p == pe )
 		goto _test_eof13;
 case 13:
 	if ( (*p) == 61 )
-		goto tr54;
-	goto tr53;
+		goto tr55;
+	goto tr54;
 st1:
 	if ( ++p == pe )
 		goto _test_eof1;
@@ -980,8 +993,8 @@ st14:
 		goto _test_eof14;
 case 14:
 	if ( (*p) == 38 )
-		goto tr56;
-	goto tr55;
+		goto tr57;
+	goto tr56;
 st3:
 	if ( ++p == pe )
 		goto _test_eof3;
@@ -1002,14 +1015,14 @@ st15:
 case 15:
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr58;
+			goto tr59;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
 			goto st18;
 	} else
 		goto st18;
-	goto tr57;
-tr58:
+	goto tr58;
+tr59:
 #line 1 "NONE"
 	{te = p+1;}
 	goto st16;
@@ -1017,14 +1030,14 @@ st16:
 	if ( ++p == pe )
 		goto _test_eof16;
 case 16:
-#line 1021 "patchExprScanner.cc"
+#line 1034 "patchExprScanner.cc"
 	switch( (*p) ) {
 		case 69: goto st5;
 		case 101: goto st5;
 	}
 	if ( 48 <= (*p) && (*p) <= 57 )
-		goto tr58;
-	goto tr60;
+		goto tr59;
+	goto tr61;
 st5:
 	if ( ++p == pe )
 		goto _test_eof5;
@@ -1049,7 +1062,7 @@ st17:
 case 17:
 	if ( 48 <= (*p) && (*p) <= 57 )
 		goto st17;
-	goto tr60;
+	goto tr61;
 st18:
 	if ( ++p == pe )
 		goto _test_eof18;
@@ -1059,7 +1072,7 @@ case 18:
 			goto st18;
 	} else if ( (*p) >= 65 )
 		goto st18;
-	goto tr62;
+	goto tr63;
 tr27:
 #line 1 "NONE"
 	{te = p+1;}
@@ -1068,22 +1081,22 @@ st19:
 	if ( ++p == pe )
 		goto _test_eof19;
 case 19:
-#line 1072 "patchExprScanner.cc"
+#line 1085 "patchExprScanner.cc"
 	switch( (*p) ) {
-		case 46: goto tr58;
+		case 46: goto tr59;
 		case 69: goto st5;
 		case 101: goto st5;
 	}
 	if ( 48 <= (*p) && (*p) <= 57 )
 		goto tr27;
-	goto tr60;
+	goto tr61;
 st20:
 	if ( ++p == pe )
 		goto _test_eof20;
 case 20:
 	if ( (*p) == 61 )
-		goto tr64;
-	goto tr63;
+		goto tr65;
+	goto tr64;
 st7:
 	if ( ++p == pe )
 		goto _test_eof7;
@@ -1096,230 +1109,254 @@ st21:
 		goto _test_eof21;
 case 21:
 	if ( (*p) == 61 )
-		goto tr66;
-	goto tr65;
+		goto tr67;
+	goto tr66;
 st22:
 	if ( ++p == pe )
 		goto _test_eof22;
 case 22:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
-tr68:
+		goto tr69;
+	goto tr68;
+tr69:
 #line 1 "NONE"
 	{te = p+1;}
 #line 313 "patchExprScanner.rl"
-	{act = 71;}
+	{act = 75;}
 	goto st23;
-tr72:
+tr73:
 #line 1 "NONE"
 	{te = p+1;}
-#line 415 "patchExprScanner.rl"
-	{act = 65;}
+#line 420 "patchExprScanner.rl"
+	{act = 68;}
 	goto st23;
-tr79:
+tr80:
 #line 1 "NONE"
 	{te = p+1;}
 #line 383 "patchExprScanner.rl"
 	{act = 40;}
 	goto st23;
-tr80:
+tr81:
 #line 1 "NONE"
 	{te = p+1;}
-#line 419 "patchExprScanner.rl"
-	{act = 69;}
+#line 424 "patchExprScanner.rl"
+	{act = 72;}
 	goto st23;
-tr82:
+tr83:
 #line 1 "NONE"
 	{te = p+1;}
 #line 382 "patchExprScanner.rl"
 	{act = 39;}
 	goto st23;
-tr86:
+tr87:
 #line 1 "NONE"
 	{te = p+1;}
 #line 385 "patchExprScanner.rl"
 	{act = 42;}
 	goto st23;
-tr91:
+tr92:
 #line 1 "NONE"
 	{te = p+1;}
 #line 401 "patchExprScanner.rl"
 	{act = 55;}
 	goto st23;
-tr94:
+tr95:
 #line 1 "NONE"
 	{te = p+1;}
-#line 408 "patchExprScanner.rl"
-	{act = 60;}
+#line 413 "patchExprScanner.rl"
+	{act = 63;}
 	goto st23;
-tr98:
+tr99:
 #line 1 "NONE"
 	{te = p+1;}
 #line 378 "patchExprScanner.rl"
 	{act = 35;}
 	goto st23;
-tr101:
+tr102:
 #line 1 "NONE"
 	{te = p+1;}
 #line 387 "patchExprScanner.rl"
 	{act = 44;}
 	goto st23;
-tr108:
+tr110:
 #line 1 "NONE"
 	{te = p+1;}
 #line 370 "patchExprScanner.rl"
 	{act = 27;}
 	goto st23;
-tr110:
+tr113:
+#line 1 "NONE"
+	{te = p+1;}
+#line 426 "patchExprScanner.rl"
+	{act = 74;}
+	goto st23;
+tr115:
 #line 1 "NONE"
 	{te = p+1;}
 #line 372 "patchExprScanner.rl"
 	{act = 29;}
 	goto st23;
-tr114:
+tr119:
 #line 1 "NONE"
 	{te = p+1;}
-#line 417 "patchExprScanner.rl"
-	{act = 67;}
+#line 422 "patchExprScanner.rl"
+	{act = 70;}
 	goto st23;
-tr119:
+tr131:
+#line 1 "NONE"
+	{te = p+1;}
+#line 409 "patchExprScanner.rl"
+	{act = 61;}
+	goto st23;
+tr136:
 #line 1 "NONE"
 	{te = p+1;}
 #line 374 "patchExprScanner.rl"
 	{act = 31;}
 	goto st23;
-tr123:
+tr140:
 #line 1 "NONE"
 	{te = p+1;}
 #line 400 "patchExprScanner.rl"
 	{act = 54;}
 	goto st23;
-tr127:
+tr144:
 #line 1 "NONE"
 	{te = p+1;}
 #line 390 "patchExprScanner.rl"
 	{act = 47;}
 	goto st23;
-tr128:
+tr145:
 #line 1 "NONE"
 	{te = p+1;}
 #line 399 "patchExprScanner.rl"
 	{act = 53;}
 	goto st23;
-tr132:
+tr150:
 #line 1 "NONE"
 	{te = p+1;}
 #line 395 "patchExprScanner.rl"
 	{act = 51;}
 	goto st23;
-tr133:
+tr161:
+#line 1 "NONE"
+	{te = p+1;}
+#line 410 "patchExprScanner.rl"
+	{act = 62;}
+	goto st23;
+tr162:
 #line 1 "NONE"
 	{te = p+1;}
 #line 369 "patchExprScanner.rl"
 	{act = 26;}
 	goto st23;
-tr136:
+tr165:
 #line 1 "NONE"
 	{te = p+1;}
 #line 375 "patchExprScanner.rl"
 	{act = 32;}
 	goto st23;
-tr138:
+tr167:
 #line 1 "NONE"
 	{te = p+1;}
 #line 394 "patchExprScanner.rl"
 	{act = 50;}
 	goto st23;
-tr146:
+tr175:
 #line 1 "NONE"
 	{te = p+1;}
 #line 371 "patchExprScanner.rl"
 	{act = 28;}
 	goto st23;
-tr147:
+tr176:
 #line 1 "NONE"
 	{te = p+1;}
 #line 405 "patchExprScanner.rl"
 	{act = 59;}
 	goto st23;
-tr155:
+tr185:
 #line 1 "NONE"
 	{te = p+1;}
 #line 396 "patchExprScanner.rl"
 	{act = 52;}
 	goto st23;
-tr157:
+tr187:
 #line 1 "NONE"
 	{te = p+1;}
 #line 386 "patchExprScanner.rl"
 	{act = 43;}
 	goto st23;
-tr170:
+tr191:
 #line 1 "NONE"
 	{te = p+1;}
-#line 412 "patchExprScanner.rl"
-	{act = 64;}
+#line 408 "patchExprScanner.rl"
+	{act = 60;}
 	goto st23;
-tr173:
+tr204:
+#line 1 "NONE"
+	{te = p+1;}
+#line 417 "patchExprScanner.rl"
+	{act = 67;}
+	goto st23;
+tr207:
 #line 1 "NONE"
 	{te = p+1;}
 #line 377 "patchExprScanner.rl"
 	{act = 34;}
 	goto st23;
-tr174:
+tr208:
 #line 1 "NONE"
 	{te = p+1;}
 #line 402 "patchExprScanner.rl"
 	{act = 56;}
 	goto st23;
-tr182:
+tr216:
 #line 1 "NONE"
 	{te = p+1;}
-#line 411 "patchExprScanner.rl"
-	{act = 63;}
+#line 416 "patchExprScanner.rl"
+	{act = 66;}
 	goto st23;
-tr189:
+tr223:
 #line 1 "NONE"
 	{te = p+1;}
 #line 388 "patchExprScanner.rl"
 	{act = 45;}
 	goto st23;
-tr197:
+tr231:
 #line 1 "NONE"
 	{te = p+1;}
-#line 420 "patchExprScanner.rl"
-	{act = 70;}
+#line 425 "patchExprScanner.rl"
+	{act = 73;}
 	goto st23;
-tr199:
+tr233:
 #line 1 "NONE"
 	{te = p+1;}
-#line 416 "patchExprScanner.rl"
-	{act = 66;}
+#line 421 "patchExprScanner.rl"
+	{act = 69;}
 	goto st23;
-tr204:
+tr238:
 #line 1 "NONE"
 	{te = p+1;}
-#line 409 "patchExprScanner.rl"
-	{act = 61;}
+#line 414 "patchExprScanner.rl"
+	{act = 64;}
 	goto st23;
-tr217:
+tr251:
 #line 1 "NONE"
 	{te = p+1;}
 #line 403 "patchExprScanner.rl"
 	{act = 57;}
 	goto st23;
-tr219:
+tr253:
 #line 1 "NONE"
 	{te = p+1;}
 #line 404 "patchExprScanner.rl"
@@ -1329,81 +1366,81 @@ st23:
 	if ( ++p == pe )
 		goto _test_eof23;
 case 23:
-#line 1333 "patchExprScanner.cc"
+#line 1370 "patchExprScanner.cc"
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr69;
+		goto tr69;
+	goto tr70;
 st24:
 	if ( ++p == pe )
 		goto _test_eof24;
 case 24:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 101: goto st25;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st25:
 	if ( ++p == pe )
 		goto _test_eof25;
 case 25:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 114: goto st26;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st26:
 	if ( ++p == pe )
 		goto _test_eof26;
 case 26:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 111: goto tr72;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 111: goto tr73;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st27:
 	if ( ++p == pe )
 		goto _test_eof27;
 case 27:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 99: goto st28;
 		case 114: goto st30;
 		case 115: goto st31;
@@ -1412,2153 +1449,2696 @@ case 27:
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st28:
 	if ( ++p == pe )
 		goto _test_eof28;
 case 28:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 111: goto st29;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st29:
 	if ( ++p == pe )
 		goto _test_eof29;
 case 29:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 115: goto tr79;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 115: goto tr80;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st30:
 	if ( ++p == pe )
 		goto _test_eof30;
 case 30:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 103: goto tr80;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 103: goto tr81;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st31:
 	if ( ++p == pe )
 		goto _test_eof31;
 case 31:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 105: goto st32;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st32:
 	if ( ++p == pe )
 		goto _test_eof32;
 case 32:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 110: goto tr82;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 110: goto tr83;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st33:
 	if ( ++p == pe )
 		goto _test_eof33;
 case 33:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 97: goto st34;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 98 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st34:
 	if ( ++p == pe )
 		goto _test_eof34;
 case 34:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 110: goto st35;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st35:
 	if ( ++p == pe )
 		goto _test_eof35;
 case 35:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 50: goto tr86;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 50: goto tr87;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr85;
+		goto tr69;
+	goto tr86;
 st36:
 	if ( ++p == pe )
 		goto _test_eof36;
 case 36:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 101: goto st37;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st37:
 	if ( ++p == pe )
 		goto _test_eof37;
 case 37:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 114: goto st38;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st38:
 	if ( ++p == pe )
 		goto _test_eof38;
 case 38:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 97: goto st39;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 98 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st39:
 	if ( ++p == pe )
 		goto _test_eof39;
 case 39:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 103: goto st40;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st40:
 	if ( ++p == pe )
 		goto _test_eof40;
 case 40:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto tr91;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto tr92;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st41:
 	if ( ++p == pe )
 		goto _test_eof41;
 case 41:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 111: goto st42;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st42:
 	if ( ++p == pe )
 		goto _test_eof42;
 case 42:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 111: goto st43;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st43:
 	if ( ++p == pe )
 		goto _test_eof43;
 case 43:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 108: goto tr94;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 108: goto tr95;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st44:
 	if ( ++p == pe )
 		goto _test_eof44;
 case 44:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 98: goto st45;
 		case 111: goto st47;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st45:
 	if ( ++p == pe )
 		goto _test_eof45;
 case 45:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 114: goto st46;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st46:
 	if ( ++p == pe )
 		goto _test_eof46;
 case 46:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 116: goto tr98;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 116: goto tr99;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st47:
 	if ( ++p == pe )
 		goto _test_eof47;
 case 47:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 115: goto st48;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st48:
 	if ( ++p == pe )
 		goto _test_eof48;
 case 48:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 104: goto tr101;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 104: goto tr102;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr100;
+		goto tr69;
+	goto tr101;
 st49:
 	if ( ++p == pe )
 		goto _test_eof49;
 case 49:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 101: goto st50;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st50:
 	if ( ++p == pe )
 		goto _test_eof50;
 case 50:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 103: goto st51;
+		case 108: goto st56;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st51:
 	if ( ++p == pe )
 		goto _test_eof51;
 case 51:
 	switch( (*p) ) {
-		case 46: goto tr68;
+		case 46: goto tr69;
 		case 84: goto st52;
-		case 95: goto tr68;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st52:
 	if ( ++p == pe )
 		goto _test_eof52;
 case 52:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 111: goto st53;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st53:
 	if ( ++p == pe )
 		goto _test_eof53;
 case 53:
 	switch( (*p) ) {
-		case 46: goto tr68;
+		case 46: goto tr69;
 		case 82: goto st54;
-		case 95: goto tr68;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st54:
 	if ( ++p == pe )
 		goto _test_eof54;
 case 54:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 97: goto st55;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 98 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st55:
 	if ( ++p == pe )
 		goto _test_eof55;
 case 55:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 100: goto tr108;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 100: goto tr110;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st56:
 	if ( ++p == pe )
 		goto _test_eof56;
 case 56:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 120: goto st57;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 116: goto st57;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st57:
 	if ( ++p == pe )
 		goto _test_eof57;
 case 57:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 112: goto tr110;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 97: goto st58;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 98 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st58:
 	if ( ++p == pe )
 		goto _test_eof58;
 case 58:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 97: goto st59;
+		case 46: goto tr69;
+		case 84: goto tr113;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st59:
 	if ( ++p == pe )
 		goto _test_eof59;
 case 59:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 108: goto st60;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 120: goto st60;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st60:
 	if ( ++p == pe )
 		goto _test_eof60;
 case 60:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 115: goto st61;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 112: goto tr115;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st61:
 	if ( ++p == pe )
 		goto _test_eof61;
 case 61:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto tr114;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 97: goto st62;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 98 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st62:
 	if ( ++p == pe )
 		goto _test_eof62;
 case 62:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 111: goto st63;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 108: goto st63;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st63:
 	if ( ++p == pe )
 		goto _test_eof63;
 case 63:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 103: goto st64;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 115: goto st64;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st64:
 	if ( ++p == pe )
 		goto _test_eof64;
 case 64:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 49: goto st65;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto tr119;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr117;
+		goto tr69;
+	goto tr68;
 st65:
 	if ( ++p == pe )
 		goto _test_eof65;
 case 65:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 48: goto tr119;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 110: goto st66;
 	}
 	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr68;
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st66:
 	if ( ++p == pe )
 		goto _test_eof66;
 case 66:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 97: goto st67;
-		case 105: goto st71;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 116: goto st67;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st67:
 	if ( ++p == pe )
 		goto _test_eof67;
 case 67:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 103: goto st68;
-		case 120: goto tr123;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto st68;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st68:
 	if ( ++p == pe )
 		goto _test_eof68;
 case 68:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 83: goto st69;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto st69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr124;
+		goto tr69;
+	goto tr68;
 st69:
 	if ( ++p == pe )
 		goto _test_eof69;
 case 69:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 113: goto st70;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 110: goto st70;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st70:
 	if ( ++p == pe )
 		goto _test_eof70;
 case 70:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 114: goto tr127;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 97: goto st71;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 98 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st71:
 	if ( ++p == pe )
 		goto _test_eof71;
 case 71:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 110: goto tr128;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 108: goto st72;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st72:
 	if ( ++p == pe )
 		goto _test_eof72;
 case 72:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto st73;
+		case 46: goto tr69;
+		case 70: goto st73;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st73:
 	if ( ++p == pe )
 		goto _test_eof73;
 case 73:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 103: goto st74;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 105: goto st74;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st74:
 	if ( ++p == pe )
 		goto _test_eof74;
 case 74:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 48: goto tr132;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto st75;
 	}
 	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr68;
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr131;
+		goto tr69;
+	goto tr68;
 st75:
 	if ( ++p == pe )
 		goto _test_eof75;
 case 75:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 105: goto tr133;
-		case 111: goto st76;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 108: goto st76;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st76:
 	if ( ++p == pe )
 		goto _test_eof76;
 case 76:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 115: goto st77;
-		case 119: goto tr136;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 100: goto tr131;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st77:
 	if ( ++p == pe )
 		goto _test_eof77;
 case 77:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 48: goto tr138;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 111: goto st78;
 	}
 	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
-			goto tr68;
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr137;
+		goto tr69;
+	goto tr68;
 st78:
 	if ( ++p == pe )
 		goto _test_eof78;
 case 78:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 97: goto st79;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 103: goto st79;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st79:
 	if ( ++p == pe )
 		goto _test_eof79;
 case 79:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 100: goto st80;
-		case 110: goto st85;
+		case 46: goto tr69;
+		case 49: goto st80;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr134;
 st80:
 	if ( ++p == pe )
 		goto _test_eof80;
 case 80:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 84: goto st81;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 48: goto tr136;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+		if ( 49 <= (*p) && (*p) <= 57 )
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st81:
 	if ( ++p == pe )
 		goto _test_eof81;
 case 81:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 111: goto st82;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 97: goto st82;
+		case 105: goto st86;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 98 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st82:
 	if ( ++p == pe )
 		goto _test_eof82;
 case 82:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 68: goto st83;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 103: goto st83;
+		case 120: goto tr140;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st83:
 	if ( ++p == pe )
 		goto _test_eof83;
 case 83:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto st84;
+		case 46: goto tr69;
+		case 83: goto st84;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr141;
 st84:
 	if ( ++p == pe )
 		goto _test_eof84;
 case 84:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 103: goto tr146;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 113: goto st85;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st85:
 	if ( ++p == pe )
 		goto _test_eof85;
 case 85:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 100: goto tr147;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto tr144;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st86:
 	if ( ++p == pe )
 		goto _test_eof86;
 case 86:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 105: goto st87;
-		case 112: goto st90;
-		case 113: goto st103;
-		case 117: goto st105;
-		case 121: goto st106;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 110: goto tr145;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st87:
 	if ( ++p == pe )
 		goto _test_eof87;
 case 87:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 103: goto st88;
-		case 110: goto st89;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto st88;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st88:
 	if ( ++p == pe )
 		goto _test_eof88;
 case 88:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 110: goto tr155;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 103: goto st89;
+		case 105: goto st90;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st89:
 	if ( ++p == pe )
 		goto _test_eof89;
 case 89:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 104: goto tr157;
+		case 46: goto tr69;
+		case 48: goto tr150;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+		if ( 49 <= (*p) && (*p) <= 57 )
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr156;
+		goto tr69;
+	goto tr149;
 st90:
 	if ( ++p == pe )
 		goto _test_eof90;
 case 90:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 104: goto st91;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 103: goto st91;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st91:
 	if ( ++p == pe )
 		goto _test_eof91;
 case 91:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto st92;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 104: goto st92;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st92:
 	if ( ++p == pe )
 		goto _test_eof92;
 case 92:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 114: goto st93;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 98: goto st93;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st93:
 	if ( ++p == pe )
 		goto _test_eof93;
 case 93:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 105: goto st94;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 111: goto st94;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st94:
 	if ( ++p == pe )
 		goto _test_eof94;
 case 94:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 99: goto st95;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 117: goto st95;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st95:
 	if ( ++p == pe )
 		goto _test_eof95;
 case 95:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 97: goto st96;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto st96;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st96:
 	if ( ++p == pe )
 		goto _test_eof96;
 case 96:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 108: goto st97;
+		case 46: goto tr69;
+		case 70: goto st97;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st97:
 	if ( ++p == pe )
 		goto _test_eof97;
 case 97:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 84: goto st98;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 105: goto st98;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st98:
 	if ( ++p == pe )
 		goto _test_eof98;
 case 98:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 101: goto st99;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st99:
 	if ( ++p == pe )
 		goto _test_eof99;
 case 99:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 110: goto st100;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 108: goto st100;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st100:
 	if ( ++p == pe )
 		goto _test_eof100;
 case 100:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 115: goto st101;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 100: goto tr161;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st101:
 	if ( ++p == pe )
 		goto _test_eof101;
 case 101:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 105: goto tr162;
 		case 111: goto st102;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st102:
 	if ( ++p == pe )
 		goto _test_eof102;
 case 102:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 114: goto tr170;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 115: goto st103;
+		case 119: goto tr165;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st103:
 	if ( ++p == pe )
 		goto _test_eof103;
 case 103:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 114: goto st104;
+		case 46: goto tr69;
+		case 48: goto tr167;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+		if ( 49 <= (*p) && (*p) <= 57 )
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr166;
 st104:
 	if ( ++p == pe )
 		goto _test_eof104;
 case 104:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 116: goto tr173;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 97: goto st105;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 98 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr172;
+		goto tr69;
+	goto tr68;
 st105:
 	if ( ++p == pe )
 		goto _test_eof105;
 case 105:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 109: goto tr174;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 100: goto st106;
+		case 110: goto st111;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st106:
 	if ( ++p == pe )
 		goto _test_eof106;
 case 106:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 109: goto st107;
+		case 46: goto tr69;
+		case 84: goto st107;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st107:
 	if ( ++p == pe )
 		goto _test_eof107;
 case 107:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 109: goto st108;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 111: goto st108;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st108:
 	if ( ++p == pe )
 		goto _test_eof108;
 case 108:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 84: goto st109;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 68: goto st109;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st109:
 	if ( ++p == pe )
 		goto _test_eof109;
 case 109:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
 		case 101: goto st110;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st110:
 	if ( ++p == pe )
 		goto _test_eof110;
 case 110:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 110: goto st111;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 103: goto tr175;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st111:
 	if ( ++p == pe )
 		goto _test_eof111;
 case 111:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 115: goto st112;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 100: goto tr176;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st112:
 	if ( ++p == pe )
 		goto _test_eof112;
 case 112:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 111: goto st113;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 105: goto st113;
+		case 110: goto st116;
+		case 112: goto st120;
+		case 113: goto st133;
+		case 117: goto st135;
+		case 121: goto st136;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st113:
 	if ( ++p == pe )
 		goto _test_eof113;
 case 113:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 114: goto tr182;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 103: goto st114;
+		case 110: goto st115;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st114:
 	if ( ++p == pe )
 		goto _test_eof114;
 case 114:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 97: goto st115;
-		case 101: goto st117;
-		case 105: goto st122;
-		case 114: goto st124;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 110: goto tr185;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st115:
 	if ( ++p == pe )
 		goto _test_eof115;
 case 115:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 110: goto st116;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 104: goto tr187;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr186;
 st116:
 	if ( ++p == pe )
 		goto _test_eof116;
 case 116:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 104: goto tr189;
+		case 46: goto tr69;
+		case 71: goto st117;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr188;
+		goto tr69;
+	goto tr68;
 st117:
 	if ( ++p == pe )
 		goto _test_eof117;
 case 117:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 110: goto st118;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto st118;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st118:
 	if ( ++p == pe )
 		goto _test_eof118;
 case 118:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 115: goto st119;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 97: goto st119;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 98 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st119:
 	if ( ++p == pe )
 		goto _test_eof119;
 case 119:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 111: goto st120;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 100: goto tr191;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st120:
 	if ( ++p == pe )
 		goto _test_eof120;
 case 120:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 114: goto tr193;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 104: goto st121;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
-tr193:
-#line 1 "NONE"
-	{te = p+1;}
-	goto st121;
+		goto tr69;
+	goto tr68;
 st121:
 	if ( ++p == pe )
 		goto _test_eof121;
 case 121:
-#line 3119 "patchExprScanner.cc"
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 58: goto st8;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto st122;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr194;
-st8:
-	if ( ++p == pe )
-		goto _test_eof8;
-case 8:
-	if ( (*p) == 58 )
-		goto st9;
-	goto tr9;
-st9:
-	if ( ++p == pe )
-		goto _test_eof9;
-case 9:
-	if ( (*p) == 73 )
-		goto tr11;
-	goto tr9;
+		goto tr69;
+	goto tr68;
 st122:
 	if ( ++p == pe )
 		goto _test_eof122;
 case 122:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 109: goto st123;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto st123;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st123:
 	if ( ++p == pe )
 		goto _test_eof123;
 case 123:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto tr197;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 105: goto st124;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st124:
 	if ( ++p == pe )
 		goto _test_eof124;
 case 124:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 117: goto st125;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 99: goto st125;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st125:
 	if ( ++p == pe )
 		goto _test_eof125;
 case 125:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto tr199;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 97: goto st126;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 98 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st126:
 	if ( ++p == pe )
 		goto _test_eof126;
 case 126:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto st127;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 108: goto st127;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st127:
 	if ( ++p == pe )
 		goto _test_eof127;
 case 127:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 99: goto st128;
+		case 46: goto tr69;
+		case 84: goto st128;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st128:
 	if ( ++p == pe )
 		goto _test_eof128;
 case 128:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 116: goto st129;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto st129;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st129:
 	if ( ++p == pe )
 		goto _test_eof129;
 case 129:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 111: goto st130;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 110: goto st130;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st130:
 	if ( ++p == pe )
 		goto _test_eof130;
 case 130:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 114: goto tr204;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 115: goto st131;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st131:
 	if ( ++p == pe )
 		goto _test_eof131;
 case 131:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto st132;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 111: goto st132;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st132:
 	if ( ++p == pe )
 		goto _test_eof132;
 case 132:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 105: goto st133;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto tr204;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st133:
 	if ( ++p == pe )
 		goto _test_eof133;
 case 133:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 103: goto st134;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto st134;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st134:
 	if ( ++p == pe )
 		goto _test_eof134;
 case 134:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 104: goto st135;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 116: goto tr207;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr206;
 st135:
 	if ( ++p == pe )
 		goto _test_eof135;
 case 135:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 116: goto st136;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 109: goto tr208;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st136:
 	if ( ++p == pe )
 		goto _test_eof136;
 case 136:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 65: goto st137;
-		case 83: goto st143;
-		case 95: goto tr68;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 109: goto st137;
 	}
-	if ( (*p) < 66 ) {
+	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st137:
 	if ( ++p == pe )
 		goto _test_eof137;
 case 137:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 118: goto st138;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 109: goto st138;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st138:
 	if ( ++p == pe )
 		goto _test_eof138;
 case 138:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto st139;
+		case 46: goto tr69;
+		case 84: goto st139;
+		case 95: goto tr69;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st139:
 	if ( ++p == pe )
 		goto _test_eof139;
 case 139:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 114: goto st140;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto st140;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st140:
 	if ( ++p == pe )
 		goto _test_eof140;
 case 140:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 97: goto st141;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 110: goto st141;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
-			goto tr68;
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st141:
 	if ( ++p == pe )
 		goto _test_eof141;
 case 141:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 103: goto st142;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 115: goto st142;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st142:
 	if ( ++p == pe )
 		goto _test_eof142;
 case 142:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 101: goto tr217;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 111: goto st143;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st143:
 	if ( ++p == pe )
 		goto _test_eof143;
 case 143:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 117: goto st144;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto tr216;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
 st144:
 	if ( ++p == pe )
 		goto _test_eof144;
 case 144:
 	switch( (*p) ) {
-		case 46: goto tr68;
-		case 95: goto tr68;
-		case 109: goto tr219;
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 97: goto st145;
+		case 101: goto st147;
+		case 105: goto st152;
+		case 114: goto st154;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 98 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st145:
+	if ( ++p == pe )
+		goto _test_eof145;
+case 145:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 110: goto st146;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st146:
+	if ( ++p == pe )
+		goto _test_eof146;
+case 146:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 104: goto tr223;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr222;
+st147:
+	if ( ++p == pe )
+		goto _test_eof147;
+case 147:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 110: goto st148;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st148:
+	if ( ++p == pe )
+		goto _test_eof148;
+case 148:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 115: goto st149;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st149:
+	if ( ++p == pe )
+		goto _test_eof149;
+case 149:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 111: goto st150;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st150:
+	if ( ++p == pe )
+		goto _test_eof150;
+case 150:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto tr227;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+tr227:
+#line 1 "NONE"
+	{te = p+1;}
+	goto st151;
+st151:
+	if ( ++p == pe )
+		goto _test_eof151;
+case 151:
+#line 3699 "patchExprScanner.cc"
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 58: goto st8;
+		case 95: goto tr69;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr228;
+st8:
+	if ( ++p == pe )
+		goto _test_eof8;
+case 8:
+	if ( (*p) == 58 )
+		goto st9;
+	goto tr9;
+st9:
+	if ( ++p == pe )
+		goto _test_eof9;
+case 9:
+	if ( (*p) == 73 )
+		goto tr11;
+	goto tr9;
+st152:
+	if ( ++p == pe )
+		goto _test_eof152;
+case 152:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 109: goto st153;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st153:
+	if ( ++p == pe )
+		goto _test_eof153;
+case 153:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto tr231;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st154:
+	if ( ++p == pe )
+		goto _test_eof154;
+case 154:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 117: goto st155;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st155:
+	if ( ++p == pe )
+		goto _test_eof155;
+case 155:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto tr233;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st156:
+	if ( ++p == pe )
+		goto _test_eof156;
+case 156:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto st157;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st157:
+	if ( ++p == pe )
+		goto _test_eof157;
+case 157:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 99: goto st158;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st158:
+	if ( ++p == pe )
+		goto _test_eof158;
+case 158:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 116: goto st159;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st159:
+	if ( ++p == pe )
+		goto _test_eof159;
+case 159:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 111: goto st160;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st160:
+	if ( ++p == pe )
+		goto _test_eof160;
+case 160:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto tr238;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st161:
+	if ( ++p == pe )
+		goto _test_eof161;
+case 161:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto st162;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st162:
+	if ( ++p == pe )
+		goto _test_eof162;
+case 162:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 105: goto st163;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st163:
+	if ( ++p == pe )
+		goto _test_eof163;
+case 163:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 103: goto st164;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st164:
+	if ( ++p == pe )
+		goto _test_eof164;
+case 164:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 104: goto st165;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
-			goto tr68;
+			goto tr69;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
-			goto tr68;
+			goto tr69;
 	} else
-		goto tr68;
-	goto tr67;
+		goto tr69;
+	goto tr68;
+st165:
+	if ( ++p == pe )
+		goto _test_eof165;
+case 165:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 116: goto st166;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st166:
+	if ( ++p == pe )
+		goto _test_eof166;
+case 166:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 65: goto st167;
+		case 83: goto st173;
+		case 95: goto tr69;
+	}
+	if ( (*p) < 66 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st167:
+	if ( ++p == pe )
+		goto _test_eof167;
+case 167:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 118: goto st168;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st168:
+	if ( ++p == pe )
+		goto _test_eof168;
+case 168:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto st169;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st169:
+	if ( ++p == pe )
+		goto _test_eof169;
+case 169:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 114: goto st170;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st170:
+	if ( ++p == pe )
+		goto _test_eof170;
+case 170:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 97: goto st171;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 98 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st171:
+	if ( ++p == pe )
+		goto _test_eof171;
+case 171:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 103: goto st172;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st172:
+	if ( ++p == pe )
+		goto _test_eof172;
+case 172:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 101: goto tr251;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st173:
+	if ( ++p == pe )
+		goto _test_eof173;
+case 173:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 117: goto st174;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
+st174:
+	if ( ++p == pe )
+		goto _test_eof174;
+case 174:
+	switch( (*p) ) {
+		case 46: goto tr69;
+		case 95: goto tr69;
+		case 109: goto tr253;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr69;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr69;
+	} else
+		goto tr69;
+	goto tr68;
 st10:
 	if ( ++p == pe )
 		goto _test_eof10;
@@ -3685,8 +4265,6 @@ case 10:
 	_test_eof119: cs = 119; goto _test_eof; 
 	_test_eof120: cs = 120; goto _test_eof; 
 	_test_eof121: cs = 121; goto _test_eof; 
-	_test_eof8: cs = 8; goto _test_eof; 
-	_test_eof9: cs = 9; goto _test_eof; 
 	_test_eof122: cs = 122; goto _test_eof; 
 	_test_eof123: cs = 123; goto _test_eof; 
 	_test_eof124: cs = 124; goto _test_eof; 
@@ -3710,156 +4288,218 @@ case 10:
 	_test_eof142: cs = 142; goto _test_eof; 
 	_test_eof143: cs = 143; goto _test_eof; 
 	_test_eof144: cs = 144; goto _test_eof; 
+	_test_eof145: cs = 145; goto _test_eof; 
+	_test_eof146: cs = 146; goto _test_eof; 
+	_test_eof147: cs = 147; goto _test_eof; 
+	_test_eof148: cs = 148; goto _test_eof; 
+	_test_eof149: cs = 149; goto _test_eof; 
+	_test_eof150: cs = 150; goto _test_eof; 
+	_test_eof151: cs = 151; goto _test_eof; 
+	_test_eof8: cs = 8; goto _test_eof; 
+	_test_eof9: cs = 9; goto _test_eof; 
+	_test_eof152: cs = 152; goto _test_eof; 
+	_test_eof153: cs = 153; goto _test_eof; 
+	_test_eof154: cs = 154; goto _test_eof; 
+	_test_eof155: cs = 155; goto _test_eof; 
+	_test_eof156: cs = 156; goto _test_eof; 
+	_test_eof157: cs = 157; goto _test_eof; 
+	_test_eof158: cs = 158; goto _test_eof; 
+	_test_eof159: cs = 159; goto _test_eof; 
+	_test_eof160: cs = 160; goto _test_eof; 
+	_test_eof161: cs = 161; goto _test_eof; 
+	_test_eof162: cs = 162; goto _test_eof; 
+	_test_eof163: cs = 163; goto _test_eof; 
+	_test_eof164: cs = 164; goto _test_eof; 
+	_test_eof165: cs = 165; goto _test_eof; 
+	_test_eof166: cs = 166; goto _test_eof; 
+	_test_eof167: cs = 167; goto _test_eof; 
+	_test_eof168: cs = 168; goto _test_eof; 
+	_test_eof169: cs = 169; goto _test_eof; 
+	_test_eof170: cs = 170; goto _test_eof; 
+	_test_eof171: cs = 171; goto _test_eof; 
+	_test_eof172: cs = 172; goto _test_eof; 
+	_test_eof173: cs = 173; goto _test_eof; 
+	_test_eof174: cs = 174; goto _test_eof; 
 	_test_eof10: cs = 10; goto _test_eof; 
 
 	_test_eof: {}
 	if ( p == eof )
 	{
 	switch ( cs ) {
-	case 12: goto tr52;
-	case 13: goto tr53;
-	case 14: goto tr55;
-	case 15: goto tr57;
-	case 16: goto tr60;
+	case 12: goto tr53;
+	case 13: goto tr54;
+	case 14: goto tr56;
+	case 15: goto tr58;
+	case 16: goto tr61;
 	case 5: goto tr5;
 	case 6: goto tr5;
-	case 17: goto tr60;
-	case 18: goto tr62;
-	case 19: goto tr60;
-	case 20: goto tr63;
-	case 21: goto tr65;
-	case 22: goto tr67;
-	case 23: goto tr69;
-	case 24: goto tr67;
-	case 25: goto tr67;
-	case 26: goto tr67;
-	case 27: goto tr67;
-	case 28: goto tr67;
-	case 29: goto tr67;
-	case 30: goto tr67;
-	case 31: goto tr67;
-	case 32: goto tr67;
-	case 33: goto tr67;
-	case 34: goto tr67;
-	case 35: goto tr85;
-	case 36: goto tr67;
-	case 37: goto tr67;
-	case 38: goto tr67;
-	case 39: goto tr67;
-	case 40: goto tr67;
-	case 41: goto tr67;
-	case 42: goto tr67;
-	case 43: goto tr67;
-	case 44: goto tr67;
-	case 45: goto tr67;
-	case 46: goto tr67;
-	case 47: goto tr67;
-	case 48: goto tr100;
-	case 49: goto tr67;
-	case 50: goto tr67;
-	case 51: goto tr67;
-	case 52: goto tr67;
-	case 53: goto tr67;
-	case 54: goto tr67;
-	case 55: goto tr67;
-	case 56: goto tr67;
-	case 57: goto tr67;
-	case 58: goto tr67;
-	case 59: goto tr67;
-	case 60: goto tr67;
-	case 61: goto tr67;
-	case 62: goto tr67;
-	case 63: goto tr67;
-	case 64: goto tr117;
-	case 65: goto tr67;
-	case 66: goto tr67;
-	case 67: goto tr67;
-	case 68: goto tr124;
-	case 69: goto tr67;
-	case 70: goto tr67;
-	case 71: goto tr67;
-	case 72: goto tr67;
-	case 73: goto tr67;
-	case 74: goto tr131;
-	case 75: goto tr67;
-	case 76: goto tr67;
-	case 77: goto tr137;
-	case 78: goto tr67;
-	case 79: goto tr67;
-	case 80: goto tr67;
-	case 81: goto tr67;
-	case 82: goto tr67;
-	case 83: goto tr67;
-	case 84: goto tr67;
-	case 85: goto tr67;
-	case 86: goto tr67;
-	case 87: goto tr67;
-	case 88: goto tr67;
-	case 89: goto tr156;
-	case 90: goto tr67;
-	case 91: goto tr67;
-	case 92: goto tr67;
-	case 93: goto tr67;
-	case 94: goto tr67;
-	case 95: goto tr67;
-	case 96: goto tr67;
-	case 97: goto tr67;
-	case 98: goto tr67;
-	case 99: goto tr67;
-	case 100: goto tr67;
-	case 101: goto tr67;
-	case 102: goto tr67;
-	case 103: goto tr67;
-	case 104: goto tr172;
-	case 105: goto tr67;
-	case 106: goto tr67;
-	case 107: goto tr67;
-	case 108: goto tr67;
-	case 109: goto tr67;
-	case 110: goto tr67;
-	case 111: goto tr67;
-	case 112: goto tr67;
-	case 113: goto tr67;
-	case 114: goto tr67;
-	case 115: goto tr67;
-	case 116: goto tr188;
-	case 117: goto tr67;
-	case 118: goto tr67;
-	case 119: goto tr67;
-	case 120: goto tr67;
-	case 121: goto tr194;
+	case 17: goto tr61;
+	case 18: goto tr63;
+	case 19: goto tr61;
+	case 20: goto tr64;
+	case 21: goto tr66;
+	case 22: goto tr68;
+	case 23: goto tr70;
+	case 24: goto tr68;
+	case 25: goto tr68;
+	case 26: goto tr68;
+	case 27: goto tr68;
+	case 28: goto tr68;
+	case 29: goto tr68;
+	case 30: goto tr68;
+	case 31: goto tr68;
+	case 32: goto tr68;
+	case 33: goto tr68;
+	case 34: goto tr68;
+	case 35: goto tr86;
+	case 36: goto tr68;
+	case 37: goto tr68;
+	case 38: goto tr68;
+	case 39: goto tr68;
+	case 40: goto tr68;
+	case 41: goto tr68;
+	case 42: goto tr68;
+	case 43: goto tr68;
+	case 44: goto tr68;
+	case 45: goto tr68;
+	case 46: goto tr68;
+	case 47: goto tr68;
+	case 48: goto tr101;
+	case 49: goto tr68;
+	case 50: goto tr68;
+	case 51: goto tr68;
+	case 52: goto tr68;
+	case 53: goto tr68;
+	case 54: goto tr68;
+	case 55: goto tr68;
+	case 56: goto tr68;
+	case 57: goto tr68;
+	case 58: goto tr68;
+	case 59: goto tr68;
+	case 60: goto tr68;
+	case 61: goto tr68;
+	case 62: goto tr68;
+	case 63: goto tr68;
+	case 64: goto tr68;
+	case 65: goto tr68;
+	case 66: goto tr68;
+	case 67: goto tr68;
+	case 68: goto tr68;
+	case 69: goto tr68;
+	case 70: goto tr68;
+	case 71: goto tr68;
+	case 72: goto tr68;
+	case 73: goto tr68;
+	case 74: goto tr68;
+	case 75: goto tr68;
+	case 76: goto tr68;
+	case 77: goto tr68;
+	case 78: goto tr68;
+	case 79: goto tr134;
+	case 80: goto tr68;
+	case 81: goto tr68;
+	case 82: goto tr68;
+	case 83: goto tr141;
+	case 84: goto tr68;
+	case 85: goto tr68;
+	case 86: goto tr68;
+	case 87: goto tr68;
+	case 88: goto tr68;
+	case 89: goto tr149;
+	case 90: goto tr68;
+	case 91: goto tr68;
+	case 92: goto tr68;
+	case 93: goto tr68;
+	case 94: goto tr68;
+	case 95: goto tr68;
+	case 96: goto tr68;
+	case 97: goto tr68;
+	case 98: goto tr68;
+	case 99: goto tr68;
+	case 100: goto tr68;
+	case 101: goto tr68;
+	case 102: goto tr68;
+	case 103: goto tr166;
+	case 104: goto tr68;
+	case 105: goto tr68;
+	case 106: goto tr68;
+	case 107: goto tr68;
+	case 108: goto tr68;
+	case 109: goto tr68;
+	case 110: goto tr68;
+	case 111: goto tr68;
+	case 112: goto tr68;
+	case 113: goto tr68;
+	case 114: goto tr68;
+	case 115: goto tr186;
+	case 116: goto tr68;
+	case 117: goto tr68;
+	case 118: goto tr68;
+	case 119: goto tr68;
+	case 120: goto tr68;
+	case 121: goto tr68;
+	case 122: goto tr68;
+	case 123: goto tr68;
+	case 124: goto tr68;
+	case 125: goto tr68;
+	case 126: goto tr68;
+	case 127: goto tr68;
+	case 128: goto tr68;
+	case 129: goto tr68;
+	case 130: goto tr68;
+	case 131: goto tr68;
+	case 132: goto tr68;
+	case 133: goto tr68;
+	case 134: goto tr206;
+	case 135: goto tr68;
+	case 136: goto tr68;
+	case 137: goto tr68;
+	case 138: goto tr68;
+	case 139: goto tr68;
+	case 140: goto tr68;
+	case 141: goto tr68;
+	case 142: goto tr68;
+	case 143: goto tr68;
+	case 144: goto tr68;
+	case 145: goto tr68;
+	case 146: goto tr222;
+	case 147: goto tr68;
+	case 148: goto tr68;
+	case 149: goto tr68;
+	case 150: goto tr68;
+	case 151: goto tr228;
 	case 8: goto tr9;
 	case 9: goto tr9;
-	case 122: goto tr67;
-	case 123: goto tr67;
-	case 124: goto tr67;
-	case 125: goto tr67;
-	case 126: goto tr67;
-	case 127: goto tr67;
-	case 128: goto tr67;
-	case 129: goto tr67;
-	case 130: goto tr67;
-	case 131: goto tr67;
-	case 132: goto tr67;
-	case 133: goto tr67;
-	case 134: goto tr67;
-	case 135: goto tr67;
-	case 136: goto tr67;
-	case 137: goto tr67;
-	case 138: goto tr67;
-	case 139: goto tr67;
-	case 140: goto tr67;
-	case 141: goto tr67;
-	case 142: goto tr67;
-	case 143: goto tr67;
-	case 144: goto tr67;
+	case 152: goto tr68;
+	case 153: goto tr68;
+	case 154: goto tr68;
+	case 155: goto tr68;
+	case 156: goto tr68;
+	case 157: goto tr68;
+	case 158: goto tr68;
+	case 159: goto tr68;
+	case 160: goto tr68;
+	case 161: goto tr68;
+	case 162: goto tr68;
+	case 163: goto tr68;
+	case 164: goto tr68;
+	case 165: goto tr68;
+	case 166: goto tr68;
+	case 167: goto tr68;
+	case 168: goto tr68;
+	case 169: goto tr68;
+	case 170: goto tr68;
+	case 171: goto tr68;
+	case 172: goto tr68;
+	case 173: goto tr68;
+	case 174: goto tr68;
 	}
 	}
 
 	_out: {}
 	}
 
-#line 662 "patchExprScanner.rl"
+#line 668 "patchExprScanner.rl"
    /* ^^^ FSM execution here ^^^ */;
 
     if (0 == cs)
diff --git a/src/finiteVolume/expressions/patch/patchExprScanner.rl b/src/finiteVolume/expressions/patch/patchExprScanner.rl
index 209fd02d4b2..a56f7d3edb6 100644
--- a/src/finiteVolume/expressions/patch/patchExprScanner.rl
+++ b/src/finiteVolume/expressions/patch/patchExprScanner.rl
@@ -186,12 +186,12 @@ static int driverTokenType
 
         switch (lookBehind)
         {
-            case TOK_CSET : good = driver_.isCellSet(ident); break;
-            case TOK_FSET : good = driver_.isFaceSet(ident); break;
-            case TOK_PSET : good = driver_.isPointSet(ident); break;
-            case TOK_CZONE : good = driver_.isCellZone(ident); break;
-            case TOK_FZONE : good = driver_.isFaceZone(ident); break;
-            case TOK_PZONE : good = driver_.isPointZone(ident); break;
+            case TOK_CELL_SET : good = driver_.isCellSet(ident); break;
+            case TOK_FACE_SET : good = driver_.isFaceSet(ident); break;
+            case TOK_POINT_SET : good = driver_.isPointSet(ident); break;
+            case TOK_CELL_ZONE : good = driver_.isCellZone(ident); break;
+            case TOK_FACE_ZONE : good = driver_.isFaceZone(ident); break;
+            case TOK_POINT_ZONE : good = driver_.isPointZone(ident); break;
         }
 
         if (good)
@@ -336,7 +336,7 @@ static int driverTokenType
 
     number => emit_number;
 
-    ## operators
+    ## Operators
     '!'  =>{ EMIT_TOKEN(NOT); };
     '%'  =>{ EMIT_TOKEN(PERCENT); };
     '('  =>{ EMIT_TOKEN(LPAREN); };
@@ -404,6 +404,11 @@ static int driverTokenType
     "weightSum" =>{ EMIT_TOKEN(WEIGHT_SUM); };
     "rand"      =>{ EMIT_TOKEN(RAND); };
 
+    ## Patch-specific
+    "snGrad"    =>{ EMIT_TOKEN(SN_GRAD); };
+    "internalField" =>{ EMIT_TOKEN(INTERNAL_FIELD); };
+    "neighbourField" =>{ EMIT_TOKEN(NEIGHBOUR_FIELD); };
+
     ## Types
     "bool"      =>{ EMIT_TOKEN(BOOL); };
     "vector"    =>{ EMIT_TOKEN(VECTOR); };
@@ -418,6 +423,7 @@ static int driverTokenType
     "tensor::I" =>{ EMIT_TOKEN(IDENTITY_TENSOR); };
     "arg"       =>{ EMIT_TOKEN(ARG); };
     "time"      =>{ EMIT_TOKEN(TIME); };
+    "deltaT"    =>{ EMIT_TOKEN(DELTA_T); };
 
     ## Identifier (field, etc - error if unknown)
     ## Handle 'bare' names and single/double quoted ones
diff --git a/src/finiteVolume/expressions/volume/volumeExprDriver.C b/src/finiteVolume/expressions/volume/volumeExprDriver.C
index 6a417e5eddc..9010fc03d48 100644
--- a/src/finiteVolume/expressions/volume/volumeExprDriver.C
+++ b/src/finiteVolume/expressions/volume/volumeExprDriver.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -81,24 +81,24 @@ addNamedToRunTimeSelectionTable
 } // End namespace Foam
 
 
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
 
-Foam::expressions::volumeExpr::parseDriver::parseDriver
+namespace Foam
+{
+
+static inline const TimeState* lookupTimeState
 (
-    const fvMesh& mesh,
-    bool cacheReadFields
+    const polyMesh& m
 )
-:
-    parsing::genericRagelLemonDriver(),
-    expressions::fvExprDriver(cacheReadFields),
-    mesh_(mesh),
-    resultType_(),
-    isLogical_(false),
-    fieldGeoType_(NO_DATA),
-    resultDimension_()
-{}
+{
+    return &static_cast<const TimeState&>(m.time());
+}
+
+} // End namespace Foam
 
 
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
 Foam::expressions::volumeExpr::parseDriver::parseDriver
 (
     const fvMesh& mesh,
@@ -106,7 +106,7 @@ Foam::expressions::volumeExpr::parseDriver::parseDriver
 )
 :
     parsing::genericRagelLemonDriver(),
-    expressions::fvExprDriver(dict),
+    expressions::fvExprDriver(dict, lookupTimeState(mesh)),
     mesh_(mesh),
     resultType_(),
     isLogical_(false),
@@ -128,7 +128,9 @@ Foam::expressions::volumeExpr::parseDriver::parseDriver
     isLogical_(false),
     fieldGeoType_(NO_DATA),
     resultDimension_()
-{}
+{
+    resetTimeReference(mesh_.time());  // Extra safety
+}
 
 
 Foam::expressions::volumeExpr::parseDriver::parseDriver
@@ -150,7 +152,7 @@ Foam::expressions::volumeExpr::parseDriver::parseDriver
 )
 :
     parsing::genericRagelLemonDriver(),
-    expressions::fvExprDriver(dict),
+    expressions::fvExprDriver(dict, lookupTimeState(mesh)),
     mesh_(mesh),
     resultType_(),
     isLogical_(false),
diff --git a/src/finiteVolume/expressions/volume/volumeExprDriver.H b/src/finiteVolume/expressions/volume/volumeExprDriver.H
index 3d738c27de4..5237a38853a 100644
--- a/src/finiteVolume/expressions/volume/volumeExprDriver.H
+++ b/src/finiteVolume/expressions/volume/volumeExprDriver.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -177,16 +177,13 @@ public:
 
     // Constructors
 
-        //- Construct for specified mesh
+        //- Construct for specified mesh, with dictionary information
         explicit parseDriver
         (
             const fvMesh& mesh,
-            bool cacheReadFields = false
+            const dictionary& dict = dictionary::null
         );
 
-        //- Construct for specified mesh with given dictionary
-        parseDriver(const fvMesh& mesh, const dictionary& dict);
-
         //- Construct for specified mesh with copy of driver context
         parseDriver(const fvMesh& mesh, const parseDriver& driver);
 
@@ -196,6 +193,7 @@ public:
         //- Construct with patchName and region specified in dictionary
         parseDriver(const dictionary& dict, const fvMesh& mesh);
 
+
         //- Clone
         virtual autoPtr<expressions::fvExprDriver> clone() const
         {
diff --git a/src/finiteVolume/expressions/volume/volumeExprDriverFields.C b/src/finiteVolume/expressions/volume/volumeExprDriverFields.C
index efc3457e091..caff1eb1d08 100644
--- a/src/finiteVolume/expressions/volume/volumeExprDriverFields.C
+++ b/src/finiteVolume/expressions/volume/volumeExprDriverFields.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -266,17 +266,11 @@ Foam::expressions::volumeExpr::parseDriver::field_rand
     bool gaussian
 ) const
 {
-    auto tresult = volScalarField::New
-    (
-        "rand",
-        mesh(),
-        dimless
-    );
-    auto& fld = tresult.ref().primitiveFieldRef();
+    auto tfld = volScalarField::New("rand", mesh(), dimless);
 
-    fill_random(fld, seed, gaussian);
+    exprDriver::fill_random(tfld.ref().primitiveFieldRef(), seed, gaussian);
 
-    return tresult;
+    return tfld;
 }
 
 
diff --git a/src/finiteVolume/expressions/volume/volumeExprDriverTemplates.C b/src/finiteVolume/expressions/volume/volumeExprDriverTemplates.C
index 3ffdb5b0b15..d16a946d358 100644
--- a/src/finiteVolume/expressions/volume/volumeExprDriverTemplates.C
+++ b/src/finiteVolume/expressions/volume/volumeExprDriverTemplates.C
@@ -245,7 +245,9 @@ Foam::expressions::volumeExpr::parseDriver::newVolField
     const Type& val
 ) const
 {
-    return GeometricField<Type,fvPatchField,volMesh>::New
+    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
+
+    return fieldType::New
     (
         word("constant.") + word(pTraits<Type>::typeName),
         mesh(),
@@ -261,7 +263,9 @@ Foam::expressions::volumeExpr::parseDriver::newSurfaceField
     const Type& val
 ) const
 {
-    return GeometricField<Type,fvsPatchField,surfaceMesh>::New
+    typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType;
+
+    return fieldType::New
     (
         word("constant.") + word(pTraits<Type>::typeName),
         mesh(),
@@ -277,7 +281,9 @@ Foam::expressions::volumeExpr::parseDriver::newPointField
     const Type& val
 ) const
 {
-    return GeometricField<Type,pointPatchField,pointMesh>::New
+    typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
+
+    return fieldType::New
     (
         word("constant.") + word(pTraits<Type>::typeName),
         pointMesh::New(mesh()),
diff --git a/src/finiteVolume/expressions/volume/volumeExprLemonParser.h b/src/finiteVolume/expressions/volume/volumeExprLemonParser.h
index f658b6fe3ca..b24aa9a4371 100644
--- a/src/finiteVolume/expressions/volume/volumeExprLemonParser.h
+++ b/src/finiteVolume/expressions/volume/volumeExprLemonParser.h
@@ -27,94 +27,95 @@
 #define TOK_RAD_TO_DEG                      27
 #define TOK_ARG                             28
 #define TOK_TIME                            29
-#define TOK_SCALAR_ID                       30
-#define TOK_MIN                             31
-#define TOK_COMMA                           32
-#define TOK_MAX                             33
-#define TOK_SUM                             34
-#define TOK_AVERAGE                         35
-#define TOK_EXP                             36
-#define TOK_LOG                             37
-#define TOK_LOG10                           38
-#define TOK_SQR                             39
-#define TOK_SQRT                            40
-#define TOK_CBRT                            41
-#define TOK_SIN                             42
-#define TOK_COS                             43
-#define TOK_TAN                             44
-#define TOK_ASIN                            45
-#define TOK_ACOS                            46
-#define TOK_ATAN                            47
-#define TOK_SINH                            48
-#define TOK_COSH                            49
-#define TOK_TANH                            50
-#define TOK_POW                             51
-#define TOK_ATAN2                           52
-#define TOK_POS                             53
-#define TOK_NEG                             54
-#define TOK_POS0                            55
-#define TOK_NEG0                            56
-#define TOK_SIGN                            57
-#define TOK_FLOOR                           58
-#define TOK_CEIL                            59
-#define TOK_ROUND                           60
-#define TOK_HYPOT                           61
-#define TOK_RAND                            62
-#define TOK_VECTOR_ID                       63
-#define TOK_SPH_TENSOR_ID                   64
-#define TOK_SYM_TENSOR_ID                   65
-#define TOK_IDENTITY_TENSOR                 66
-#define TOK_TENSOR_ID                       67
-#define TOK_LTRUE                           68
-#define TOK_LFALSE                          69
-#define TOK_BOOL                            70
-#define TOK_CSET                            71
-#define TOK_IDENTIFIER                      72
-#define TOK_CZONE                           73
-#define TOK_CELL_VOLUME                     74
-#define TOK_WEIGHT_AVERAGE                  75
-#define TOK_WEIGHT_SUM                      76
-#define TOK_FACE_EXPR                       77
-#define TOK_SSCALAR_ID                      78
-#define TOK_SVECTOR_ID                      79
-#define TOK_SSPH_TENSOR_ID                  80
-#define TOK_SSYM_TENSOR_ID                  81
-#define TOK_STENSOR_ID                      82
-#define TOK_FSET                            83
-#define TOK_FZONE                           84
-#define TOK_FACE_AREA                       85
-#define TOK_FACE_CENTRE                     86
-#define TOK_POINT_EXPR                      87
-#define TOK_PSCALAR_ID                      88
-#define TOK_PVECTOR_ID                      89
-#define TOK_PSPH_TENSOR_ID                  90
-#define TOK_PSYM_TENSOR_ID                  91
-#define TOK_PTENSOR_ID                      92
-#define TOK_PSET                            93
-#define TOK_PZONE                           94
-#define TOK_POINTS                          95
-#define TOK_MAG                             96
-#define TOK_MAGSQR                          97
-#define TOK_VECTOR                          98
-#define TOK_TENSOR                          99
-#define TOK_SYM_TENSOR                     100
-#define TOK_SPH_TENSOR                     101
-#define TOK_CMPT_X                         102
-#define TOK_CMPT_Y                         103
-#define TOK_CMPT_Z                         104
-#define TOK_CMPT_XX                        105
-#define TOK_CMPT_XY                        106
-#define TOK_CMPT_XZ                        107
-#define TOK_CMPT_YX                        108
-#define TOK_CMPT_YY                        109
-#define TOK_CMPT_YZ                        110
-#define TOK_CMPT_ZX                        111
-#define TOK_CMPT_ZY                        112
-#define TOK_CMPT_ZZ                        113
-#define TOK_CMPT_II                        114
-#define TOK_TRANSPOSE                      115
-#define TOK_DIAG                           116
-#define TOK_POINT_TO_CELL                  117
-#define TOK_RECONSTRUCT                    118
-#define TOK_CELL_TO_FACE                   119
-#define TOK_CELL_TO_POINT                  120
+#define TOK_DELTA_T                         30
+#define TOK_SCALAR_ID                       31
+#define TOK_MIN                             32
+#define TOK_COMMA                           33
+#define TOK_MAX                             34
+#define TOK_SUM                             35
+#define TOK_AVERAGE                         36
+#define TOK_EXP                             37
+#define TOK_LOG                             38
+#define TOK_LOG10                           39
+#define TOK_SQR                             40
+#define TOK_SQRT                            41
+#define TOK_CBRT                            42
+#define TOK_SIN                             43
+#define TOK_COS                             44
+#define TOK_TAN                             45
+#define TOK_ASIN                            46
+#define TOK_ACOS                            47
+#define TOK_ATAN                            48
+#define TOK_SINH                            49
+#define TOK_COSH                            50
+#define TOK_TANH                            51
+#define TOK_POW                             52
+#define TOK_ATAN2                           53
+#define TOK_POS                             54
+#define TOK_NEG                             55
+#define TOK_POS0                            56
+#define TOK_NEG0                            57
+#define TOK_SIGN                            58
+#define TOK_FLOOR                           59
+#define TOK_CEIL                            60
+#define TOK_ROUND                           61
+#define TOK_HYPOT                           62
+#define TOK_RAND                            63
+#define TOK_VECTOR_ID                       64
+#define TOK_SPH_TENSOR_ID                   65
+#define TOK_SYM_TENSOR_ID                   66
+#define TOK_IDENTITY_TENSOR                 67
+#define TOK_TENSOR_ID                       68
+#define TOK_LTRUE                           69
+#define TOK_LFALSE                          70
+#define TOK_BOOL                            71
+#define TOK_CELL_SET                        72
+#define TOK_IDENTIFIER                      73
+#define TOK_CELL_ZONE                       74
+#define TOK_CELL_VOLUME                     75
+#define TOK_WEIGHT_AVERAGE                  76
+#define TOK_WEIGHT_SUM                      77
+#define TOK_FACE_EXPR                       78
+#define TOK_SSCALAR_ID                      79
+#define TOK_SVECTOR_ID                      80
+#define TOK_SSPH_TENSOR_ID                  81
+#define TOK_SSYM_TENSOR_ID                  82
+#define TOK_STENSOR_ID                      83
+#define TOK_FACE_SET                        84
+#define TOK_FACE_ZONE                       85
+#define TOK_FACE_AREA                       86
+#define TOK_FACE_CENTRE                     87
+#define TOK_POINT_EXPR                      88
+#define TOK_PSCALAR_ID                      89
+#define TOK_PVECTOR_ID                      90
+#define TOK_PSPH_TENSOR_ID                  91
+#define TOK_PSYM_TENSOR_ID                  92
+#define TOK_PTENSOR_ID                      93
+#define TOK_POINT_SET                       94
+#define TOK_POINT_ZONE                      95
+#define TOK_POINTS                          96
+#define TOK_MAG                             97
+#define TOK_MAGSQR                          98
+#define TOK_VECTOR                          99
+#define TOK_TENSOR                         100
+#define TOK_SYM_TENSOR                     101
+#define TOK_SPH_TENSOR                     102
+#define TOK_CMPT_X                         103
+#define TOK_CMPT_Y                         104
+#define TOK_CMPT_Z                         105
+#define TOK_CMPT_XX                        106
+#define TOK_CMPT_XY                        107
+#define TOK_CMPT_XZ                        108
+#define TOK_CMPT_YX                        109
+#define TOK_CMPT_YY                        110
+#define TOK_CMPT_YZ                        111
+#define TOK_CMPT_ZX                        112
+#define TOK_CMPT_ZY                        113
+#define TOK_CMPT_ZZ                        114
+#define TOK_CMPT_II                        115
+#define TOK_TRANSPOSE                      116
+#define TOK_DIAG                           117
+#define TOK_POINT_TO_CELL                  118
+#define TOK_RECONSTRUCT                    119
+#define TOK_CELL_TO_FACE                   120
+#define TOK_CELL_TO_POINT                  121
diff --git a/src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4 b/src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4
index 23cda840092..4d17ebd4cb6 100644
--- a/src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4
+++ b/src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4
@@ -161,6 +161,7 @@ svalue (lhs) ::= DEG_TO_RAD LPAREN RPAREN . { lhs = Foam::degToRad(); }
 svalue (lhs) ::= RAD_TO_DEG LPAREN RPAREN . { lhs = Foam::radToDeg(); }
 svalue (lhs) ::= ARG LPAREN RPAREN .  { lhs = driver->argValue(); }
 svalue (lhs) ::= TIME LPAREN RPAREN . { lhs = driver->timeValue(); }
+svalue (lhs) ::= DELTA_T LPAREN RPAREN . { lhs = driver->deltaT(); }
 
 
 /* * * * * * * * * * * * * * * * Volume Fields * * * * * * * * * * * * * * * *\
diff --git a/src/finiteVolume/expressions/volume/volumeExprLemonParserMacros.m4 b/src/finiteVolume/expressions/volume/volumeExprLemonParserMacros.m4
index a0df5c6314c..7cde6ab1e74 100644
--- a/src/finiteVolume/expressions/volume/volumeExprLemonParserMacros.m4
+++ b/src/finiteVolume/expressions/volume/volumeExprLemonParserMacros.m4
@@ -6,11 +6,10 @@ divert(-1)dnl
 #     \\  /    A nd           | www.openfoam.com
 #      \\/     M anipulation  |
 #------------------------------------------------------------------------------
-#     Copyright (C) 2019 OpenCFD Ltd.
+#     Copyright (C) 2019-2021 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, licensed under GNU General Public License
-#     <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Description
 #     Driver-specific m4/lemon macros for volume expressions.
@@ -35,8 +34,8 @@ divert(-1)dnl
 
 define([rules_driver_volume_functions],
 [dnl
-rule_driver_select(_logic_, CSET, field_cellSet)dnl
-rule_driver_select(_logic_, CZONE, field_cellZone)dnl
+rule_driver_select(_logic_, CELL_SET, field_cellSet)dnl
+rule_driver_select(_logic_, CELL_ZONE, field_cellZone)dnl
 dnl
 rule_driver_nullary(_scalar_, CELL_VOLUME, field_cellVolume)dnl
 rule_driver_nullary(_vector_, POS, field_cellCentre)dnl CELL_CENTRE
@@ -57,8 +56,8 @@ dnl
 
 define([rules_driver_surface_functions],
 [dnl
-rule_driver_select(_logic_, FSET, field_faceSet)dnl
-rule_driver_select(_logic_, FZONE, field_faceZone)dnl
+rule_driver_select(_logic_, FACE_SET, field_faceSet)dnl
+rule_driver_select(_logic_, FACE_ZONE, field_faceZone)dnl
 dnl
 rule_driver_nullary(_scalar_, FACE_AREA, field_faceArea)dnl
 rule_driver_nullary(_vector_, FACE_CENTRE, field_faceCentre)dnl
@@ -80,8 +79,8 @@ dnl
 
 define([rules_driver_point_functions],
 [dnl
-rule_driver_select(_logic_, PSET, field_pointSet)dnl
-rule_driver_select(_logic_, PZONE, field_pointZone)dnl
+rule_driver_select(_logic_, POINT_SET, field_pointSet)dnl
+rule_driver_select(_logic_, POINT_ZONE, field_pointZone)dnl
 dnl
 rule_driver_nullary(_vector_, POINTS, field_pointField)dnl
 dnl
diff --git a/src/finiteVolume/expressions/volume/volumeExprScanner.H b/src/finiteVolume/expressions/volume/volumeExprScanner.H
index b432a602fbe..0e8e5795739 100644
--- a/src/finiteVolume/expressions/volume/volumeExprScanner.H
+++ b/src/finiteVolume/expressions/volume/volumeExprScanner.H
@@ -57,7 +57,7 @@ union scanToken
     Foam::scalar svalue;
     Foam::word*  name;
 
-    //- Null construct, bit-wise zero for union content
+    //- Default construct, bit-wise zero for union content
     scanToken() : ivalue(0) {}
 };
 
@@ -73,7 +73,7 @@ class scanner
         //- Wrapped lemon parser
         parser* parser_;
 
-        // Ragel code state, action
+        //- Ragel code state, action
         int cs, act;
 
 
@@ -104,7 +104,7 @@ public:
 
     // Constructors
 
-        //- Construct null, optionally setting debugging
+        //- Default construct, optionally setting debugging
         explicit scanner(bool withDebug = false)
         :
             parser_(nullptr),
diff --git a/src/finiteVolume/expressions/volume/volumeExprScanner.cc b/src/finiteVolume/expressions/volume/volumeExprScanner.cc
index 14922aa88d4..104e0ca6631 100644
--- a/src/finiteVolume/expressions/volume/volumeExprScanner.cc
+++ b/src/finiteVolume/expressions/volume/volumeExprScanner.cc
@@ -63,12 +63,12 @@ namespace Foam
 // Special handling for these known (stashed) look-back types
 static const Enum<int> lookBehindTokenEnums
 ({
-    TOKEN_PAIR("cellSet", CSET),
-    TOKEN_PAIR("faceSet", FSET),
-    TOKEN_PAIR("pointSet", PSET),
-    TOKEN_PAIR("cellZone", CZONE),
-    TOKEN_PAIR("faceZone", FZONE),
-    TOKEN_PAIR("pointZone", PZONE),
+    TOKEN_PAIR("cellSet", CELL_SET),
+    TOKEN_PAIR("faceSet", FACE_SET),
+    TOKEN_PAIR("pointSet", POINT_SET),
+    TOKEN_PAIR("cellZone", CELL_ZONE),
+    TOKEN_PAIR("faceZone", FACE_ZONE),
+    TOKEN_PAIR("pointZone", POINT_ZONE),
 });
 
 #define HAS_LOOKBEHIND_TOKENS
@@ -203,12 +203,12 @@ static int driverTokenType
 
         switch (lookBehind)
         {
-            case TOK_CSET : good = driver_.isCellSet(ident); break;
-            case TOK_FSET : good = driver_.isFaceSet(ident); break;
-            case TOK_PSET : good = driver_.isPointSet(ident); break;
-            case TOK_CZONE : good = driver_.isCellZone(ident); break;
-            case TOK_FZONE : good = driver_.isFaceZone(ident); break;
-            case TOK_PZONE : good = driver_.isPointZone(ident); break;
+            case TOK_CELL_SET : good = driver_.isCellSet(ident); break;
+            case TOK_FACE_SET : good = driver_.isFaceSet(ident); break;
+            case TOK_POINT_SET : good = driver_.isPointSet(ident); break;
+            case TOK_CELL_ZONE : good = driver_.isCellZone(ident); break;
+            case TOK_FACE_ZONE : good = driver_.isFaceZone(ident); break;
+            case TOK_POINT_ZONE : good = driver_.isPointZone(ident); break;
         }
 
         if (good)
@@ -324,7 +324,7 @@ static const int volumeExpr_error = 0;
 static const int volumeExpr_en_main = 11;
 
 
-#line 459 "volumeExprScanner.rl"
+#line 460 "volumeExprScanner.rl"
 
 
 
@@ -564,7 +564,7 @@ bool Foam::expressions::volumeExpr::scanner::process
 	act = 0;
 	}
 
-#line 689 "volumeExprScanner.rl"
+#line 690 "volumeExprScanner.rl"
    /* ^^^ FSM initialization here ^^^ */;
 
     
@@ -861,6 +861,9 @@ tr69:
 	{{p = ((te))-1;} EMIT_TOKEN(TIME); }
 	break;
 	case 71:
+	{{p = ((te))-1;} EMIT_TOKEN(DELTA_T); }
+	break;
+	case 72:
 	{{p = ((te))-1;}
         driver_.parsePosition() = (ts-buf);
         dispatch_ident(driver_, scanTok, word(ts, te-ts, false));
@@ -878,35 +881,35 @@ tr100:
 #line 409 "volumeExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(COS); }}
 	goto st11;
-tr117:
+tr121:
 #line 402 "volumeExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(LOG); }}
 	goto st11;
-tr124:
+tr128:
 #line 418 "volumeExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(MAG); }}
 	goto st11;
-tr131:
+tr135:
 #line 422 "volumeExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(NEG); }}
 	goto st11;
-tr137:
+tr141:
 #line 421 "volumeExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(POS); }}
 	goto st11;
-tr156:
+tr160:
 #line 408 "volumeExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(SIN); }}
 	goto st11;
-tr172:
+tr176:
 #line 405 "volumeExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(SQR); }}
 	goto st11;
-tr188:
+tr192:
 #line 410 "volumeExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(TAN); }}
 	goto st11;
-tr194:
+tr198:
 #line 439 "volumeExprScanner.rl"
 	{te = p;p--;{ EMIT_TOKEN(TENSOR); }}
 	goto st11;
@@ -918,7 +921,7 @@ st11:
 case 11:
 #line 1 "NONE"
 	{ts = p;}
-#line 922 "volumeExprScanner.cc"
+#line 925 "volumeExprScanner.cc"
 	switch( (*p) ) {
 		case 32: goto st12;
 		case 33: goto st13;
@@ -946,17 +949,17 @@ case 11:
 		case 98: goto st41;
 		case 99: goto st44;
 		case 100: goto st49;
-		case 101: goto st56;
-		case 102: goto st58;
-		case 108: goto st62;
-		case 109: goto st66;
-		case 110: goto st72;
-		case 112: goto st75;
-		case 114: goto st78;
-		case 115: goto st86;
-		case 116: goto st114;
-		case 118: goto st126;
-		case 119: goto st131;
+		case 101: goto st59;
+		case 102: goto st61;
+		case 108: goto st65;
+		case 109: goto st69;
+		case 110: goto st75;
+		case 112: goto st78;
+		case 114: goto st81;
+		case 115: goto st89;
+		case 116: goto st117;
+		case 118: goto st129;
+		case 119: goto st134;
 		case 124: goto st10;
 	}
 	if ( (*p) < 48 ) {
@@ -1046,7 +1049,7 @@ st16:
 	if ( ++p == pe )
 		goto _test_eof16;
 case 16:
-#line 1050 "volumeExprScanner.cc"
+#line 1053 "volumeExprScanner.cc"
 	switch( (*p) ) {
 		case 69: goto st5;
 		case 101: goto st5;
@@ -1097,7 +1100,7 @@ st19:
 	if ( ++p == pe )
 		goto _test_eof19;
 case 19:
-#line 1101 "volumeExprScanner.cc"
+#line 1104 "volumeExprScanner.cc"
 	switch( (*p) ) {
 		case 46: goto tr58;
 		case 69: goto st5;
@@ -1148,7 +1151,7 @@ tr68:
 #line 1 "NONE"
 	{te = p+1;}
 #line 342 "volumeExprScanner.rl"
-	{act = 71;}
+	{act = 72;}
 	goto st23;
 tr72:
 #line 1 "NONE"
@@ -1204,151 +1207,157 @@ tr101:
 #line 416 "volumeExprScanner.rl"
 	{act = 44;}
 	goto st23;
-tr108:
+tr109:
 #line 1 "NONE"
 	{te = p+1;}
 #line 399 "volumeExprScanner.rl"
 	{act = 27;}
 	goto st23;
-tr110:
+tr112:
+#line 1 "NONE"
+	{te = p+1;}
+#line 450 "volumeExprScanner.rl"
+	{act = 71;}
+	goto st23;
+tr114:
 #line 1 "NONE"
 	{te = p+1;}
 #line 401 "volumeExprScanner.rl"
 	{act = 29;}
 	goto st23;
-tr114:
+tr118:
 #line 1 "NONE"
 	{te = p+1;}
 #line 446 "volumeExprScanner.rl"
 	{act = 67;}
 	goto st23;
-tr119:
+tr123:
 #line 1 "NONE"
 	{te = p+1;}
 #line 403 "volumeExprScanner.rl"
 	{act = 31;}
 	goto st23;
-tr123:
+tr127:
 #line 1 "NONE"
 	{te = p+1;}
 #line 429 "volumeExprScanner.rl"
 	{act = 54;}
 	goto st23;
-tr127:
+tr131:
 #line 1 "NONE"
 	{te = p+1;}
 #line 419 "volumeExprScanner.rl"
 	{act = 47;}
 	goto st23;
-tr128:
+tr132:
 #line 1 "NONE"
 	{te = p+1;}
 #line 428 "volumeExprScanner.rl"
 	{act = 53;}
 	goto st23;
-tr132:
+tr136:
 #line 1 "NONE"
 	{te = p+1;}
 #line 424 "volumeExprScanner.rl"
 	{act = 51;}
 	goto st23;
-tr133:
+tr137:
 #line 1 "NONE"
 	{te = p+1;}
 #line 398 "volumeExprScanner.rl"
 	{act = 26;}
 	goto st23;
-tr136:
+tr140:
 #line 1 "NONE"
 	{te = p+1;}
 #line 404 "volumeExprScanner.rl"
 	{act = 32;}
 	goto st23;
-tr138:
+tr142:
 #line 1 "NONE"
 	{te = p+1;}
 #line 423 "volumeExprScanner.rl"
 	{act = 50;}
 	goto st23;
-tr146:
+tr150:
 #line 1 "NONE"
 	{te = p+1;}
 #line 400 "volumeExprScanner.rl"
 	{act = 28;}
 	goto st23;
-tr147:
+tr151:
 #line 1 "NONE"
 	{te = p+1;}
 #line 434 "volumeExprScanner.rl"
 	{act = 59;}
 	goto st23;
-tr155:
+tr159:
 #line 1 "NONE"
 	{te = p+1;}
 #line 425 "volumeExprScanner.rl"
 	{act = 52;}
 	goto st23;
-tr157:
+tr161:
 #line 1 "NONE"
 	{te = p+1;}
 #line 415 "volumeExprScanner.rl"
 	{act = 43;}
 	goto st23;
-tr170:
+tr174:
 #line 1 "NONE"
 	{te = p+1;}
 #line 441 "volumeExprScanner.rl"
 	{act = 64;}
 	goto st23;
-tr173:
+tr177:
 #line 1 "NONE"
 	{te = p+1;}
 #line 406 "volumeExprScanner.rl"
 	{act = 34;}
 	goto st23;
-tr174:
+tr178:
 #line 1 "NONE"
 	{te = p+1;}
 #line 431 "volumeExprScanner.rl"
 	{act = 56;}
 	goto st23;
-tr182:
+tr186:
 #line 1 "NONE"
 	{te = p+1;}
 #line 440 "volumeExprScanner.rl"
 	{act = 63;}
 	goto st23;
-tr189:
+tr193:
 #line 1 "NONE"
 	{te = p+1;}
 #line 417 "volumeExprScanner.rl"
 	{act = 45;}
 	goto st23;
-tr197:
+tr201:
 #line 1 "NONE"
 	{te = p+1;}
 #line 449 "volumeExprScanner.rl"
 	{act = 70;}
 	goto st23;
-tr199:
+tr203:
 #line 1 "NONE"
 	{te = p+1;}
 #line 445 "volumeExprScanner.rl"
 	{act = 66;}
 	goto st23;
-tr204:
+tr208:
 #line 1 "NONE"
 	{te = p+1;}
 #line 438 "volumeExprScanner.rl"
 	{act = 61;}
 	goto st23;
-tr217:
+tr221:
 #line 1 "NONE"
 	{te = p+1;}
 #line 432 "volumeExprScanner.rl"
 	{act = 57;}
 	goto st23;
-tr219:
+tr223:
 #line 1 "NONE"
 	{te = p+1;}
 #line 433 "volumeExprScanner.rl"
@@ -1358,7 +1367,7 @@ st23:
 	if ( ++p == pe )
 		goto _test_eof23;
 case 23:
-#line 1362 "volumeExprScanner.cc"
+#line 1371 "volumeExprScanner.cc"
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
@@ -1853,6 +1862,7 @@ case 50:
 		case 46: goto tr68;
 		case 95: goto tr68;
 		case 103: goto st51;
+		case 108: goto st56;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -1942,7 +1952,7 @@ case 55:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 100: goto tr108;
+		case 100: goto tr109;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -1960,7 +1970,7 @@ case 56:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 120: goto st57;
+		case 116: goto st57;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -1978,13 +1988,13 @@ case 57:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 112: goto tr110;
+		case 97: goto st58;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
+		if ( 98 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -1995,14 +2005,14 @@ st58:
 case 58:
 	switch( (*p) ) {
 		case 46: goto tr68;
+		case 84: goto tr112;
 		case 95: goto tr68;
-		case 97: goto st59;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
+		if ( 97 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -2014,7 +2024,7 @@ case 59:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 108: goto st60;
+		case 120: goto st60;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2032,7 +2042,7 @@ case 60:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 115: goto st61;
+		case 112: goto tr114;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2050,13 +2060,13 @@ case 61:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto tr114;
+		case 97: goto st62;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
+		if ( 98 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -2068,7 +2078,7 @@ case 62:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 111: goto st63;
+		case 108: goto st63;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2086,7 +2096,7 @@ case 63:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 103: goto st64;
+		case 115: goto st64;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2103,8 +2113,8 @@ st64:
 case 64:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 49: goto st65;
 		case 95: goto tr68;
+		case 101: goto tr118;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2114,18 +2124,18 @@ case 64:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr117;
+	goto tr67;
 st65:
 	if ( ++p == pe )
 		goto _test_eof65;
 case 65:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 48: goto tr119;
 		case 95: goto tr68;
+		case 111: goto st66;
 	}
 	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
+		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
@@ -2140,14 +2150,13 @@ case 66:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 97: goto st67;
-		case 105: goto st71;
+		case 103: goto st67;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
+		if ( 97 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -2158,9 +2167,8 @@ st67:
 case 67:
 	switch( (*p) ) {
 		case 46: goto tr68;
+		case 49: goto st68;
 		case 95: goto tr68;
-		case 103: goto st68;
-		case 120: goto tr123;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2170,25 +2178,25 @@ case 67:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr67;
+	goto tr121;
 st68:
 	if ( ++p == pe )
 		goto _test_eof68;
 case 68:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 83: goto st69;
+		case 48: goto tr123;
 		case 95: goto tr68;
 	}
 	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
+		if ( 49 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr124;
+	goto tr67;
 st69:
 	if ( ++p == pe )
 		goto _test_eof69;
@@ -2196,13 +2204,14 @@ case 69:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 113: goto st70;
+		case 97: goto st70;
+		case 105: goto st74;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
+		if ( 98 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -2214,7 +2223,8 @@ case 70:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 114: goto tr127;
+		case 103: goto st71;
+		case 120: goto tr127;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2231,8 +2241,8 @@ st71:
 case 71:
 	switch( (*p) ) {
 		case 46: goto tr68;
+		case 83: goto st72;
 		case 95: goto tr68;
-		case 110: goto tr128;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2242,7 +2252,7 @@ case 71:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr67;
+	goto tr128;
 st72:
 	if ( ++p == pe )
 		goto _test_eof72;
@@ -2250,7 +2260,7 @@ case 72:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto st73;
+		case 113: goto st73;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2268,7 +2278,7 @@ case 73:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 103: goto st74;
+		case 114: goto tr131;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2285,18 +2295,18 @@ st74:
 case 74:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 48: goto tr132;
 		case 95: goto tr68;
+		case 110: goto tr132;
 	}
 	if ( (*p) < 65 ) {
-		if ( 49 <= (*p) && (*p) <= 57 )
+		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr131;
+	goto tr67;
 st75:
 	if ( ++p == pe )
 		goto _test_eof75;
@@ -2304,8 +2314,7 @@ case 75:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 105: goto tr133;
-		case 111: goto st76;
+		case 101: goto st76;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2323,8 +2332,7 @@ case 76:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 115: goto st77;
-		case 119: goto tr136;
+		case 103: goto st77;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2341,7 +2349,7 @@ st77:
 case 77:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 48: goto tr138;
+		case 48: goto tr136;
 		case 95: goto tr68;
 	}
 	if ( (*p) < 65 ) {
@@ -2352,7 +2360,7 @@ case 77:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr137;
+	goto tr135;
 st78:
 	if ( ++p == pe )
 		goto _test_eof78;
@@ -2360,13 +2368,14 @@ case 78:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 97: goto st79;
+		case 105: goto tr137;
+		case 111: goto st79;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
+		if ( 97 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -2378,8 +2387,8 @@ case 79:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 100: goto st80;
-		case 110: goto st85;
+		case 115: goto st80;
+		case 119: goto tr140;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2396,18 +2405,18 @@ st80:
 case 80:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 84: goto st81;
+		case 48: goto tr142;
 		case 95: goto tr68;
 	}
 	if ( (*p) < 65 ) {
-		if ( 48 <= (*p) && (*p) <= 57 )
+		if ( 49 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
 		if ( 97 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr67;
+	goto tr141;
 st81:
 	if ( ++p == pe )
 		goto _test_eof81;
@@ -2415,13 +2424,13 @@ case 81:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 111: goto st82;
+		case 97: goto st82;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
+		if ( 98 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -2432,8 +2441,9 @@ st82:
 case 82:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 68: goto st83;
 		case 95: goto tr68;
+		case 100: goto st83;
+		case 110: goto st88;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2450,8 +2460,8 @@ st83:
 case 83:
 	switch( (*p) ) {
 		case 46: goto tr68;
+		case 84: goto st84;
 		case 95: goto tr68;
-		case 101: goto st84;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2469,7 +2479,7 @@ case 84:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 103: goto tr146;
+		case 111: goto st85;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2486,8 +2496,8 @@ st85:
 case 85:
 	switch( (*p) ) {
 		case 46: goto tr68;
+		case 68: goto st86;
 		case 95: goto tr68;
-		case 100: goto tr147;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2505,11 +2515,7 @@ case 86:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 105: goto st87;
-		case 112: goto st90;
-		case 113: goto st103;
-		case 117: goto st105;
-		case 121: goto st106;
+		case 101: goto st87;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2527,8 +2533,7 @@ case 87:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 103: goto st88;
-		case 110: goto st89;
+		case 103: goto tr150;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2546,7 +2551,7 @@ case 88:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 110: goto tr155;
+		case 100: goto tr151;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2564,7 +2569,11 @@ case 89:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 104: goto tr157;
+		case 105: goto st90;
+		case 112: goto st93;
+		case 113: goto st106;
+		case 117: goto st108;
+		case 121: goto st109;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2574,7 +2583,7 @@ case 89:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr156;
+	goto tr67;
 st90:
 	if ( ++p == pe )
 		goto _test_eof90;
@@ -2582,7 +2591,8 @@ case 90:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 104: goto st91;
+		case 103: goto st91;
+		case 110: goto st92;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2600,7 +2610,7 @@ case 91:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto st92;
+		case 110: goto tr159;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2618,7 +2628,7 @@ case 92:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 114: goto st93;
+		case 104: goto tr161;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2628,7 +2638,7 @@ case 92:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr67;
+	goto tr160;
 st93:
 	if ( ++p == pe )
 		goto _test_eof93;
@@ -2636,7 +2646,7 @@ case 93:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 105: goto st94;
+		case 104: goto st94;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2654,7 +2664,7 @@ case 94:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 99: goto st95;
+		case 101: goto st95;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2672,13 +2682,13 @@ case 95:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 97: goto st96;
+		case 114: goto st96;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
+		if ( 97 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -2690,7 +2700,7 @@ case 96:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 108: goto st97;
+		case 105: goto st97;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2707,8 +2717,8 @@ st97:
 case 97:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 84: goto st98;
 		case 95: goto tr68;
+		case 99: goto st98;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2726,13 +2736,13 @@ case 98:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto st99;
+		case 97: goto st99;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
+		if ( 98 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -2744,7 +2754,7 @@ case 99:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 110: goto st100;
+		case 108: goto st100;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2761,8 +2771,8 @@ st100:
 case 100:
 	switch( (*p) ) {
 		case 46: goto tr68;
+		case 84: goto st101;
 		case 95: goto tr68;
-		case 115: goto st101;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2780,7 +2790,7 @@ case 101:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 111: goto st102;
+		case 101: goto st102;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2798,7 +2808,7 @@ case 102:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 114: goto tr170;
+		case 110: goto st103;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2816,7 +2826,7 @@ case 103:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 114: goto st104;
+		case 115: goto st104;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2834,7 +2844,7 @@ case 104:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 116: goto tr173;
+		case 111: goto st105;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2844,7 +2854,7 @@ case 104:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr172;
+	goto tr67;
 st105:
 	if ( ++p == pe )
 		goto _test_eof105;
@@ -2852,7 +2862,7 @@ case 105:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 109: goto tr174;
+		case 114: goto tr174;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2870,7 +2880,7 @@ case 106:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 109: goto st107;
+		case 114: goto st107;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2888,7 +2898,7 @@ case 107:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 109: goto st108;
+		case 116: goto tr177;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2898,15 +2908,15 @@ case 107:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr67;
+	goto tr176;
 st108:
 	if ( ++p == pe )
 		goto _test_eof108;
 case 108:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 84: goto st109;
 		case 95: goto tr68;
+		case 109: goto tr178;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2924,7 +2934,7 @@ case 109:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto st110;
+		case 109: goto st110;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2942,7 +2952,7 @@ case 110:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 110: goto st111;
+		case 109: goto st111;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2959,8 +2969,8 @@ st111:
 case 111:
 	switch( (*p) ) {
 		case 46: goto tr68;
+		case 84: goto st112;
 		case 95: goto tr68;
-		case 115: goto st112;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2978,7 +2988,7 @@ case 112:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 111: goto st113;
+		case 101: goto st113;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -2996,7 +3006,7 @@ case 113:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 114: goto tr182;
+		case 110: goto st114;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3014,16 +3024,13 @@ case 114:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 97: goto st115;
-		case 101: goto st117;
-		case 105: goto st122;
-		case 114: goto st124;
+		case 115: goto st115;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
+		if ( 97 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -3035,7 +3042,7 @@ case 115:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 110: goto st116;
+		case 111: goto st116;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3053,7 +3060,7 @@ case 116:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 104: goto tr189;
+		case 114: goto tr186;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3063,7 +3070,7 @@ case 116:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr188;
+	goto tr67;
 st117:
 	if ( ++p == pe )
 		goto _test_eof117;
@@ -3071,13 +3078,16 @@ case 117:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 110: goto st118;
+		case 97: goto st118;
+		case 101: goto st120;
+		case 105: goto st125;
+		case 114: goto st127;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
+		if ( 98 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -3089,7 +3099,7 @@ case 118:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 115: goto st119;
+		case 110: goto st119;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3107,7 +3117,7 @@ case 119:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 111: goto st120;
+		case 104: goto tr193;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3117,7 +3127,7 @@ case 119:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr67;
+	goto tr192;
 st120:
 	if ( ++p == pe )
 		goto _test_eof120;
@@ -3125,7 +3135,7 @@ case 120:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 114: goto tr193;
+		case 110: goto st121;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3136,19 +3146,14 @@ case 120:
 	} else
 		goto tr68;
 	goto tr67;
-tr193:
-#line 1 "NONE"
-	{te = p+1;}
-	goto st121;
 st121:
 	if ( ++p == pe )
 		goto _test_eof121;
 case 121:
-#line 3148 "volumeExprScanner.cc"
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 58: goto st8;
 		case 95: goto tr68;
+		case 115: goto st122;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3158,21 +3163,7 @@ case 121:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr194;
-st8:
-	if ( ++p == pe )
-		goto _test_eof8;
-case 8:
-	if ( (*p) == 58 )
-		goto st9;
-	goto tr9;
-st9:
-	if ( ++p == pe )
-		goto _test_eof9;
-case 9:
-	if ( (*p) == 73 )
-		goto tr11;
-	goto tr9;
+	goto tr67;
 st122:
 	if ( ++p == pe )
 		goto _test_eof122;
@@ -3180,7 +3171,7 @@ case 122:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 109: goto st123;
+		case 111: goto st123;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3198,7 +3189,7 @@ case 123:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto tr197;
+		case 114: goto tr197;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3209,14 +3200,19 @@ case 123:
 	} else
 		goto tr68;
 	goto tr67;
+tr197:
+#line 1 "NONE"
+	{te = p+1;}
+	goto st124;
 st124:
 	if ( ++p == pe )
 		goto _test_eof124;
 case 124:
+#line 3212 "volumeExprScanner.cc"
 	switch( (*p) ) {
 		case 46: goto tr68;
+		case 58: goto st8;
 		case 95: goto tr68;
-		case 117: goto st125;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3226,7 +3222,21 @@ case 124:
 			goto tr68;
 	} else
 		goto tr68;
-	goto tr67;
+	goto tr198;
+st8:
+	if ( ++p == pe )
+		goto _test_eof8;
+case 8:
+	if ( (*p) == 58 )
+		goto st9;
+	goto tr9;
+st9:
+	if ( ++p == pe )
+		goto _test_eof9;
+case 9:
+	if ( (*p) == 73 )
+		goto tr11;
+	goto tr9;
 st125:
 	if ( ++p == pe )
 		goto _test_eof125;
@@ -3234,7 +3244,7 @@ case 125:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto tr199;
+		case 109: goto st126;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3252,7 +3262,7 @@ case 126:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto st127;
+		case 101: goto tr201;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3270,7 +3280,7 @@ case 127:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 99: goto st128;
+		case 117: goto st128;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3288,7 +3298,7 @@ case 128:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 116: goto st129;
+		case 101: goto tr203;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3306,7 +3316,7 @@ case 129:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 111: goto st130;
+		case 101: goto st130;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3324,7 +3334,7 @@ case 130:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 114: goto tr204;
+		case 99: goto st131;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3342,7 +3352,7 @@ case 131:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto st132;
+		case 116: goto st132;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3360,7 +3370,7 @@ case 132:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 105: goto st133;
+		case 111: goto st133;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3378,7 +3388,7 @@ case 133:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 103: goto st134;
+		case 114: goto tr208;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3396,7 +3406,7 @@ case 134:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 104: goto st135;
+		case 101: goto st135;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3414,7 +3424,7 @@ case 135:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 116: goto st136;
+		case 105: goto st136;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3431,11 +3441,10 @@ st136:
 case 136:
 	switch( (*p) ) {
 		case 46: goto tr68;
-		case 65: goto st137;
-		case 83: goto st143;
 		case 95: goto tr68;
+		case 103: goto st137;
 	}
-	if ( (*p) < 66 ) {
+	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
@@ -3451,7 +3460,7 @@ case 137:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 118: goto st138;
+		case 104: goto st138;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3469,7 +3478,7 @@ case 138:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto st139;
+		case 116: goto st139;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3486,10 +3495,11 @@ st139:
 case 139:
 	switch( (*p) ) {
 		case 46: goto tr68;
+		case 65: goto st140;
+		case 83: goto st146;
 		case 95: goto tr68;
-		case 114: goto st140;
 	}
-	if ( (*p) < 65 ) {
+	if ( (*p) < 66 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
@@ -3505,13 +3515,13 @@ case 140:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 97: goto st141;
+		case 118: goto st141;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 98 <= (*p) && (*p) <= 122 )
+		if ( 97 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -3523,7 +3533,7 @@ case 141:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 103: goto st142;
+		case 101: goto st142;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3541,7 +3551,7 @@ case 142:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 101: goto tr217;
+		case 114: goto st143;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3559,13 +3569,13 @@ case 143:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 117: goto st144;
+		case 97: goto st144;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto tr68;
 	} else if ( (*p) > 90 ) {
-		if ( 97 <= (*p) && (*p) <= 122 )
+		if ( 98 <= (*p) && (*p) <= 122 )
 			goto tr68;
 	} else
 		goto tr68;
@@ -3577,7 +3587,61 @@ case 144:
 	switch( (*p) ) {
 		case 46: goto tr68;
 		case 95: goto tr68;
-		case 109: goto tr219;
+		case 103: goto st145;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr68;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr68;
+	} else
+		goto tr68;
+	goto tr67;
+st145:
+	if ( ++p == pe )
+		goto _test_eof145;
+case 145:
+	switch( (*p) ) {
+		case 46: goto tr68;
+		case 95: goto tr68;
+		case 101: goto tr221;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr68;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr68;
+	} else
+		goto tr68;
+	goto tr67;
+st146:
+	if ( ++p == pe )
+		goto _test_eof146;
+case 146:
+	switch( (*p) ) {
+		case 46: goto tr68;
+		case 95: goto tr68;
+		case 117: goto st147;
+	}
+	if ( (*p) < 65 ) {
+		if ( 48 <= (*p) && (*p) <= 57 )
+			goto tr68;
+	} else if ( (*p) > 90 ) {
+		if ( 97 <= (*p) && (*p) <= 122 )
+			goto tr68;
+	} else
+		goto tr68;
+	goto tr67;
+st147:
+	if ( ++p == pe )
+		goto _test_eof147;
+case 147:
+	switch( (*p) ) {
+		case 46: goto tr68;
+		case 95: goto tr68;
+		case 109: goto tr223;
 	}
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
@@ -3714,11 +3778,11 @@ case 10:
 	_test_eof119: cs = 119; goto _test_eof; 
 	_test_eof120: cs = 120; goto _test_eof; 
 	_test_eof121: cs = 121; goto _test_eof; 
-	_test_eof8: cs = 8; goto _test_eof; 
-	_test_eof9: cs = 9; goto _test_eof; 
 	_test_eof122: cs = 122; goto _test_eof; 
 	_test_eof123: cs = 123; goto _test_eof; 
 	_test_eof124: cs = 124; goto _test_eof; 
+	_test_eof8: cs = 8; goto _test_eof; 
+	_test_eof9: cs = 9; goto _test_eof; 
 	_test_eof125: cs = 125; goto _test_eof; 
 	_test_eof126: cs = 126; goto _test_eof; 
 	_test_eof127: cs = 127; goto _test_eof; 
@@ -3739,6 +3803,9 @@ case 10:
 	_test_eof142: cs = 142; goto _test_eof; 
 	_test_eof143: cs = 143; goto _test_eof; 
 	_test_eof144: cs = 144; goto _test_eof; 
+	_test_eof145: cs = 145; goto _test_eof; 
+	_test_eof146: cs = 146; goto _test_eof; 
+	_test_eof147: cs = 147; goto _test_eof; 
 	_test_eof10: cs = 10; goto _test_eof; 
 
 	_test_eof: {}
@@ -3799,23 +3866,23 @@ case 10:
 	case 61: goto tr67;
 	case 62: goto tr67;
 	case 63: goto tr67;
-	case 64: goto tr117;
+	case 64: goto tr67;
 	case 65: goto tr67;
 	case 66: goto tr67;
-	case 67: goto tr67;
-	case 68: goto tr124;
+	case 67: goto tr121;
+	case 68: goto tr67;
 	case 69: goto tr67;
 	case 70: goto tr67;
-	case 71: goto tr67;
+	case 71: goto tr128;
 	case 72: goto tr67;
 	case 73: goto tr67;
-	case 74: goto tr131;
+	case 74: goto tr67;
 	case 75: goto tr67;
 	case 76: goto tr67;
-	case 77: goto tr137;
+	case 77: goto tr135;
 	case 78: goto tr67;
 	case 79: goto tr67;
-	case 80: goto tr67;
+	case 80: goto tr141;
 	case 81: goto tr67;
 	case 82: goto tr67;
 	case 83: goto tr67;
@@ -3824,10 +3891,10 @@ case 10:
 	case 86: goto tr67;
 	case 87: goto tr67;
 	case 88: goto tr67;
-	case 89: goto tr156;
+	case 89: goto tr67;
 	case 90: goto tr67;
 	case 91: goto tr67;
-	case 92: goto tr67;
+	case 92: goto tr160;
 	case 93: goto tr67;
 	case 94: goto tr67;
 	case 95: goto tr67;
@@ -3839,10 +3906,10 @@ case 10:
 	case 101: goto tr67;
 	case 102: goto tr67;
 	case 103: goto tr67;
-	case 104: goto tr172;
+	case 104: goto tr67;
 	case 105: goto tr67;
 	case 106: goto tr67;
-	case 107: goto tr67;
+	case 107: goto tr176;
 	case 108: goto tr67;
 	case 109: goto tr67;
 	case 110: goto tr67;
@@ -3851,17 +3918,17 @@ case 10:
 	case 113: goto tr67;
 	case 114: goto tr67;
 	case 115: goto tr67;
-	case 116: goto tr188;
+	case 116: goto tr67;
 	case 117: goto tr67;
 	case 118: goto tr67;
-	case 119: goto tr67;
+	case 119: goto tr192;
 	case 120: goto tr67;
-	case 121: goto tr194;
-	case 8: goto tr9;
-	case 9: goto tr9;
+	case 121: goto tr67;
 	case 122: goto tr67;
 	case 123: goto tr67;
-	case 124: goto tr67;
+	case 124: goto tr198;
+	case 8: goto tr9;
+	case 9: goto tr9;
 	case 125: goto tr67;
 	case 126: goto tr67;
 	case 127: goto tr67;
@@ -3882,13 +3949,16 @@ case 10:
 	case 142: goto tr67;
 	case 143: goto tr67;
 	case 144: goto tr67;
+	case 145: goto tr67;
+	case 146: goto tr67;
+	case 147: goto tr67;
 	}
 	}
 
 	_out: {}
 	}
 
-#line 691 "volumeExprScanner.rl"
+#line 692 "volumeExprScanner.rl"
    /* ^^^ FSM execution here ^^^ */;
 
     if (0 == cs)
diff --git a/src/finiteVolume/expressions/volume/volumeExprScanner.rl b/src/finiteVolume/expressions/volume/volumeExprScanner.rl
index 8c552a93316..a1538290052 100644
--- a/src/finiteVolume/expressions/volume/volumeExprScanner.rl
+++ b/src/finiteVolume/expressions/volume/volumeExprScanner.rl
@@ -61,12 +61,12 @@ namespace Foam
 // Special handling for these known (stashed) look-back types
 static const Enum<int> lookBehindTokenEnums
 ({
-    TOKEN_PAIR("cellSet", CSET),
-    TOKEN_PAIR("faceSet", FSET),
-    TOKEN_PAIR("pointSet", PSET),
-    TOKEN_PAIR("cellZone", CZONE),
-    TOKEN_PAIR("faceZone", FZONE),
-    TOKEN_PAIR("pointZone", PZONE),
+    TOKEN_PAIR("cellSet", CELL_SET),
+    TOKEN_PAIR("faceSet", FACE_SET),
+    TOKEN_PAIR("pointSet", POINT_SET),
+    TOKEN_PAIR("cellZone", CELL_ZONE),
+    TOKEN_PAIR("faceZone", FACE_ZONE),
+    TOKEN_PAIR("pointZone", POINT_ZONE),
 });
 
 #define HAS_LOOKBEHIND_TOKENS
@@ -201,12 +201,12 @@ static int driverTokenType
 
         switch (lookBehind)
         {
-            case TOK_CSET : good = driver_.isCellSet(ident); break;
-            case TOK_FSET : good = driver_.isFaceSet(ident); break;
-            case TOK_PSET : good = driver_.isPointSet(ident); break;
-            case TOK_CZONE : good = driver_.isCellZone(ident); break;
-            case TOK_FZONE : good = driver_.isFaceZone(ident); break;
-            case TOK_PZONE : good = driver_.isPointZone(ident); break;
+            case TOK_CELL_SET : good = driver_.isCellSet(ident); break;
+            case TOK_FACE_SET : good = driver_.isFaceSet(ident); break;
+            case TOK_POINT_SET : good = driver_.isPointSet(ident); break;
+            case TOK_CELL_ZONE : good = driver_.isCellZone(ident); break;
+            case TOK_FACE_ZONE : good = driver_.isFaceZone(ident); break;
+            case TOK_POINT_ZONE : good = driver_.isPointZone(ident); break;
         }
 
         if (good)
@@ -365,7 +365,7 @@ static int driverTokenType
 
     number => emit_number;
 
-    ## operators
+    ## Operators
     '!'  =>{ EMIT_TOKEN(NOT); };
     '%'  =>{ EMIT_TOKEN(PERCENT); };
     '('  =>{ EMIT_TOKEN(LPAREN); };
@@ -447,6 +447,7 @@ static int driverTokenType
     "tensor::I" =>{ EMIT_TOKEN(IDENTITY_TENSOR); };
     "arg"       =>{ EMIT_TOKEN(ARG); };
     "time"      =>{ EMIT_TOKEN(TIME); };
+    "deltaT"    =>{ EMIT_TOKEN(DELTA_T); };
 
     ## Identifier (field, etc - error if unknown)
     ## Handle 'bare' names and single/double quoted ones
-- 
GitLab