package org.codehaus.jparsec.lambda;

import org.codehaus.jparsec.Parser;
import org.codehaus.jparsec.Scanners;
import org.codehaus.jparsec.misc.Mapper;

import static org.codehaus.jparsec.misc.Mapper._;

public class LambdaParser {

  // scanners
  private static final Parser<String> identifier = Scanners.IDENTIFIER;

  private static final Parser<?> L_PAREN = token("(");
  private static final Parser<?> R_PAREN = token(")");
  private static final Parser<?> WS = _(Scanners.WHITESPACES);
  private static final Parser<?> WS_OPT = _(Scanners.WHITESPACES.optional());

  // parsers
  private static final Parser.Reference<Expr> lambdaRef = Parser.newReference();

  private static final Parser<Expr> var = Mapper.curry(Var.class).sequence(identifier).cast();

  private static final Parser<App> app = Mapper.curry(App.class)
      .sequence(WS_OPT, lambdaRef.lazy(), WS_OPT, lambdaRef.lazy(), WS_OPT)
      .between(L_PAREN, R_PAREN).between(WS_OPT, WS_OPT);

  private static final Parser<Expr> lambda = var.or(app);

  private static Parser<?> token(String name) {
    return _(Scanners.string(name));
  }

  static {
    lambdaRef.set(lambda);
  }

  public Expr parse(String input) {
    return lambda.parse(input);
  }

}

@@ -137,21 +137,107 @@
 sec.
-misc.Mapper;%0A
+Terminals;%0Aimport org.codehaus.jparsec.misc.Mapper;%0A%0Aimport static org.codehaus.jparsec.Parsers.or;
 %0Aimp
@@ -382,25 +382,33 @@
 r = 
-Scanners.IDENTIFI
+Terminals.Identifier.PARS
 ER;%0A
@@ -435,39 +435,90 @@
 nal 
-Parser%3C?%3E L_PAREN = token(%22(%22);
+Terminals TERMS = Terminals.caseSensitive(new String%5B%5D%7B%22(%22, %22)%22%7D, new String%5B0%5D);%0A
 %0A  p
@@ -547,17 +547,17 @@
 rser%3C?%3E 
-R
+L
 _PAREN =
@@ -564,17 +564,17 @@
  token(%22
-)
+(
 %22);%0A  pr
@@ -606,113 +606,27 @@
 %3C?%3E 
-WS = _(Scanners.WHITESPACES);%0A  private static final Parser%3C?%3E WS_OPT = _(Scanners.WHITESPACES.optional()
+R_PAREN = token(%22)%22
 );%0A%0A
@@ -750,19 +750,18 @@
  Parser%3C
-Exp
+Va
 r%3E var =
@@ -809,15 +809,8 @@
 ier)
-.cast()
 ;%0A%0A 
@@ -889,24 +889,16 @@
 equence(
-WS_OPT, 
 lambdaRe
@@ -910,16 +910,8 @@
 y(),
- WS_OPT,
  lam
@@ -923,24 +923,16 @@
 f.lazy()
-, WS_OPT
 )%0A      
@@ -961,32 +961,8 @@
 REN)
-.between(WS_OPT, WS_OPT)
 ;%0A%0A 
@@ -1009,15 +1009,15 @@
 a = 
-var.or(
+or(var,
 app)
@@ -1084,23 +1084,19 @@
 n _(
-Scanners.string
+TERMS.token
 (nam
@@ -1202,16 +1202,72 @@
  lambda.
+from(TERMS.tokenizer(),Scanners.WHITESPACES.optional()).
 parse(in

use terminals to tokenize input [pme]