oft House Labs

Product Pattern String Engine 1.1
Author Copyright (c) 1999, Soft House Labs, Andre N Belokon
Web:   http://softlab.od.ua
Email: support@softlab.od.ua
Status Shareware
   without source 25$
   with source 40$
Limitation Work only in Delphi IDE. Nag-screen.
Registration Pattern String Engine w/o source Registration
Pattern String Engine with source Registration

This is a legal Agreement between you (either an single individual or an entity, herein referred to as Licensee) and SoftHouseLabs (herein after referred to as Licensor). By installing this software (herein after referred to as Product), you indicate your acceptance of this Agreement.

SOFTHOUSELABS EVALUATION LICENSE AGREEMENT

  1.GRANT OF LICENSE.

    1.1 Licensor grants you a non-exclusive royalty-free license to make as many copies of the Product accompanying this greement as you want, solely to test and to evaluate the Product efore you make the decision to purchase the Product.

    1.2 You shall not use, copy, rent, lease, sell, modify, decompile, disassemble, otherwise reverse engineer, or transfer the Product except as provided in this Agreement. Any such unauthorized use shall result in immediate and automatic termination of this Agreement.

    1.3 You may transfer and distribute the Product in its unmodified form via electronic means to another persons so long as their use of the Product will be strictly for the purpose of evaluation.

    1.4 You are specificaly prohibited from charging, or requesting donations for copies of the Product, distributing the Product with any other products without Licensors prior written permission.

  2. WARRANTY AND LIMITATION OF LIABILITY.

The Licensor hereby disclaims all warranties of any kind relating to the Product, whether express or implied, including without limitation any implied warranties of merchantability or fitness for a particular purpose. The Licensee must assume the entire risk of using the Product.

   Pattern String Engine is intended for lexical analysis of strings. Is based on technology "pattern matching". Allows to find all possible variants of comparison of string with a pattern (exhausting search).

Examples of use:

Check string on correspondence to pattern <number> [+ -* /] <number>:

var pat: TPattern;
..............................
// Create pattern
pat: = PSE( [PSENumber, PSEChar('+-*/'), PSENumber] );
// Activate pattern on some string
pat.Activate (SourceString);
if pat.Match then begin
   // Match OK
end;
// Free pattern

pat.Free;

Some remark for this sample:

PSENumber - predefined pattern, which compare with any number (digital sequence).
PSEChar(const S: string) - create pattern for single char, exists in string S (used as charset).
PSE(PatternList: array of const) - group sequence of patterns in single pattern.

The previous example, but is little bit more complex. We have determined, that the string corresponds to some pattern, but more often it is required to divide this string on some substrings appropriate to some parts of the template. So, for example, we should select two numbers and sign of operation. It is easy for making:

var pat: TPattern;
    num1, num2, sign: string;
..............................
// Create pattern
pat: = PSE( [PSENumber[num1],
             PSEChar('+-*/')[sign],
             PSENumber[num2]] );
// Activate pattern on some string
pat.Activate(SourceString);
if pat.Match then // Math OK
  case sign[1] of
    '+': Result:=StrToFloat(num1) + StrToFloat(num2);
    '-': Result:=StrToFloat(num1) - StrToFloat(num2);
    '*': Result:=StrToFloat(num1) * StrToFloat(num2);
    '/': Result:=StrToFloat(num1) / StrToFloat(num2);
  end
else
  
Result:=0;
// Free pattern
pat.Free;

In this sample we used linking pattern with variable (PSENumber[num1]). After successful matching, text coincided with this pattern will be assigned to linked variable.

Taking into account, that the pattern matching is made always at the left on the right, we can use already assigned values more to the right for comparison. For example, the following pattern will find two equal substrings with maximum length:

var pat: TPattern;
    str,maxstr: string;
..............................
// Create pattern

pat:=PSE([PSEAny, PSEAnyStr[str],
          PSEAny, PSEVar(str), PSEAny]);
// Activate pattern on some string
pat.Activate (SourceString);
maxstr:='';
// for all successful matches
while
pat.Match do begin
  if Length(str) > Length(maxstr) then
    
maxstr:=str;
  pat.MatchNext;
end;
pat.Free;
// Write result
writeln(maxstr);

For SorceString is equal to 'pattern string engine find all matches pattern in string' we have result 'pattern'.

Some remark for sample:

PSEAny - predefined pattern, which will be successful compare with any string or empty string.
PSEVar(const S: string) - predefined pattern, which successful compare with string equal to value of variable, putting as parameter.

There are special pattern for build more complex pattern. For example

pat:=PSE( [PSEOneOf([PSENumber, PSEIdent]),
           PSEChar('+-*/'),
           PSEOneOf([PSENumber, PSEIdent])] );

successfully is compared to the following strings: '267+67', '267-abc', 'Abc*i'

PSEOneOf([list of pattern]) math successful if some pattern from list is successful.

Pattern String Engine interface part


unit PatternEngine;

// Pattern String Engine for Delphi 4.0
// Version 1.1 Shareware
// Copyright (c) Soft House Labs, Andre N Belokon, 1997-1999
// WWW:   http://softlab.od.ua/
// EMail: support@softlab.od.ua

interface

uses  SysUtils, Windows, Classes, Dialogs;

type
  PatternException = class(Exception);
  TPattern = class;

  TPatItemType = (piNil,piSimple,piPattern);
  TPatItem = class
  public
    ItemType: TPatItemType;
    pSimple:   string;
    pPattern:  TPattern;
    constructor Create(const VarRec: TVarRec);
    destructor Destroy; override;
    property MathLen: integer;
  end;

  TPatList = class(TList)
  public
    constructor Create(AOwner: TPattern; const Pattern: array of const);
    destructor Destroy; override;
    procedure NewItem(const VarRec: TVarRec);
    property Items[Index: integer]: TPatItem;
  end;

  TPattern = class(TObject)
  public
    constructor Create(const APattern: array of const);
    destructor Destroy; override;

    procedure Activate(const S: string);
    procedure ActivatePtr(P: PChar);

    function Math: Boolean;
    procedure MathNext; virtual; abstract;

    property MathPtr: PChar;
    property MathNextPtr: PChar;
    property MathStr: string;
    property MathLen: integer;
    property IsMath: Boolean;

    property SetValue[var AValue: string]: TPattern; default;
  end;

  TPSE = class(TPattern)
  public
    procedure MathNext; override;
  end;

  TPSEOneOf = class(TPattern)
  public
    procedure MathNext; override;
  end;

  TPSEMayBe = class(TPSE)
  public
    procedure MathNext; override;
  end;

  TPSECharSet = class(TPattern)
  public
    // SCharSet:: 'asd..g0..5.8' -> ['a','s','d'..'g','0'..'5','.','8']
    // if #0 in CharSet then goal may be have empty length
    constructor Create(const SCharSet: string);
    constructor CreateLen(const SCharSet: string; AMaxLen: integer);
    procedure MathNext; override;
  end;

  TPSEVar = class(TPattern)
  public
    constructor Create(var AValue: string);
    procedure MathNext; override;
  end;

  TPSESetLen = class(TPSE)
  public
    constructor Create(const APattern: array of const; Min,Max: integer);
    procedure MathNext; override;
  end;

  TPatternCallBack = function: Boolean;
  TPSEBack = class(TPattern)
  public
    constructor Create(ACallBack: TPatternCallBack);
    procedure MathNext; override;
  end;

function PSE(const APattern: array of const): TPattern;
function PSEOneOf(const APattern: array of const): TPattern;
function PSEMayBe(const APattern: array of const): TPattern;
function PSECharSet(const SCharSet: string): TPattern;
function PSECharSetLen(const SCharSet: string; AMaxLen: integer): TPattern;
function PSEChar(const SCharSet: string): TPattern;
function PSEVar(var AValue: string): TPattern;
function PSESetLen(const APattern: array of const; Min,Max: integer): TPattern;
function PSEBack(ACallBack: TPatternCallBack): TPattern;

function PSEDigit: TPattern;    // 0..9
function PSEDigits: TPattern;   // <digit>{<digit>}
function PSEInteger: TPattern;  // [+-]<digits>
function PSENumber: TPattern;   // [+-]<digits>[.<digits>]
function PSEIdent: TPattern;    // a..zA..Z_{a..zA..Z0..9_}
function PSEAny: TPattern;      // any string or empty
function PSEAnyStr: TPattern;   // any string with length > 0
function PSEAnyChar: TPattern;  // any char

implementation

function PSEBack(ACallBack: TPatternCallBack): TPattern;
begin
  Result:=TPSEBack.Create(ACallBack);
end;

function PSEAnyStr: TPattern;
begin
  Result:=PSECharSet(#1'..'#255);
end;

function PSEAnyChar: TPattern;
begin
  Result:=PSECharSetLen(#1'..'#255,1);
end;

function PSEAny: TPattern;
begin
  Result:=PSECharSet(#1'..'#255#0);
end;

function PSESetLen(const APattern: array of const; Min,Max: integer): TPattern;
begin
  Result:=TPSESetLen.Create(APattern,Min,Max);
end;

function PSEMayBe(const APattern: array of const): TPattern;
begin
  Result:=TPSEMayBe.Create(APattern);
end;

function PSEVar(var AValue: string): TPattern;
begin
  Result:=TPSEVar.Create(AValue);
end;

function PSENumber: TPattern;
begin
  Result:=PSE([PSEChar('+-'#0),PSEDigits,PSEMayBe([PSEMayBe(['.']),PSEDigits])]);
end;

function PSEInteger: TPattern;
begin
  Result:=PSE([PSEChar('+-'#0),PSEDigits]);
end;

function PSEIdent: TPattern;
begin
  Result:=PSE([PSEChar('a..zA..Z_'),PSECharSet('a..zA..Z_0..9'#0)]);
end;

function PSEDigits: TPattern;
begin
  Result:=PSECharSet('0..9');
end;

function PSEDigit: TPattern;
begin
  Result:=PSEChar('0..9');
end;

function PSE(const APattern: array of const): TPattern;
begin
  Result:=TPSE.Create(APattern);
end;

function PSEOneOf(const APattern: array of const): TPattern;
begin
  Result:=TPSEOneOf.Create(APattern);
end;

function PSEChar(const SCharSet: string): TPattern;
begin
  Result:=TPSECharSet.CreateLen(SCharSet,1);
end;

function PSECharSet(const SCharSet: string): TPattern;
begin
  Result:=TPSECharSet.Create(SCharSet);
end;

function PSECharSetLen(const SCharSet: string; AMaxLen: integer): TPattern;
begin
  Result:=TPSECharSet.CreateLen(SCharSet,AMaxLen);
end;