Last active
July 26, 2017 14:03
-
-
Save kmizu/6f7687b0924bd00baab76ae43ef62386 to your computer and use it in GitHub Desktop.
Javaで始めるパーザコンビネータの作り方(3) ~ Hello or World! ref: http://qiita.com/kmizu/items/c509d726285c2e7416fb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Parser<A> pa = ...; | |
Parser<B> pb = ...; | |
String input; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ParseResult<X> lresult = pa.invoke(input); //(1) | |
if(lresult instanceof ParseResult.Failure<?>) { | |
return pb.invoke(input); | |
} else { | |
return lresult; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package parser; | |
public class Or<X> implements Parser<X> { | |
private Parser<X> lhs; | |
private Parser<X> rhs; | |
public Or(Parser<X> lhs, Parser<X> rhs) { | |
this.lhs = lhs; | |
this.rhs = rhs; | |
} | |
@Override | |
public ParseResult<X> invoke(String input) { | |
ParseResult<X> lresult = lhs.invoke(input); | |
if(lresult instanceof ParseResult.Failure<?>) { | |
return rhs.invoke(input); | |
} else { | |
return lresult; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package parser; | |
public interface Parser<T> { | |
ParseResult<T> invoke(String input); | |
default Parser<T> or(Parser<T> rhs) { | |
return new Or<>(this, rhs); | |
} | |
default <U> Parser<Tuple2<T, U>> cat(Parser<U> rhs) { | |
return new Cat<>(this, rhs); | |
} | |
static Parser<String> string(String literal) { | |
return new StringParser(literal); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Main { | |
public static void main(String[] args) { | |
Parser<String> helloOrWorld = Parser.string("Hello").or(Parser.string("World")); | |
Parser<Tuple2<String, String>> hw = helloOrWorld.cat(helloOrWorld); | |
System.out.println(hw.invoke("HelloWorld")); | |
System.out.println(hw.invoke("HelloHello")); | |
System.out.println(hw.invoke("WorldHello")); | |
System.out.println(hw.invoke("WorldWorld")); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Success(Tuple2{item1=Hello, item2=World}, ) | |
Success(Tuple2{item1=Hello, item2=Hello}, ) | |
Success(Tuple2{item1=World, item2=Hello}, ) | |
Success(Tuple2{item1=World, item2=World}, ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package parser; | |
public interface ParseResult<T> { | |
public static class Success<T> implements ParseResult<T> { | |
public final T value; | |
public final String next; | |
Success(T value, String next) { | |
this.value = value; | |
this.next = next; | |
} | |
@Override | |
public <U> ParseResult<U> map(Function<T, U> fn) { | |
return new Success<U>(fn.apply(value), next); | |
} | |
@Override | |
public String toString() { | |
return "Success(" + value + ", " + next + ")"; | |
} | |
} | |
public static class Failure<T> implements ParseResult<T> { | |
public final String message; | |
public final String next; | |
public Failure(String message, String next) { | |
this.message = message; | |
this.next = next; | |
} | |
@Override | |
public <U> ParseResult<U> map(Function<T, U> fn) { | |
return (ParseResult<U>)this; | |
} | |
@Override | |
public String toString() { | |
return "Failure(" + message + ", " + next; | |
} | |
} | |
<U> ParseResult<U> map(Function<T, U> fn); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package parser; | |
import java.util.function.BiFunction; | |
public class Tuple2<X, Y> { | |
public final X item1; | |
public final Y item2; | |
public Tuple2(X item1, Y item2) { | |
this.item1 = item1; | |
this.item2 = item2; | |
} | |
public X item1() { | |
return item1; | |
} | |
public Y item2() { | |
return item2; | |
} | |
public <U> U extract(BiFunction<X, Y, U> f) { | |
return f.apply(item1, item2); | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (this == o) return true; | |
if (o == null || getClass() != o.getClass()) return false; | |
Tuple2<?, ?> tp2 = (Tuple2<?, ?>) o; | |
if (!item1.equals(tp2.item1)) return false; | |
return item2.equals(tp2.item2); | |
} | |
@Override | |
public int hashCode() { | |
int result = item1.hashCode(); | |
result = 31 * result + item2.hashCode(); | |
return result; | |
} | |
@Override | |
public String toString() { | |
return "Tuple2{" + "item1=" + item1 + ", item2=" + item2 + '}'; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package parser; | |
import java.util.function.BiFunction; | |
public class Tuple2<X, Y> { | |
public final X item1; | |
public final Y item2; | |
public Tuple2(X item1, Y item2) { | |
this.item1 = item1; | |
this.item2 = item2; | |
} | |
public X item1() { | |
return item1; | |
} | |
public Y item2() { | |
return item2; | |
} | |
public <U> U extract(BiFunction<X, Y, U> f) { | |
return f.apply(item1, item2); | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (this == o) return true; | |
if (o == null || getClass() != o.getClass()) return false; | |
Tuple2<?, ?> tp2 = (Tuple2<?, ?>) o; | |
if (!item1.equals(tp2.item1)) return false; | |
return item2.equals(tp2.item2); | |
} | |
@Override | |
public int hashCode() { | |
int result = item1.hashCode(); | |
result = 31 * result + item2.hashCode(); | |
return result; | |
} | |
@Override | |
public String toString() { | |
return "Tuple2{" + "item1=" + item1 + ", item2=" + item2 + '}'; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment