//    deriv2.java by Steven R. Brandt
//    <p>
//    An example file explaining how to use
//    com.stevesoft.pat, com.stevesoft.pat.wrap,
//    and com.stevesoft.pat.apps
//    <p>
//    This software comes without express or implied warranty.
//    No claim is made about the suitability of this software for
//    any purpose and neither I nor SteveSoft shall be liable for
//    damages suffered by the user of this software.
import com.stevesoft.pat.*;

/* Inventing patterns for package pat was possible, but not
   a simple operation in the past.  Now it is easy.

   To define a pattern you now need three things:

   1) A name:  The syntax for your pattern will be
   "(??name)".  By beginning the pattern with the
   String "(?" we follow the convention established
   by Perl for creating new pattern strings that don't
   conflict with previously existing ones.

   2) A normal Regex pattern:  Probably whatever pattern
   you want to define must satisfy a certain standard Regex.
   In our example, we want to match valid mathematical
   statement of the form digit+digit=digit.  This rule must
   satisfy the Regex "\\d\\+\\d=\\d" as one criterion for a
   successful match.

   3) A Validator:  You should derive a class from Validator
   that defines the method validate(String src,int start,int end).
   This method does whatever other checking you require for your
   pattern to match that a normal Regex can't do -- in our example
   we check to see if the first two digits do, in fact, add up
   to the third.  The first argument is the String we are searching,
   the second is the start position of the matching portion of the string,
   the third is the end position.  If your validator method wants
   the String to match, it should return the new end position
   within the String.  Often, this will just mean returning the
   value passed in the third argument of validate, as below.

   If you return a -1 from this method, the validation fails and
   Regex will keep looking (if possible) for something that matches
   your pattern.


   These three things, the name, pattern, and validator should
   be given to the static method

     Regex.define(String name, String pattern, Validator v).

   Once this is done, further compilations by Regex will know
   about your new pattern.
   */

// This is the new rule we wish to define...
class CheckMath extends Validator {
  public int validate(StringLike src,int start,int end) {
    // get the values of the three digits -- we know
    // that we will have digits here because of the
    // pattern we specified.
    int d1 = src.charAt(start)-'0';
    int d2 = src.charAt(start+2)-'0';
    int d3 = src.charAt(start+4)-'0';
    return d1+d2 == d3 ? end : -1;
  }
}

public class deriv2 {
  public static void main(String[] args) {

    Regex.define(
      "math1",          // name of our new pattern
      "\\d\\+\\d=\\d",  // a standard Regex that our pattern must satisfy
      new CheckMath()); // Validator for our pattern

    // The second argument to Regex is the replacement rule,
    // and, as is conventional, $& expands to the matched portion
    // of the pattern.
    Regex r = new Regex("(??math1)","correct($&)");

    // Substitute for valid matches in a test String.
    String p = r.replaceAll("math 1+1=2, 2+3=4, 6+2=8, 1+3=9, 2+3=5.");

    System.out.println(p);
  }
}
