-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add parser fuzzer and a completely sane test case
- Loading branch information
Showing
3 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import scala.util.Random | ||
import scala.language.implicitConversions | ||
|
||
val maxDepth = 30 | ||
|
||
var r = new Random() | ||
|
||
def choose[A](from: Seq[A]): A = from(r.nextInt(from.length)) | ||
|
||
abstract class Node { | ||
def produce(depth: Int): Unit | ||
|
||
def ? = new Opt(this) | ||
def *(min: Int = 0) = new Star(this, min) | ||
def ++(other: Node): Node = new Concat(this, other) | ||
def | : Node => Node = new Or(this, _) | ||
} | ||
|
||
case object IDENT extends Node { | ||
override def produce(depth: Int): Unit = { | ||
System.out.print(choose('a' to 'z')) | ||
} | ||
} | ||
|
||
case object INTEGER_LITERAL extends Node { | ||
override def produce(depth: Int): Unit = { | ||
System.out.print(choose('0' to '9')) | ||
} | ||
} | ||
|
||
case class Terminal(s: String) extends Node { | ||
override def produce(depth: Int): Unit = { | ||
System.out.print(s) | ||
} | ||
} | ||
|
||
implicit def String2Terminal(s: String): Node = new Terminal(s) | ||
|
||
case class Or(n1: Node, n2: Node) extends Node { | ||
private def flatten(n: Node): Seq[Node] = n match { | ||
case or: Or => or.flattened | ||
case _ => Seq(n) | ||
} | ||
|
||
val flattened: Seq[Node] = flatten(n1) ++ flatten(n2) | ||
|
||
override def produce(depth: Int): Unit = { | ||
choose(flattened).produce(depth+1) | ||
} | ||
} | ||
|
||
case class Concat(n1: Node, n2: Node) extends Node { | ||
override def produce(depth: Int): Unit = { | ||
n1.produce(depth+1) | ||
n2.produce(depth+1) | ||
} | ||
} | ||
|
||
case class Opt(n: Node) extends Node { | ||
override def produce(depth: Int): Unit = { | ||
if (depth < maxDepth && r.nextBoolean()) { | ||
n.produce(depth+1) | ||
} | ||
} | ||
} | ||
|
||
case class Star(n: Node, min: Int = 0) extends Node { | ||
override def produce(depth: Int): Unit = { | ||
if (depth >= maxDepth) return | ||
1 to min foreach (_ => n.produce(depth+1)) | ||
while (r.nextBoolean()) { | ||
n.produce(depth+1) | ||
} | ||
} | ||
} | ||
|
||
class Ind(n: => Node) extends Node { | ||
override def produce(depth: Int): Unit = n.produce(depth) | ||
} | ||
|
||
val Ind = new Ind(_) | ||
def OneOf(ss: Seq[String]): Node = ss map Terminal reduce Or | ||
|
||
val Program = ClassDeclaration.*(2) | ||
lazy val ClassDeclaration: Node = "class " ++ IDENT ++ " {\n" ++ (" " ++ ClassMember).*(5) ++ "\n}\n\n" | ||
lazy val ClassMember: Node = Field | Method | MainMethod | ||
lazy val Field: Node = "public " ++ Type ++ " " ++ IDENT ++ ";\n" | ||
lazy val MainMethod: Node = "public static void " ++ IDENT ++ "(String[] " ++ IDENT ++ ") " ++ Block | ||
lazy val Method: Node = "public " ++ Type ++ " " ++ IDENT ++ "(" ++ Parameters.? ++ ") " ++ Block | ||
lazy val Parameters: Node = Parameter | Parameter ++ ", " ++ Ind(Parameters) | ||
lazy val Parameter: Node = Type ++ " " ++ IDENT | ||
lazy val Type: Node = Ind(Type) ++ "[]" | BasicType | ||
lazy val BasicType: Node = "int" | "boolean" | "void" | IDENT | ||
lazy val Statement: Node = Block | EmptyStatement | IfStatement | ExpressionStatement | WhileStatement | ReturnStatement | ||
lazy val Block: Node = "{\n " ++ BlockStatement.*() ++ " \n }\n" | ||
lazy val BlockStatement: Node = Ind(Statement) | LocalVariableDeclarationStatement | ||
lazy val LocalVariableDeclarationStatement: Node = Type ++ " " ++ IDENT ++ (" = " ++ Expression).? ++ ";\n " | ||
lazy val EmptyStatement: Node = ";\n " | ||
lazy val WhileStatement: Node = "while (" ++ Expression ++ ")\n " ++ Ind(Statement) | ||
lazy val IfStatement: Node = "if (" ++ Expression ++ ")\n " ++ Ind(Statement) ++ ("else\n " ++ Ind(Statement)).? | ||
lazy val ExpressionStatement: Node = Expression ++ ";\n " | ||
lazy val ReturnStatement: Node = "return " ++ Expression.? ++ ";\n " | ||
lazy val Expression: Node = | ||
Ind(Expression) ++ " " ++ OneOf(List("!=", "*", "+", "-", "/", "<=", "<", "==", "=", ">=", ">", "%", "&&", "||")) ++ " " ++ Ind(Expression) | | ||
UnaryExpression | ||
lazy val UnaryExpression: Node = PostfixExpression | ("!" | "-") ++ Ind(UnaryExpression) | ||
lazy val PostfixExpression: Node = PrimaryExpression ++ PostfixOp.*() | ||
lazy val PostfixOp: Node = MethodInvocation | FieldAccess | ArrayAccess | ||
lazy val MethodInvocation: Node = "." ++ IDENT ++ "(" ++ Arguments ++ ")" | ||
lazy val FieldAccess: Node = "." ++ IDENT | ||
lazy val ArrayAccess: Node = "[" ++ Ind(Expression) ++ "]" | ||
lazy val Arguments: Node = (Ind(Expression) ++ (", " ++ Ind(Expression)).*()).? | ||
lazy val PrimaryExpression: Node = "null" | "false" | "true" | INTEGER_LITERAL | IDENT | IDENT ++ "(" ++ Arguments ++ ")" | "this" | "(" ++ Ind(Expression) ++ ")" | NewObjectExpression | NewArrayExpression | ||
lazy val NewObjectExpression: Node = "new " ++ IDENT ++ "()" | ||
lazy val NewArrayExpression: Node = "new " ++ BasicType ++ "[" ++ Ind(Expression) ++ "]" ++ Terminal("[]").*() | ||
|
||
Program.produce(0) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
class f { | ||
public int r; | ||
public static void m(String[] k) { | ||
{ | ||
int i; | ||
boolean w; | ||
|
||
} | ||
int h; | ||
!!null; | ||
void k = 1; | ||
boolean[] x = !true; | ||
|
||
} | ||
public boolean e; | ||
public int[] w(void a) { | ||
|
||
} | ||
public boolean b() { | ||
void k; | ||
|
||
} | ||
public static void l(String[] x) { | ||
|
||
} | ||
|
||
} | ||
|
||
class z { | ||
public static void j(String[] j) { | ||
|
||
} | ||
public static void f(String[] k) { | ||
|
||
} | ||
public boolean n(void[] e, int v) { | ||
|
||
} | ||
public static void u(String[] u) { | ||
if (-null != !8) | ||
; | ||
a[] e; | ||
if (new boolean[false].f()) | ||
while (-7.k.n()[!5 - !!!!h % new t() < false != --!new a() - -false == true + u < false || -(!!true)][null].e().u.p()) | ||
{ | ||
return ; | ||
|
||
} | ||
int s; | ||
return ; | ||
|
||
} | ||
public static void g(String[] k) { | ||
while (----!!2) | ||
{ | ||
int d = -q; | ||
{ | ||
while (new e()) | ||
{ | ||
|
||
} | ||
{ | ||
void p; | ||
|
||
} | ||
{ | ||
|
||
} | ||
|
||
} | ||
|
||
} | ||
boolean e = !-!-!true * new t() && new int[---new x[o()] >= -true / (-false) / this % !-(!4) != -this].q() < this || z(!w); | ||
|
||
} | ||
public void m; | ||
public static void p(String[] d) { | ||
return ; | ||
int z; | ||
int k = !-new boolean[!--!m() && s()[8][(!--g) / -!this == new int[2 || new int[-(-this < 1)] < 3 < 5 || !new int[-!!-new g()] + -f <= -3] >= !true < new boolean[!-null]].u][]; | ||
|
||
} | ||
public static void a(String[] e) { | ||
|
||
} | ||
|
||
} | ||
|
||
class g { | ||
public static void d(String[] k) { | ||
|
||
} | ||
public int s() { | ||
|
||
} | ||
public g[] c(boolean l, d x) { | ||
while (i()[!---b()].z.h.k()) | ||
return -this <= 4[z[d() % -(r()) + 9 || c].i]; | ||
|
||
} | ||
public static void z(String[] z) { | ||
|
||
} | ||
public w b(int[] m) { | ||
void e = false; | ||
|
||
} | ||
|
||
} | ||
|
||
class i { | ||
public int h; | ||
public boolean y; | ||
public int d(k v, void[][][] x) { | ||
a v; | ||
{ | ||
!a(null, this, --null)[!!true < 8].i.o().y[new int[new boolean[-n()] % 9 % --k()] % true == -j()]; | ||
|
||
} | ||
|
||
} | ||
public void g; | ||
public boolean[] u; | ||
|
||
} | ||
|
||
class u { | ||
public void[] e(k i) { | ||
|
||
} | ||
public static void p(String[] a) { | ||
null; | ||
|
||
} | ||
public static void z(String[] x) { | ||
|
||
} | ||
public static void e(String[] w) { | ||
|
||
} | ||
public void y() { | ||
while ((!(2).u() = null[v() == b() + (this) * new r() && !--!(false == null) = !!new int[this != null > !m() / !w] = !6 <= false >= 0 + true * (3) = !-!6 = new c()] >= new int[l][][])) | ||
; | ||
|
||
} | ||
|
||
} | ||
|
||
class c { | ||
public static void e(String[] i) { | ||
|
||
} | ||
public static void l(String[] b) { | ||
|
||
} | ||
public void s(v v, void[] r, boolean[] m, k[][] j) { | ||
|
||
} | ||
public static void z(String[] c) { | ||
void w; | ||
|
||
} | ||
public static void t(String[] a) { | ||
{ | ||
|
||
} | ||
|
||
} | ||
|
||
} | ||
|
||
class r { | ||
public void b() { | ||
j c; | ||
|
||
} | ||
public int s(void z) { | ||
|
||
} | ||
public y z; | ||
public static void v(String[] q) { | ||
void r = (new w() = true.j); | ||
|
||
} | ||
public static void b(String[] d) { | ||
|
||
} | ||
|
||
} | ||
|