<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>priv/peg_includes.erl</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,4 @@
 ebin/*
 ebin_tests/*
-extra/*.beam
\ No newline at end of file
+extra/*.beam
+*#*
\ No newline at end of file</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -10,26 +10,24 @@ tests: clean src_src src_tests
 ebin:
 	mkdir ebin
 
+priv:
+	mkdir priv
+
 ebin_tests:
 	mkdir ebin_tests
 
-ebin_tests/examples:
-	mkdir ebin_tests/examples
-
-special: src/herml_scan.erl src/herml_parse.erl
+priv/peg_includes.erl: priv src/peg.erl
+	cat src/peg.erl | grep -v &quot;^%&quot; | grep -v &quot;^-&quot; &gt; priv/peg_includes.erl
 
-src_src: ebin src/neotoma.app
+src_src: ebin src/neotoma.app priv/peg_includes.erl
 	cd src;erl -pz ../ebin -make
 
-src_tests: ebin_tests test_examples
+src_tests: ebin_tests
 	cd tests;erl -pz ../ebin -make
 
 src/neotoma.app: ebin
 	cp src/neotoma.app ebin
 
-test_examples: ebin_tests/examples
-	cd tests/examples;erl -pz ../../ebin -make
-
 clean:
 	rm -rf ebin
 	rm -rf ebin_tests</diff>
      <filename>Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,23 +1,205 @@
 -module(csv).
 -export([parse/1,file/1]).
--include_lib(&quot;neotoma/include/peg.hrl&quot;).
+-compile(nowarn_unused_function).
 
-rule(rows) -&gt;
-  peg:choose([peg:seq([peg:label('head', fun row/2), peg:label('tail', peg:zero_or_more(peg:seq([fun crlf/2, fun row/2])))]), peg:string(&quot;&quot;)]);
+file(Filename) -&gt; {ok, Bin} = file:read_file(Filename), parse(binary_to_list(Bin)).
 
-rule(row) -&gt;
-  peg:choose([peg:seq([peg:label('head', fun field/2), peg:label('tail', peg:zero_or_more(peg:seq([fun field_sep/2, fun field/2])))]), peg:string(&quot;&quot;)]);
+parse(Input) -&gt;
+  setup_memo(csv),
+  Result = case rows(Input,{{line,1},{column,1}}) of
+             {AST, [], _Index} -&gt; AST;
+             Any -&gt; Any
+           end,
+  release_memo(), Result.
 
-rule(field) -&gt;
-  peg:choose([fun quoted_field/2, peg:zero_or_more(peg:seq([peg:not_(peg:choose([fun field_sep/2, fun crlf/2])), peg:anything()]))]);
+'rows'(Input, Index) -&gt;
+  p(Input, Index, 'rows', fun(I,D) -&gt; (p_choose([p_seq([p_label('head', fun 'row'/2), p_label('tail', p_zero_or_more(p_seq([fun 'crlf'/2, fun 'row'/2])))]), p_string(&quot;&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('rows', Node, Idx) end).
 
-rule(quoted_field) -&gt;
-  peg:seq([peg:string(&quot;\&quot;&quot;), peg:label('string', peg:zero_or_more(peg:choose([peg:string(&quot;\&quot;\&quot;&quot;), peg:seq([peg:not_(peg:string(&quot;\&quot;&quot;)), peg:anything()])]))), peg:string(&quot;\&quot;&quot;)]);
+'row'(Input, Index) -&gt;
+  p(Input, Index, 'row', fun(I,D) -&gt; (p_choose([p_seq([p_label('head', fun 'field'/2), p_label('tail', p_zero_or_more(p_seq([fun 'field_sep'/2, fun 'field'/2])))]), p_string(&quot;&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('row', Node, Idx) end).
 
-rule(field_sep) -&gt;
-  peg:string(&quot;,&quot;);
+'field'(Input, Index) -&gt;
+  p(Input, Index, 'field', fun(I,D) -&gt; (p_choose([fun 'quoted_field'/2, p_zero_or_more(p_seq([p_not(p_choose([fun 'field_sep'/2, fun 'crlf'/2])), p_anything()]))]))(I,D) end, fun(Node, Idx) -&gt; transform('field', Node, Idx) end).
 
-rule(crlf) -&gt;
-  peg:choose([peg:string(&quot;\r\n&quot;), peg:string(&quot;\n&quot;)]).
+'quoted_field'(Input, Index) -&gt;
+  p(Input, Index, 'quoted_field', fun(I,D) -&gt; (p_seq([p_string(&quot;\&quot;&quot;), p_label('string', p_zero_or_more(p_choose([p_string(&quot;\&quot;\&quot;&quot;), p_seq([p_not(p_string(&quot;\&quot;&quot;)), p_anything()])]))), p_string(&quot;\&quot;&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('quoted_field', Node, Idx) end).
 
-transform(Symbol,Node,Index) -&gt; csv_gen:transform(Symbol, Node).
+'field_sep'(Input, Index) -&gt;
+  p(Input, Index, 'field_sep', fun(I,D) -&gt; (p_string(&quot;,&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('field_sep', Node, Idx) end).
+
+'crlf'(Input, Index) -&gt;
+  p(Input, Index, 'crlf', fun(I,D) -&gt; (p_choose([p_string(&quot;\r\n&quot;), p_string(&quot;\n&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('crlf', Node, Idx) end).
+
+transform(Symbol,Node,Index) -&gt; csv_gen:transform(Symbol, Node, Index).
+
+
+
+
+
+p(Inp, Index, Name, ParseFun) -&gt;
+  p(Inp, Index, Name, ParseFun, fun(N, _Idx) -&gt; N end).
+
+p(Inp, StartIndex, Name, ParseFun, TransformFun) -&gt;
+  % Grab the memo table from ets
+  Memo = get_memo(StartIndex),
+  % See if the current reduction is memoized
+  case dict:find(Name, Memo) of
+    % If it is, return the result
+    {ok, Result} -&gt; Result;
+    % If not, attempt to parse
+    _ -&gt;
+      case ParseFun(Inp, StartIndex) of
+        % If it fails, memoize the failure
+        {fail,_} = Failure -&gt;
+          memoize(StartIndex, dict:store(Name, Failure, Memo)),
+          Failure;
+        % If it passes, transform and memoize the result.
+        {Result, InpRem, NewIndex} -&gt;
+          Transformed = TransformFun(Result, StartIndex),
+          memoize(StartIndex, dict:store(Name, {Transformed, InpRem, NewIndex}, Memo)),
+          {Transformed, InpRem, NewIndex}
+      end
+  end.
+
+setup_memo(Name) -&gt;
+  TID = ets:new(Name, [set]),
+  put(ets_table, TID).
+
+release_memo() -&gt;
+  ets:delete(get(ets_table)),
+  erase(ets_table).
+
+memoize(Position, Struct) -&gt;
+  ets:insert(get(ets_table), {Position, Struct}).
+
+get_memo(Position) -&gt;
+  case ets:lookup(get(ets_table), Position) of
+    [] -&gt; dict:new();
+    [{Position, Dict}] -&gt; Dict
+  end.
+
+p_eof() -&gt;
+  fun([], Index) -&gt; {eof, [], Index};
+     (_, Index) -&gt; {fail, {expected, eof, Index}} end.
+
+p_optional(P) -&gt;
+  fun(Input, Index) -&gt;
+      case P(Input, Index) of
+        {fail,_} -&gt; {[], Input, Index};
+        {_, _, _} = Success -&gt; Success
+      end
+  end.
+
+p_not(P) -&gt;
+  fun(Input, Index)-&gt;
+      case P(Input,Index) of
+        {fail,_} -&gt;
+          {[], Input, Index};
+        {Result, _, _} -&gt; {fail, {expected, {no_match, Result},Index}}
+      end
+  end.
+
+p_assert(P) -&gt;
+  fun(Input,Index) -&gt;
+      case P(Input,Index) of
+        {fail,_} = Failure-&gt; Failure;
+        _ -&gt; {[], Input, Index}
+      end
+  end.
+
+p_and(P) -&gt;
+  p_seq(P).
+
+p_seq(P) -&gt;
+  fun(Input, Index) -&gt;
+      p_all(P, Input, Index, [])
+  end.
+
+p_all([], Inp, Index, Accum ) -&gt; {lists:reverse( Accum ), Inp, Index};
+p_all([P|Parsers], Inp, Index, Accum) -&gt;
+  case P(Inp, Index) of
+    {fail, _} = Failure -&gt; Failure;
+    {Result, InpRem, NewIndex} -&gt; p_all(Parsers, InpRem, NewIndex, [Result|Accum])
+  end.
+
+p_choose(Parsers) -&gt;
+  fun(Input, Index) -&gt;
+      p_attempt(Parsers, Input, Index, none)
+  end.
+
+p_attempt([], _Input, _Index, Failure) -&gt; Failure;
+p_attempt([P|Parsers], Input, Index, FirstFailure)-&gt;
+  case P(Input, Index) of
+    {fail, _} = Failure -&gt;
+      case FirstFailure of
+        none -&gt; p_attempt(Parsers, Input, Index, Failure);
+        _ -&gt; p_attempt(Parsers, Input, Index, FirstFailure)
+      end;
+    Result -&gt; Result
+  end.
+
+p_zero_or_more(P) -&gt;
+  fun(Input, Index) -&gt;
+      p_scan(P, Input, Index, [])
+  end.
+
+p_one_or_more(P) -&gt;
+  fun(Input, Index)-&gt;
+      Result = p_scan(P, Input, Index, []),
+      case Result of
+        {[_|_], _, _} -&gt;
+          Result;
+        _ -&gt;
+          {fail, {expected, Failure, _}} = P(Input,Index),
+          {fail, {expected, {at_least_one, Failure}, Index}}
+      end
+  end.
+
+p_label(Tag, P) -&gt;
+  fun(Input, Index) -&gt;
+      case P(Input, Index) of
+        {fail,_} = Failure -&gt;
+           Failure;
+        {Result, InpRem, NewIndex} -&gt;
+          {{Tag, Result}, InpRem, NewIndex}
+      end
+  end.
+
+p_scan(_, [], Index, Accum) -&gt; {lists:reverse( Accum ), [], Index};
+p_scan(P, Inp, Index, Accum) -&gt;
+  case P(Inp, Index) of
+    {fail,_} -&gt; {lists:reverse(Accum), Inp, Index};
+    {Result, InpRem, NewIndex} -&gt; p_scan(P, InpRem, NewIndex, [Result | Accum])
+  end.
+
+p_string(S) -&gt;
+  fun(Input, Index) -&gt;
+      case lists:prefix(S, Input) of
+        true -&gt; {S, lists:sublist(Input, length(S)+1, length(Input)), p_advance_index(S,Index)};
+        _ -&gt; {fail, {expected, {string, S}, Index}}
+      end
+  end.
+
+p_anything() -&gt;
+  fun([], Index) -&gt; {fail, {expected, any_character, Index}};
+     ([H|T], Index) -&gt; {H, T, p_advance_index(H, Index)}
+  end.
+
+p_charclass(Class) -&gt;
+  fun(Inp, Index) -&gt;
+     {ok, RE} = re:compile(&quot;^&quot;++Class),
+      case re:run(Inp, RE) of
+        {match, _} -&gt;
+          {hd(Inp), tl(Inp), p_advance_index(hd(Inp), Index)};
+        _ -&gt; {fail,{expected, {character_class, Class}, Index}}
+      end
+  end.
+
+p_advance_index(MatchedInput, Index) when is_list(MatchedInput) -&gt; % strings
+  lists:foldl(fun p_advance_index/2, Index, MatchedInput);
+p_advance_index(MatchedInput, Index) when is_integer(MatchedInput) -&gt; % single characters
+  {{line, Line}, {column, Col}} = Index,
+  case MatchedInput of
+    $\n -&gt; {{line, Line+1}, {column, 1}};
+    _ -&gt; {{line, Line}, {column, Col+1}}
+  end.</diff>
      <filename>extra/csv.erl</filename>
    </modified>
    <modified>
      <diff>@@ -1,53 +1,235 @@
 -module(json).
 -export([parse/1,file/1]).
--include_lib(&quot;neotoma/include/peg.hrl&quot;).
+-compile(nowarn_unused_function).
 
-rule(json_value) -&gt;
-  peg:seq([peg:optional(fun space/2), peg:choose([fun object/2, fun array/2, fun string/2, fun number/2, fun true/2, fun false/2, fun null/2]), peg:optional(fun space/2)]);
+file(Filename) -&gt; {ok, Bin} = file:read_file(Filename), parse(binary_to_list(Bin)).
 
-rule(object) -&gt;
-  peg:choose([peg:seq([peg:string(&quot;{&quot;), peg:optional(fun space/2), peg:label('head', fun pair/2), peg:label('tail', peg:zero_or_more(peg:seq([peg:optional(fun space/2), peg:string(&quot;,&quot;), peg:optional(fun space/2), fun pair/2]))), peg:optional(fun space/2), peg:string(&quot;}&quot;)]), peg:seq([peg:string(&quot;{&quot;), peg:optional(fun space/2), peg:string(&quot;}&quot;)])]);
+parse(Input) -&gt;
+  setup_memo(json),
+  Result = case json_value(Input,{{line,1},{column,1}}) of
+             {AST, [], _Index} -&gt; AST;
+             Any -&gt; Any
+           end,
+  release_memo(), Result.
 
-rule(pair) -&gt;
-  peg:seq([peg:optional(fun space/2), peg:label('key', fun string/2), peg:optional(fun space/2), peg:string(&quot;:&quot;), peg:optional(fun space/2), peg:label('value', fun json_value/2), peg:optional(fun space/2)]);
+'json_value'(Input, Index) -&gt;
+  p(Input, Index, 'json_value', fun(I,D) -&gt; (p_seq([p_optional(fun 'space'/2), p_choose([fun 'object'/2, fun 'array'/2, fun 'string'/2, fun 'number'/2, fun 'true'/2, fun 'false'/2, fun 'null'/2]), p_optional(fun 'space'/2)]))(I,D) end, fun(Node, Idx) -&gt; transform('json_value', Node, Idx) end).
 
-rule(array) -&gt;
-  peg:choose([peg:seq([peg:string(&quot;[&quot;), peg:optional(fun space/2), peg:label('head', fun json_value/2), peg:label('tail', peg:zero_or_more(peg:seq([peg:optional(fun space/2), peg:string(&quot;,&quot;), peg:optional(fun space/2), fun json_value/2]))), peg:optional(fun space/2), peg:string(&quot;]&quot;)]), peg:seq([peg:string(&quot;[&quot;), peg:optional(fun space/2), peg:string(&quot;]&quot;)])]);
+'object'(Input, Index) -&gt;
+  p(Input, Index, 'object', fun(I,D) -&gt; (p_choose([p_seq([p_string(&quot;{&quot;), p_optional(fun 'space'/2), p_label('head', fun 'pair'/2), p_label('tail', p_zero_or_more(p_seq([p_optional(fun 'space'/2), p_string(&quot;,&quot;), p_optional(fun 'space'/2), fun 'pair'/2]))), p_optional(fun 'space'/2), p_string(&quot;}&quot;)]), p_seq([p_string(&quot;{&quot;), p_optional(fun 'space'/2), p_string(&quot;}&quot;)])]))(I,D) end, fun(Node, Idx) -&gt; transform('object', Node, Idx) end).
 
-rule(string) -&gt;
-  peg:seq([peg:string(&quot;\&quot;&quot;), peg:label('chars', peg:zero_or_more(peg:seq([peg:not_(peg:string(&quot;\&quot;&quot;)), peg:choose([peg:string(&quot;\\\\&quot;), peg:string(&quot;\\\&quot;&quot;), peg:anything()])]))), peg:string(&quot;\&quot;&quot;)]);
+'pair'(Input, Index) -&gt;
+  p(Input, Index, 'pair', fun(I,D) -&gt; (p_seq([p_optional(fun 'space'/2), p_label('key', fun 'string'/2), p_optional(fun 'space'/2), p_string(&quot;:&quot;), p_optional(fun 'space'/2), p_label('value', fun 'json_value'/2), p_optional(fun 'space'/2)]))(I,D) end, fun(Node, Idx) -&gt; transform('pair', Node, Idx) end).
 
-rule(number) -&gt;
-  peg:seq([fun int/2, peg:optional(fun frac/2), peg:optional(fun exp/2)]);
+'array'(Input, Index) -&gt;
+  p(Input, Index, 'array', fun(I,D) -&gt; (p_choose([p_seq([p_string(&quot;[&quot;), p_optional(fun 'space'/2), p_label('head', fun 'json_value'/2), p_label('tail', p_zero_or_more(p_seq([p_optional(fun 'space'/2), p_string(&quot;,&quot;), p_optional(fun 'space'/2), fun 'json_value'/2]))), p_optional(fun 'space'/2), p_string(&quot;]&quot;)]), p_seq([p_string(&quot;[&quot;), p_optional(fun 'space'/2), p_string(&quot;]&quot;)])]))(I,D) end, fun(Node, Idx) -&gt; transform('array', Node, Idx) end).
 
-rule(int) -&gt;
-  peg:choose([peg:seq([peg:optional(peg:string(&quot;-&quot;)), peg:seq([fun non_zero_digit/2, peg:one_or_more(fun digit/2)])]), fun digit/2]);
+'string'(Input, Index) -&gt;
+  p(Input, Index, 'string', fun(I,D) -&gt; (p_seq([p_string(&quot;\&quot;&quot;), p_label('chars', p_zero_or_more(p_seq([p_not(p_string(&quot;\&quot;&quot;)), p_choose([p_string(&quot;\\\\&quot;), p_string(&quot;\\\&quot;&quot;), p_anything()])]))), p_string(&quot;\&quot;&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('string', Node, Idx) end).
 
-rule(frac) -&gt;
-  peg:seq([peg:string(&quot;.&quot;), peg:one_or_more(fun digit/2)]);
+'number'(Input, Index) -&gt;
+  p(Input, Index, 'number', fun(I,D) -&gt; (p_seq([fun 'int'/2, p_optional(fun 'frac'/2), p_optional(fun 'exp'/2)]))(I,D) end, fun(Node, Idx) -&gt; transform('number', Node, Idx) end).
 
-rule(exp) -&gt;
-  peg:seq([fun e/2, peg:one_or_more(fun digit/2)]);
+'int'(Input, Index) -&gt;
+  p(Input, Index, 'int', fun(I,D) -&gt; (p_choose([p_seq([p_optional(p_string(&quot;-&quot;)), p_seq([fun 'non_zero_digit'/2, p_one_or_more(fun 'digit'/2)])]), fun 'digit'/2]))(I,D) end, fun(Node, Idx) -&gt; transform('int', Node, Idx) end).
 
-rule(e) -&gt;
-  peg:seq([peg:charclass(&quot;[eE]&quot;), peg:optional(peg:choose([peg:string(&quot;+&quot;), peg:string(&quot;-&quot;)]))]);
+'frac'(Input, Index) -&gt;
+  p(Input, Index, 'frac', fun(I,D) -&gt; (p_seq([p_string(&quot;.&quot;), p_one_or_more(fun 'digit'/2)]))(I,D) end, fun(Node, Idx) -&gt; transform('frac', Node, Idx) end).
+
+'exp'(Input, Index) -&gt;
+  p(Input, Index, 'exp', fun(I,D) -&gt; (p_seq([fun 'e'/2, p_one_or_more(fun 'digit'/2)]))(I,D) end, fun(Node, Idx) -&gt; transform('exp', Node, Idx) end).
 
-rule(non_zero_digit) -&gt;
-  peg:charclass(&quot;[1-9]&quot;);
+'e'(Input, Index) -&gt;
+  p(Input, Index, 'e', fun(I,D) -&gt; (p_seq([p_charclass(&quot;[eE]&quot;), p_optional(p_choose([p_string(&quot;+&quot;), p_string(&quot;-&quot;)]))]))(I,D) end, fun(Node, Idx) -&gt; transform('e', Node, Idx) end).
 
-rule(digit) -&gt;
-  peg:charclass(&quot;[0-9]&quot;);
+'non_zero_digit'(Input, Index) -&gt;
+  p(Input, Index, 'non_zero_digit', fun(I,D) -&gt; (p_charclass(&quot;[1-9]&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('non_zero_digit', Node, Idx) end).
 
-rule(true) -&gt;
-  peg:string(&quot;true&quot;);
-
-rule(false) -&gt;
-  peg:string(&quot;false&quot;);
-
-rule(null) -&gt;
-  peg:string(&quot;null&quot;);
-
-rule(space) -&gt;
-  peg:zero_or_more(peg:charclass(&quot;[ \t\n\s\r]&quot;)).
-
-transform(Symbol,Node) -&gt; json_tree:transform(Symbol, Node).
\ No newline at end of file
+'digit'(Input, Index) -&gt;
+  p(Input, Index, 'digit', fun(I,D) -&gt; (p_charclass(&quot;[0-9]&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('digit', Node, Idx) end).
+
+'true'(Input, Index) -&gt;
+  p(Input, Index, 'true', fun(I,D) -&gt; (p_string(&quot;true&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('true', Node, Idx) end).
+
+'false'(Input, Index) -&gt;
+  p(Input, Index, 'false', fun(I,D) -&gt; (p_string(&quot;false&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('false', Node, Idx) end).
+
+'null'(Input, Index) -&gt;
+  p(Input, Index, 'null', fun(I,D) -&gt; (p_string(&quot;null&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('null', Node, Idx) end).
+
+'space'(Input, Index) -&gt;
+  p(Input, Index, 'space', fun(I,D) -&gt; (p_zero_or_more(p_charclass(&quot;[ \t\n\s\r]&quot;)))(I,D) end, fun(Node, Idx) -&gt; transform('space', Node, Idx) end).
+
+transform(Symbol,Node,Index) -&gt; json_tree:transform(Symbol, Node, Index).
+
+
+
+
+
+p(Inp, Index, Name, ParseFun) -&gt;
+  p(Inp, Index, Name, ParseFun, fun(N, _Idx) -&gt; N end).
+
+p(Inp, StartIndex, Name, ParseFun, TransformFun) -&gt;
+  % Grab the memo table from ets
+  Memo = get_memo(StartIndex),
+  % See if the current reduction is memoized
+  case dict:find(Name, Memo) of
+    % If it is, return the result
+    {ok, Result} -&gt; Result;
+    % If not, attempt to parse
+    _ -&gt;
+      case ParseFun(Inp, StartIndex) of
+        % If it fails, memoize the failure
+        {fail,_} = Failure -&gt;
+          memoize(StartIndex, dict:store(Name, Failure, Memo)),
+          Failure;
+        % If it passes, transform and memoize the result.
+        {Result, InpRem, NewIndex} -&gt;
+          Transformed = TransformFun(Result, StartIndex),
+          memoize(StartIndex, dict:store(Name, {Transformed, InpRem, NewIndex}, Memo)),
+          {Transformed, InpRem, NewIndex}
+      end
+  end.
+
+setup_memo(Name) -&gt;
+  TID = ets:new(Name, [set]),
+  put(ets_table, TID).
+
+release_memo() -&gt;
+  ets:delete(get(ets_table)),
+  erase(ets_table).
+
+memoize(Position, Struct) -&gt;
+  ets:insert(get(ets_table), {Position, Struct}).
+
+get_memo(Position) -&gt;
+  case ets:lookup(get(ets_table), Position) of
+    [] -&gt; dict:new();
+    [{Position, Dict}] -&gt; Dict
+  end.
+
+p_eof() -&gt;
+  fun([], Index) -&gt; {eof, [], Index};
+     (_, Index) -&gt; {fail, {expected, eof, Index}} end.
+
+p_optional(P) -&gt;
+  fun(Input, Index) -&gt;
+      case P(Input, Index) of
+        {fail,_} -&gt; {[], Input, Index};
+        {_, _, _} = Success -&gt; Success
+      end
+  end.
+
+p_not(P) -&gt;
+  fun(Input, Index)-&gt;
+      case P(Input,Index) of
+        {fail,_} -&gt;
+          {[], Input, Index};
+        {Result, _, _} -&gt; {fail, {expected, {no_match, Result},Index}}
+      end
+  end.
+
+p_assert(P) -&gt;
+  fun(Input,Index) -&gt;
+      case P(Input,Index) of
+        {fail,_} = Failure-&gt; Failure;
+        _ -&gt; {[], Input, Index}
+      end
+  end.
+
+p_and(P) -&gt;
+  p_seq(P).
+
+p_seq(P) -&gt;
+  fun(Input, Index) -&gt;
+      p_all(P, Input, Index, [])
+  end.
+
+p_all([], Inp, Index, Accum ) -&gt; {lists:reverse( Accum ), Inp, Index};
+p_all([P|Parsers], Inp, Index, Accum) -&gt;
+  case P(Inp, Index) of
+    {fail, _} = Failure -&gt; Failure;
+    {Result, InpRem, NewIndex} -&gt; p_all(Parsers, InpRem, NewIndex, [Result|Accum])
+  end.
+
+p_choose(Parsers) -&gt;
+  fun(Input, Index) -&gt;
+      p_attempt(Parsers, Input, Index, none)
+  end.
+
+p_attempt([], _Input, _Index, Failure) -&gt; Failure;
+p_attempt([P|Parsers], Input, Index, FirstFailure)-&gt;
+  case P(Input, Index) of
+    {fail, _} = Failure -&gt;
+      case FirstFailure of
+        none -&gt; p_attempt(Parsers, Input, Index, Failure);
+        _ -&gt; p_attempt(Parsers, Input, Index, FirstFailure)
+      end;
+    Result -&gt; Result
+  end.
+
+p_zero_or_more(P) -&gt;
+  fun(Input, Index) -&gt;
+      p_scan(P, Input, Index, [])
+  end.
+
+p_one_or_more(P) -&gt;
+  fun(Input, Index)-&gt;
+      Result = p_scan(P, Input, Index, []),
+      case Result of
+        {[_|_], _, _} -&gt;
+          Result;
+        _ -&gt;
+          {fail, {expected, Failure, _}} = P(Input,Index),
+          {fail, {expected, {at_least_one, Failure}, Index}}
+      end
+  end.
+
+p_label(Tag, P) -&gt;
+  fun(Input, Index) -&gt;
+      case P(Input, Index) of
+        {fail,_} = Failure -&gt;
+           Failure;
+        {Result, InpRem, NewIndex} -&gt;
+          {{Tag, Result}, InpRem, NewIndex}
+      end
+  end.
+
+p_scan(_, [], Index, Accum) -&gt; {lists:reverse( Accum ), [], Index};
+p_scan(P, Inp, Index, Accum) -&gt;
+  case P(Inp, Index) of
+    {fail,_} -&gt; {lists:reverse(Accum), Inp, Index};
+    {Result, InpRem, NewIndex} -&gt; p_scan(P, InpRem, NewIndex, [Result | Accum])
+  end.
+
+p_string(S) -&gt;
+  fun(Input, Index) -&gt;
+      case lists:prefix(S, Input) of
+        true -&gt; {S, lists:sublist(Input, length(S)+1, length(Input)), p_advance_index(S,Index)};
+        _ -&gt; {fail, {expected, {string, S}, Index}}
+      end
+  end.
+
+p_anything() -&gt;
+  fun([], Index) -&gt; {fail, {expected, any_character, Index}};
+     ([H|T], Index) -&gt; {H, T, p_advance_index(H, Index)}
+  end.
+
+p_charclass(Class) -&gt;
+  fun(Inp, Index) -&gt;
+     {ok, RE} = re:compile(&quot;^&quot;++Class),
+      case re:run(Inp, RE) of
+        {match, _} -&gt;
+          {hd(Inp), tl(Inp), p_advance_index(hd(Inp), Index)};
+        _ -&gt; {fail,{expected, {character_class, Class}, Index}}
+      end
+  end.
+
+p_advance_index(MatchedInput, Index) when is_list(MatchedInput) -&gt; % strings
+  lists:foldl(fun p_advance_index/2, Index, MatchedInput);
+p_advance_index(MatchedInput, Index) when is_integer(MatchedInput) -&gt; % single characters
+  {{line, Line}, {column, Col}} = Index,
+  case MatchedInput of
+    $\n -&gt; {{line, Line+1}, {column, 1}};
+    _ -&gt; {{line, Line}, {column, Col+1}}
+  end.</diff>
      <filename>extra/json.erl</filename>
    </modified>
    <modified>
      <diff>@@ -18,7 +18,7 @@ transform(array, Node, _Idx) -&gt;
   Rest = [lists:nth(4, I) || I &lt;- proplists:get_value(tail, Node)],
   [Head|Rest];
 transform(number, [Int, [],[]], _Idx) -&gt;
-  list_to_integer(lists:flatten(Int));
+  list_to_integer(lists:flatten([Int]));
 transform(number, [Int, Frac, []], _Idx) -&gt;
   list_to_float(lists:flatten([Int, Frac]));
 transform(number, [Int, [], Exp], Idx) -&gt;</diff>
      <filename>extra/json_tree.erl</filename>
    </modified>
    <modified>
      <diff>@@ -1,2 +1,2 @@
-{[peg_transform, peg_itransform, peg, peg_gen, peg_meta, peg_meta_gen],
+{[peg, peg_gen, peg_meta, peg_meta_gen],
 	[{outdir, &quot;../ebin&quot;}, {i, &quot;../../&quot;}, debug_info]}.</diff>
      <filename>src/Emakefile</filename>
    </modified>
    <modified>
      <diff>@@ -13,13 +13,7 @@
 -export([p/4, p/5]).
 -export([setup_memo/1, release_memo/0]).
 
--export([eof/0, optional/1,
-         not_/1, assert/1, seq/1,
-         and_/1, choose/1,
-         zero_or_more/1, one_or_more/1,
-         label/2,
-         string/1, anything/0,
-         charclass/1]).
+-export([p_eof/0, p_optional/1, p_not/1, p_assert/1, p_seq/1, p_and/1, p_choose/1, p_zero_or_more/1, p_one_or_more/1, p_label/2, p_string/1, p_anything/0, p_charclass/1]).
 
 %% @doc Memoizing parsing function wrapper.  This form does not transform the result of a successful parse.
 %% @see p/5.
@@ -71,14 +65,14 @@ get_memo(Position) -&gt;
   end.
 
 %% @doc Generates a parse function that matches the end of the buffer.
-%% @spec eof() -&gt; parse_fun()
-eof() -&gt;
+%% @spec p_eof() -&gt; parse_fun()
+p_eof() -&gt;
   fun([], Index) -&gt; {eof, [], Index};
      (_, Index) -&gt; {fail, {expected, eof, Index}} end.
 
 %% @doc Generates a parse function that treats the passed parse function as optional.
-%% @spec optional(parse_fun()) -&gt; parse_fun()
-optional(P) -&gt;
+%% @spec p_optional(parse_fun()) -&gt; parse_fun()
+p_optional(P) -&gt;
   fun(Input, Index) -&gt;
       case P(Input, Index) of
         {fail,_} -&gt; {[], Input, Index};
@@ -87,8 +81,8 @@ optional(P) -&gt;
   end.
 
 %% @doc Generates a parse function that ensures the passed function will not match without consuming any input, that is, negative lookahead.
-%% @spec not_(parse_fun()) -&gt; parse_fun()
-not_(P) -&gt;
+%% @spec p_not(parse_fun()) -&gt; parse_fun()
+p_not(P) -&gt;
   fun(Input, Index)-&gt;
       case P(Input,Index) of
         {fail,_} -&gt;
@@ -98,8 +92,8 @@ not_(P) -&gt;
   end.
 
 %% @doc Generates a parse function that ensures the passed function will match, without consuming any input, that is, positive lookahead.
-%% @spec assert(parse_fun()) -&gt; parse_fun()
-assert(P) -&gt;
+%% @spec p_assert(parse_fun()) -&gt; parse_fun()
+p_assert(P) -&gt;
   fun(Input,Index) -&gt;
       case P(Input,Index) of
         {fail,_} = Failure-&gt; Failure;
@@ -107,55 +101,55 @@ assert(P) -&gt;
       end
   end.
 
-%% @doc Alias for seq/1.
-%% @see seq/1.
-and_(P) -&gt;
-  seq(P).
+%% @doc Alias for p_seq/1.
+%% @see p_seq/1.
+p_and(P) -&gt;
+  p_seq(P).
 
 %% @doc Generates a parse function that will match the passed parse functions in order.
-%% @spec seq([parse_fun()]) -&gt; parse_fun()
-seq(P) -&gt;
+%% @spec p_seq([parse_fun()]) -&gt; parse_fun()
+p_seq(P) -&gt;
   fun(Input, Index) -&gt;
-      all(P, Input, Index, [])
+      p_all(P, Input, Index, [])
   end.
 
-all([], Inp, Index, Accum ) -&gt; {lists:reverse( Accum ), Inp, Index};
-all([P|Parsers], Inp, Index, Accum) -&gt;
+p_all([], Inp, Index, Accum ) -&gt; {lists:reverse( Accum ), Inp, Index};
+p_all([P|Parsers], Inp, Index, Accum) -&gt;
   case P(Inp, Index) of
     {fail, _} = Failure -&gt; Failure;
-    {Result, InpRem, NewIndex} -&gt; all(Parsers, InpRem, NewIndex, [Result|Accum])
+    {Result, InpRem, NewIndex} -&gt; p_all(Parsers, InpRem, NewIndex, [Result|Accum])
   end.
 
 %% @doc Generates a parse function that will match at least one of the passed parse functions (ordered choice).
 %% @spec choose([parse_fun()]) -&gt; parse_fun()
-choose(Parsers) -&gt;
+p_choose(Parsers) -&gt;
   fun(Input, Index) -&gt;
-      attempt(Parsers, Input, Index, none)
+      p_attempt(Parsers, Input, Index, none)
   end.
 
-attempt([], _Input, _Index, Failure) -&gt; Failure;
-attempt([P|Parsers], Input, Index, FirstFailure)-&gt;
+p_attempt([], _Input, _Index, Failure) -&gt; Failure;
+p_attempt([P|Parsers], Input, Index, FirstFailure)-&gt;
   case P(Input, Index) of
     {fail, _} = Failure -&gt;
       case FirstFailure of
-        none -&gt; attempt(Parsers, Input, Index, Failure);
-        _ -&gt; attempt(Parsers, Input, Index, FirstFailure)
+        none -&gt; p_attempt(Parsers, Input, Index, Failure);
+        _ -&gt; p_attempt(Parsers, Input, Index, FirstFailure)
       end;
     Result -&gt; Result
   end.
 
 %% @doc Generates a parse function that will match any number of the passed parse function in sequence (optional greedy repetition).
-%% @spec zero_or_more(parse_fun()) -&gt; parse_fun()
-zero_or_more(P) -&gt;
+%% @spec p_zero_or_more(parse_fun()) -&gt; parse_fun()
+p_zero_or_more(P) -&gt;
   fun(Input, Index) -&gt;
-      scan(P, Input, Index, [])
+      p_scan(P, Input, Index, [])
   end.
 
 %% @doc Generates a parse function that will match at least one of the passed parse function in sequence (greedy repetition).
-%% @spec one_or_more(parse_fun()) -&gt; parse_fun()
-one_or_more(P) -&gt;
+%% @spec p_one_or_more(parse_fun()) -&gt; parse_fun()
+p_one_or_more(P) -&gt;
   fun(Input, Index)-&gt;
-      Result = scan(P, Input, Index, []),
+      Result = p_scan(P, Input, Index, []),
       case Result of
         {[_|_], _, _} -&gt;
           Result;
@@ -166,8 +160,8 @@ one_or_more(P) -&gt;
   end.
 
 %% @doc Generates a parse function that will tag the result of the passed parse function with a label when it succeeds.  The tagged result will be a 2-tuple of {Tag, Result}.
-%% @spec label(Tag::anything(), P::parse_fun()) -&gt; parse_fun()
-label(Tag, P) -&gt;
+%% @spec p_label(Tag::anything(), P::parse_fun()) -&gt; parse_fun()
+p_label(Tag, P) -&gt;
   fun(Input, Index) -&gt;
       case P(Input, Index) of
         {fail,_} = Failure -&gt;
@@ -177,28 +171,28 @@ label(Tag, P) -&gt;
       end
   end.
 
-scan(_, [], Index, Accum) -&gt; {lists:reverse( Accum ), [], Index};
-scan(P, Inp, Index, Accum) -&gt;
+p_scan(_, [], Index, Accum) -&gt; {lists:reverse( Accum ), [], Index};
+p_scan(P, Inp, Index, Accum) -&gt;
   case P(Inp, Index) of
     {fail,_} -&gt; {lists:reverse(Accum), Inp, Index};
-    {Result, InpRem, NewIndex} -&gt; scan(P, InpRem, NewIndex, [Result | Accum])
+    {Result, InpRem, NewIndex} -&gt; p_scan(P, InpRem, NewIndex, [Result | Accum])
   end.
 
 %% @doc Generates a parse function that will match the passed string on the head of the buffer.
-%% @spec string(string()) -&gt; parse_fun()
-string(S) -&gt;
+%% @spec p_string(string()) -&gt; parse_fun()
+p_string(S) -&gt;
   fun(Input, Index) -&gt;
       case lists:prefix(S, Input) of
-        true -&gt; {S, lists:sublist(Input, length(S)+1, length(Input)), advance_index(S,Index)};
+        true -&gt; {S, lists:sublist(Input, length(S)+1, length(Input)), p_advance_index(S,Index)};
         _ -&gt; {fail, {expected, {string, S}, Index}}
       end
   end.
 
 %% @doc Generates a parse function that will match any single character.
 %% @spec anything() -&gt; parse_fun()
-anything() -&gt;
+p_anything() -&gt;
   fun([], Index) -&gt; {fail, {expected, any_character, Index}};
-     ([H|T], Index) -&gt; {H, T, advance_index(H, Index)}
+     ([H|T], Index) -&gt; {H, T, p_advance_index(H, Index)}
   end.
 
 %% @doc Generates a parse function that will match any single character from the passed &quot;class&quot;.  The class should be a PCRE-compatible character class in a string.
@@ -207,19 +201,19 @@ anything() -&gt;
 %%     &quot;[0-9]&quot;
 %%     &quot;[^z]&quot; .
 %% @spec charclass(string()) -&gt; parse_fun()
-charclass(Class) -&gt;
+p_charclass(Class) -&gt;
   fun(Inp, Index) -&gt;
      {ok, RE} = re:compile(&quot;^&quot;++Class),
       case re:run(Inp, RE) of
         {match, _} -&gt;
-          {hd(Inp), tl(Inp), advance_index(hd(Inp), Index)};
+          {hd(Inp), tl(Inp), p_advance_index(hd(Inp), Index)};
         _ -&gt; {fail,{expected, {character_class, Class}, Index}}
       end
   end.
 
-advance_index(MatchedInput, Index) when is_list(MatchedInput) -&gt; % strings
-  lists:foldl(fun advance_index/2, Index, MatchedInput);
-advance_index(MatchedInput, Index) when is_integer(MatchedInput) -&gt; % single characters
+p_advance_index(MatchedInput, Index) when is_list(MatchedInput) -&gt; % strings
+  lists:foldl(fun p_advance_index/2, Index, MatchedInput);
+p_advance_index(MatchedInput, Index) when is_integer(MatchedInput) -&gt; % single characters
   {{line, Line}, {column, Col}} = Index,
   case MatchedInput of
     $\n -&gt; {{line, Line+1}, {column, 1}};</diff>
      <filename>src/peg.erl</filename>
    </modified>
    <modified>
      <diff>@@ -23,10 +23,11 @@ file(InputGrammar, Options) -&gt;
                   ModuleName,
                   TransformModule,
                   filename:absname(OutputFilename)),
-  ModuleAttrs = generate_module_attrs(ModuleName),
   Rules = parse_grammar(InputGrammar),
+  ModuleAttrs = generate_module_attrs(ModuleName),
   TransformFun = create_transform(TransformModule, OutputDir),
-  file:write_file(OutputFilename, [ModuleAttrs, &quot;\n&quot;, Rules, &quot;\n&quot;, TransformFun]).
+  {ok, PegIncludes} = file:read_file(code:priv_dir(neotoma) ++ &quot;/peg_includes.erl&quot;),
+  file:write_file(OutputFilename, [ModuleAttrs, &quot;\n&quot;, Rules, &quot;\n&quot;, TransformFun, &quot;\n&quot;, PegIncludes]).
 
 validate_params(InputGrammar, _, _, OutputFile) when InputGrammar =:= OutputFile -&gt;
   throw({badarg, &quot;Input and output file are the same!&quot;});
@@ -45,9 +46,22 @@ validate_params(_,_, TransformModule, OutputFile) -&gt;
   end.
 
 generate_module_attrs(ModName) -&gt;
+  {RootRule,_} = erase(neotoma_root_rule),
   [&quot;-module(&quot;,atom_to_list(ModName),&quot;).\n&quot;,
    &quot;-export([parse/1,file/1]).\n&quot;,
-   &quot;-include_lib(\&quot;neotoma/include/peg.hrl\&quot;).\n&quot;].
+   % This option could be problematic if your grammar is broken in
+   % some way, but hides warnings about unused parser combinators.
+   % In a future version we should just emit the used combinators,
+   % excluding the rest.
+   &quot;-compile(nowarn_unused_function).\n\n&quot;, 
+   &quot;file(Filename) -&gt; {ok, Bin} = file:read_file(Filename), parse(binary_to_list(Bin)).\n\n&quot;,
+   &quot;parse(Input) -&gt;\n&quot;,
+   &quot;  setup_memo('&quot;, atom_to_list(ModName),&quot;'),\n&quot;,
+   &quot;  Result = case '&quot;,RootRule,&quot;'(Input,{{line,1},{column,1}}) of\n&quot;,
+   &quot;             {AST, [], _Index} -&gt; AST;\n&quot;,
+   &quot;             Any -&gt; Any\n&quot;
+   &quot;           end,\n&quot;,
+   &quot;  release_memo(), Result.\n&quot;].
 
 parse_grammar(InputFile) -&gt;
   case peg_meta:file(InputFile) of</diff>
      <filename>src/peg_gen.erl</filename>
    </modified>
    <modified>
      <diff>@@ -1,89 +1,271 @@
 -module(peg_meta).
 -export([parse/1,file/1]).
--include_lib(&quot;neotoma/include/peg.hrl&quot;).
+-compile(nowarn_unused_function).
 
-rule(rules) -&gt;
-  peg:seq([peg:optional(fun space/2), fun declaration_sequence/2, peg:optional(fun space/2)]);
+file(Filename) -&gt; {ok, Bin} = file:read_file(Filename), parse(binary_to_list(Bin)).
 
-rule(declaration_sequence) -&gt;
-  peg:seq([peg:label('head', fun declaration/2), peg:label('tail', peg:zero_or_more(peg:seq([fun space/2, fun declaration/2])))]);
+parse(Input) -&gt;
+  setup_memo(peg_meta),
+  Result = case rules(Input,{{line,1},{column,1}}) of
+             {AST, [], _Index} -&gt; AST;
+             Any -&gt; Any
+           end,
+  release_memo(), Result.
 
-rule(declaration) -&gt;
-  peg:seq([fun nonterminal/2, fun space/2, peg:string(&quot;&lt;-&quot;), fun space/2, fun parsing_expression/2, peg:optional(fun space/2), peg:string(&quot;;&quot;)]);
+'rules'(Input, Index) -&gt;
+  p(Input, Index, 'rules', fun(I,D) -&gt; (p_seq([p_optional(fun 'space'/2), fun 'declaration_sequence'/2, p_optional(fun 'space'/2)]))(I,D) end, fun(Node, Idx) -&gt; transform('rules', Node, Idx) end).
 
-rule(parsing_expression) -&gt;
-  peg:choose([fun choice/2, fun sequence/2, fun primary/2]);
+'declaration_sequence'(Input, Index) -&gt;
+  p(Input, Index, 'declaration_sequence', fun(I,D) -&gt; (p_seq([p_label('head', fun 'declaration'/2), p_label('tail', p_zero_or_more(p_seq([fun 'space'/2, fun 'declaration'/2])))]))(I,D) end, fun(Node, Idx) -&gt; transform('declaration_sequence', Node, Idx) end).
 
-rule(choice) -&gt;
-  peg:seq([peg:label('head', fun alternative/2), peg:label('tail', peg:one_or_more(peg:seq([fun space/2, peg:string(&quot;/&quot;), fun space/2, fun alternative/2])))]);
+'declaration'(Input, Index) -&gt;
+  p(Input, Index, 'declaration', fun(I,D) -&gt; (p_seq([fun 'nonterminal'/2, fun 'space'/2, p_string(&quot;&lt;-&quot;), fun 'space'/2, fun 'parsing_expression'/2, p_optional(fun 'space'/2), p_string(&quot;;&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('declaration', Node, Idx) end).
 
-rule(alternative) -&gt;
-  peg:choose([fun sequence/2, fun primary/2]);
+'parsing_expression'(Input, Index) -&gt;
+  p(Input, Index, 'parsing_expression', fun(I,D) -&gt; (p_choose([fun 'choice'/2, fun 'sequence'/2, fun 'primary'/2]))(I,D) end, fun(Node, Idx) -&gt; transform('parsing_expression', Node, Idx) end).
 
-rule(primary) -&gt;
-  peg:choose([peg:seq([fun prefix/2, fun atomic/2]), peg:seq([fun atomic/2, fun suffix/2]), fun atomic/2]);
+'choice'(Input, Index) -&gt;
+  p(Input, Index, 'choice', fun(I,D) -&gt; (p_seq([p_label('head', fun 'alternative'/2), p_label('tail', p_one_or_more(p_seq([fun 'space'/2, p_string(&quot;/&quot;), fun 'space'/2, fun 'alternative'/2])))]))(I,D) end, fun(Node, Idx) -&gt; transform('choice', Node, Idx) end).
 
-rule(sequence) -&gt;
-  peg:seq([peg:label('head', fun labeled_sequence_primary/2), peg:label('tail', peg:one_or_more(peg:seq([fun space/2, fun labeled_sequence_primary/2])))]);
+'alternative'(Input, Index) -&gt;
+  p(Input, Index, 'alternative', fun(I,D) -&gt; (p_choose([fun 'sequence'/2, fun 'primary'/2]))(I,D) end, fun(Node, Idx) -&gt; transform('alternative', Node, Idx) end).
 
-rule(labeled_sequence_primary) -&gt;
-  peg:seq([peg:optional(fun label/2), fun primary/2]);
+'primary'(Input, Index) -&gt;
+  p(Input, Index, 'primary', fun(I,D) -&gt; (p_choose([p_seq([fun 'prefix'/2, fun 'atomic'/2]), p_seq([fun 'atomic'/2, fun 'suffix'/2]), fun 'atomic'/2]))(I,D) end, fun(Node, Idx) -&gt; transform('primary', Node, Idx) end).
 
-rule(label) -&gt;
-  peg:seq([fun alpha_char/2, peg:zero_or_more(fun alphanumeric_char/2), peg:string(&quot;:&quot;)]);
+'sequence'(Input, Index) -&gt;
+  p(Input, Index, 'sequence', fun(I,D) -&gt; (p_seq([p_label('head', fun 'labeled_sequence_primary'/2), p_label('tail', p_one_or_more(p_seq([fun 'space'/2, fun 'labeled_sequence_primary'/2])))]))(I,D) end, fun(Node, Idx) -&gt; transform('sequence', Node, Idx) end).
 
-rule(suffix) -&gt;
-  peg:choose([fun repetition_suffix/2, fun optional_suffix/2]);
+'labeled_sequence_primary'(Input, Index) -&gt;
+  p(Input, Index, 'labeled_sequence_primary', fun(I,D) -&gt; (p_seq([p_optional(fun 'label'/2), fun 'primary'/2]))(I,D) end, fun(Node, Idx) -&gt; transform('labeled_sequence_primary', Node, Idx) end).
 
-rule(optional_suffix) -&gt;
-  peg:string(&quot;?&quot;);
+'label'(Input, Index) -&gt;
+  p(Input, Index, 'label', fun(I,D) -&gt; (p_seq([fun 'alpha_char'/2, p_zero_or_more(fun 'alphanumeric_char'/2), p_string(&quot;:&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('label', Node, Idx) end).
 
-rule(repetition_suffix) -&gt;
-  peg:choose([peg:string(&quot;+&quot;), peg:string(&quot;*&quot;)]);
+'suffix'(Input, Index) -&gt;
+  p(Input, Index, 'suffix', fun(I,D) -&gt; (p_choose([fun 'repetition_suffix'/2, fun 'optional_suffix'/2]))(I,D) end, fun(Node, Idx) -&gt; transform('suffix', Node, Idx) end).
 
-rule(prefix) -&gt;
-  peg:choose([peg:string(&quot;&amp;&quot;), peg:string(&quot;!&quot;)]);
+'optional_suffix'(Input, Index) -&gt;
+  p(Input, Index, 'optional_suffix', fun(I,D) -&gt; (p_string(&quot;?&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('optional_suffix', Node, Idx) end).
 
-rule(atomic) -&gt;
-  peg:choose([fun terminal/2, fun nonterminal/2, fun parenthesized_expression/2]);
+'repetition_suffix'(Input, Index) -&gt;
+  p(Input, Index, 'repetition_suffix', fun(I,D) -&gt; (p_choose([p_string(&quot;+&quot;), p_string(&quot;*&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('repetition_suffix', Node, Idx) end).
 
-rule(parenthesized_expression) -&gt;
-  peg:seq([peg:string(&quot;(&quot;), peg:optional(fun space/2), fun parsing_expression/2, peg:optional(fun space/2), peg:string(&quot;)&quot;)]);
+'prefix'(Input, Index) -&gt;
+  p(Input, Index, 'prefix', fun(I,D) -&gt; (p_choose([p_string(&quot;&amp;&quot;), p_string(&quot;!&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('prefix', Node, Idx) end).
 
-rule(nonterminal) -&gt;
-  peg:seq([fun alpha_char/2, peg:zero_or_more(fun alphanumeric_char/2)]);
+'atomic'(Input, Index) -&gt;
+  p(Input, Index, 'atomic', fun(I,D) -&gt; (p_choose([fun 'terminal'/2, fun 'nonterminal'/2, fun 'parenthesized_expression'/2]))(I,D) end, fun(Node, Idx) -&gt; transform('atomic', Node, Idx) end).
 
-rule(terminal) -&gt;
-  peg:choose([fun quoted_string/2, fun character_class/2, fun anything_symbol/2]);
+'parenthesized_expression'(Input, Index) -&gt;
+  p(Input, Index, 'parenthesized_expression', fun(I,D) -&gt; (p_seq([p_string(&quot;(&quot;), p_optional(fun 'space'/2), fun 'parsing_expression'/2, p_optional(fun 'space'/2), p_string(&quot;)&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('parenthesized_expression', Node, Idx) end).
 
-rule(quoted_string) -&gt;
-  peg:choose([fun single_quoted_string/2, fun double_quoted_string/2]);
+'nonterminal'(Input, Index) -&gt;
+  p(Input, Index, 'nonterminal', fun(I,D) -&gt; (p_seq([fun 'alpha_char'/2, p_zero_or_more(fun 'alphanumeric_char'/2)]))(I,D) end, fun(Node, Idx) -&gt; transform('nonterminal', Node, Idx) end).
 
-rule(double_quoted_string) -&gt;
-  peg:seq([peg:string(&quot;\&quot;&quot;), peg:label('string', peg:zero_or_more(peg:seq([peg:not_(peg:string(&quot;\&quot;&quot;)), peg:choose([peg:string(&quot;\\\\&quot;), peg:string(&quot;\\\&quot;&quot;), peg:anything()])]))), peg:string(&quot;\&quot;&quot;)]);
+'terminal'(Input, Index) -&gt;
+  p(Input, Index, 'terminal', fun(I,D) -&gt; (p_choose([fun 'quoted_string'/2, fun 'character_class'/2, fun 'anything_symbol'/2]))(I,D) end, fun(Node, Idx) -&gt; transform('terminal', Node, Idx) end).
 
-rule(single_quoted_string) -&gt;
-  peg:seq([peg:string(&quot;'&quot;), peg:label('string', peg:zero_or_more(peg:seq([peg:not_(peg:string(&quot;'&quot;)), peg:choose([peg:string(&quot;\\\\&quot;), peg:string(&quot;\\'&quot;), peg:anything()])]))), peg:string(&quot;'&quot;)]);
+'quoted_string'(Input, Index) -&gt;
+  p(Input, Index, 'quoted_string', fun(I,D) -&gt; (p_choose([fun 'single_quoted_string'/2, fun 'double_quoted_string'/2]))(I,D) end, fun(Node, Idx) -&gt; transform('quoted_string', Node, Idx) end).
 
-rule(character_class) -&gt;
-  peg:seq([peg:string(&quot;[&quot;), peg:label('characters', peg:one_or_more(peg:seq([peg:not_(peg:string(&quot;]&quot;)), peg:choose([peg:seq([peg:string(&quot;\\\\&quot;), peg:anything()]), peg:seq([peg:not_(peg:string(&quot;\\\\&quot;)), peg:anything()])])]))), peg:string(&quot;]&quot;)]);
+'double_quoted_string'(Input, Index) -&gt;
+  p(Input, Index, 'double_quoted_string', fun(I,D) -&gt; (p_seq([p_string(&quot;\&quot;&quot;), p_label('string', p_zero_or_more(p_seq([p_not(p_string(&quot;\&quot;&quot;)), p_choose([p_string(&quot;\\\\&quot;), p_string(&quot;\\\&quot;&quot;), p_anything()])]))), p_string(&quot;\&quot;&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('double_quoted_string', Node, Idx) end).
 
-rule(anything_symbol) -&gt;
-  peg:string(&quot;.&quot;);
+'single_quoted_string'(Input, Index) -&gt;
+  p(Input, Index, 'single_quoted_string', fun(I,D) -&gt; (p_seq([p_string(&quot;'&quot;), p_label('string', p_zero_or_more(p_seq([p_not(p_string(&quot;'&quot;)), p_choose([p_string(&quot;\\\\&quot;), p_string(&quot;\\'&quot;), p_anything()])]))), p_string(&quot;'&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('single_quoted_string', Node, Idx) end).
 
-rule(alpha_char) -&gt;
-  peg:charclass(&quot;[a-z_]&quot;);
+'character_class'(Input, Index) -&gt;
+  p(Input, Index, 'character_class', fun(I,D) -&gt; (p_seq([p_string(&quot;[&quot;), p_label('characters', p_one_or_more(p_seq([p_not(p_string(&quot;]&quot;)), p_choose([p_seq([p_string(&quot;\\\\&quot;), p_anything()]), p_seq([p_not(p_string(&quot;\\\\&quot;)), p_anything()])])]))), p_string(&quot;]&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('character_class', Node, Idx) end).
 
-rule(alphanumeric_char) -&gt;
-  peg:choose([fun alpha_char/2, peg:charclass(&quot;[0-9]&quot;)]);
+'anything_symbol'(Input, Index) -&gt;
+  p(Input, Index, 'anything_symbol', fun(I,D) -&gt; (p_string(&quot;.&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('anything_symbol', Node, Idx) end).
 
-rule(space) -&gt;
-  peg:one_or_more(peg:choose([fun white/2, fun comment_to_eol/2]));
+'alpha_char'(Input, Index) -&gt;
+  p(Input, Index, 'alpha_char', fun(I,D) -&gt; (p_charclass(&quot;[a-z_]&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('alpha_char', Node, Idx) end).
 
-rule(comment_to_eol) -&gt;
-  peg:seq([peg:string(&quot;%&quot;), peg:zero_or_more(peg:seq([peg:not_(peg:string(&quot;\n&quot;)), peg:anything()]))]);
+'alphanumeric_char'(Input, Index) -&gt;
+  p(Input, Index, 'alphanumeric_char', fun(I,D) -&gt; (p_choose([fun 'alpha_char'/2, p_charclass(&quot;[0-9]&quot;)]))(I,D) end, fun(Node, Idx) -&gt; transform('alphanumeric_char', Node, Idx) end).
 
-rule(white) -&gt;
-  peg:charclass(&quot;[ \t\n\r]&quot;).
+'space'(Input, Index) -&gt;
+  p(Input, Index, 'space', fun(I,D) -&gt; (p_one_or_more(p_choose([fun 'white'/2, fun 'comment_to_eol'/2])))(I,D) end, fun(Node, Idx) -&gt; transform('space', Node, Idx) end).
 
-transform(Symbol,Node,Index) -&gt; peg_meta_gen:transform(Symbol, Node, Index).
\ No newline at end of file
+'comment_to_eol'(Input, Index) -&gt;
+  p(Input, Index, 'comment_to_eol', fun(I,D) -&gt; (p_seq([p_string(&quot;%&quot;), p_zero_or_more(p_seq([p_not(p_string(&quot;\n&quot;)), p_anything()]))]))(I,D) end, fun(Node, Idx) -&gt; transform('comment_to_eol', Node, Idx) end).
+
+'white'(Input, Index) -&gt;
+  p(Input, Index, 'white', fun(I,D) -&gt; (p_charclass(&quot;[ \t\n\r]&quot;))(I,D) end, fun(Node, Idx) -&gt; transform('white', Node, Idx) end).
+
+transform(Symbol,Node,Index) -&gt; peg_meta_gen:transform(Symbol, Node, Index).
+
+
+
+
+
+p(Inp, Index, Name, ParseFun) -&gt;
+  p(Inp, Index, Name, ParseFun, fun(N, _Idx) -&gt; N end).
+
+p(Inp, StartIndex, Name, ParseFun, TransformFun) -&gt;
+  % Grab the memo table from ets
+  Memo = get_memo(StartIndex),
+  % See if the current reduction is memoized
+  case dict:find(Name, Memo) of
+    % If it is, return the result
+    {ok, Result} -&gt; Result;
+    % If not, attempt to parse
+    _ -&gt;
+      case ParseFun(Inp, StartIndex) of
+        % If it fails, memoize the failure
+        {fail,_} = Failure -&gt;
+          memoize(StartIndex, dict:store(Name, Failure, Memo)),
+          Failure;
+        % If it passes, transform and memoize the result.
+        {Result, InpRem, NewIndex} -&gt;
+          Transformed = TransformFun(Result, StartIndex),
+          memoize(StartIndex, dict:store(Name, {Transformed, InpRem, NewIndex}, Memo)),
+          {Transformed, InpRem, NewIndex}
+      end
+  end.
+
+setup_memo(Name) -&gt;
+  TID = ets:new(Name, [set]),
+  put(ets_table, TID).
+
+release_memo() -&gt;
+  ets:delete(get(ets_table)),
+  erase(ets_table).
+
+memoize(Position, Struct) -&gt;
+  ets:insert(get(ets_table), {Position, Struct}).
+
+get_memo(Position) -&gt;
+  case ets:lookup(get(ets_table), Position) of
+    [] -&gt; dict:new();
+    [{Position, Dict}] -&gt; Dict
+  end.
+
+p_eof() -&gt;
+  fun([], Index) -&gt; {eof, [], Index};
+     (_, Index) -&gt; {fail, {expected, eof, Index}} end.
+
+p_optional(P) -&gt;
+  fun(Input, Index) -&gt;
+      case P(Input, Index) of
+        {fail,_} -&gt; {[], Input, Index};
+        {_, _, _} = Success -&gt; Success
+      end
+  end.
+
+p_not(P) -&gt;
+  fun(Input, Index)-&gt;
+      case P(Input,Index) of
+        {fail,_} -&gt;
+          {[], Input, Index};
+        {Result, _, _} -&gt; {fail, {expected, {no_match, Result},Index}}
+      end
+  end.
+
+p_assert(P) -&gt;
+  fun(Input,Index) -&gt;
+      case P(Input,Index) of
+        {fail,_} = Failure-&gt; Failure;
+        _ -&gt; {[], Input, Index}
+      end
+  end.
+
+p_and(P) -&gt;
+  p_seq(P).
+
+p_seq(P) -&gt;
+  fun(Input, Index) -&gt;
+      p_all(P, Input, Index, [])
+  end.
+
+p_all([], Inp, Index, Accum ) -&gt; {lists:reverse( Accum ), Inp, Index};
+p_all([P|Parsers], Inp, Index, Accum) -&gt;
+  case P(Inp, Index) of
+    {fail, _} = Failure -&gt; Failure;
+    {Result, InpRem, NewIndex} -&gt; p_all(Parsers, InpRem, NewIndex, [Result|Accum])
+  end.
+
+p_choose(Parsers) -&gt;
+  fun(Input, Index) -&gt;
+      p_attempt(Parsers, Input, Index, none)
+  end.
+
+p_attempt([], _Input, _Index, Failure) -&gt; Failure;
+p_attempt([P|Parsers], Input, Index, FirstFailure)-&gt;
+  case P(Input, Index) of
+    {fail, _} = Failure -&gt;
+      case FirstFailure of
+        none -&gt; p_attempt(Parsers, Input, Index, Failure);
+        _ -&gt; p_attempt(Parsers, Input, Index, FirstFailure)
+      end;
+    Result -&gt; Result
+  end.
+
+p_zero_or_more(P) -&gt;
+  fun(Input, Index) -&gt;
+      p_scan(P, Input, Index, [])
+  end.
+
+p_one_or_more(P) -&gt;
+  fun(Input, Index)-&gt;
+      Result = p_scan(P, Input, Index, []),
+      case Result of
+        {[_|_], _, _} -&gt;
+          Result;
+        _ -&gt;
+          {fail, {expected, Failure, _}} = P(Input,Index),
+          {fail, {expected, {at_least_one, Failure}, Index}}
+      end
+  end.
+
+p_label(Tag, P) -&gt;
+  fun(Input, Index) -&gt;
+      case P(Input, Index) of
+        {fail,_} = Failure -&gt;
+           Failure;
+        {Result, InpRem, NewIndex} -&gt;
+          {{Tag, Result}, InpRem, NewIndex}
+      end
+  end.
+
+p_scan(_, [], Index, Accum) -&gt; {lists:reverse( Accum ), [], Index};
+p_scan(P, Inp, Index, Accum) -&gt;
+  case P(Inp, Index) of
+    {fail,_} -&gt; {lists:reverse(Accum), Inp, Index};
+    {Result, InpRem, NewIndex} -&gt; p_scan(P, InpRem, NewIndex, [Result | Accum])
+  end.
+
+p_string(S) -&gt;
+  fun(Input, Index) -&gt;
+      case lists:prefix(S, Input) of
+        true -&gt; {S, lists:sublist(Input, length(S)+1, length(Input)), p_advance_index(S,Index)};
+        _ -&gt; {fail, {expected, {string, S}, Index}}
+      end
+  end.
+
+p_anything() -&gt;
+  fun([], Index) -&gt; {fail, {expected, any_character, Index}};
+     ([H|T], Index) -&gt; {H, T, p_advance_index(H, Index)}
+  end.
+
+p_charclass(Class) -&gt;
+  fun(Inp, Index) -&gt;
+     {ok, RE} = re:compile(&quot;^&quot;++Class),
+      case re:run(Inp, RE) of
+        {match, _} -&gt;
+          {hd(Inp), tl(Inp), p_advance_index(hd(Inp), Index)};
+        _ -&gt; {fail,{expected, {character_class, Class}, Index}}
+      end
+  end.
+
+p_advance_index(MatchedInput, Index) when is_list(MatchedInput) -&gt; % strings
+  lists:foldl(fun p_advance_index/2, Index, MatchedInput);
+p_advance_index(MatchedInput, Index) when is_integer(MatchedInput) -&gt; % single characters
+  {{line, Line}, {column, Col}} = Index,
+  case MatchedInput of
+    $\n -&gt; {{line, Line+1}, {column, 1}};
+    _ -&gt; {{line, Line}, {column, Col+1}}
+  end.</diff>
      <filename>src/peg_meta.erl</filename>
    </modified>
    <modified>
      <diff>@@ -3,57 +3,60 @@
 -author(&quot;Sean Cribbs &lt;seancribbs@gmail.com&gt;&quot;).
 
 transform(rules, Node, _Index) -&gt;
-  verify_rules(),
-  Rules = string:join(lists:nth(2, Node), &quot;;\n\n&quot;),
-  Rules ++ &quot;.\n&quot;;
+  put(neotoma_root_rule, verify_rules()),
+  Rules = string:join(lists:nth(2, Node), &quot;\n\n&quot;),
+  Rules ++ &quot;\n&quot;;
 transform(declaration_sequence, Node, _Index) -&gt;
   FirstRule = proplists:get_value(head, Node),
   OtherRules =  [lists:last(I) || I &lt;- proplists:get_value(tail, Node, [])],
   [FirstRule|OtherRules];
 transform(declaration, [{nonterminal,Symbol}|Node], Index) -&gt;
   add_lhs(Symbol, Index),
-  &quot;rule(&quot;++escape_symbol(Symbol)++&quot;) -&gt;\n  &quot; ++ lists:nth(4, Node);
+  &quot;'&quot;++Symbol++&quot;'&quot;++&quot;(Input, Index) -&gt;\n  &quot; ++
+        &quot;p(Input, Index, '&quot;++Symbol++&quot;', fun(I,D) -&gt; (&quot;++
+        lists:nth(4, Node) ++
+        &quot;)(I,D) end, fun(Node, Idx) -&gt; transform('&quot;++Symbol++&quot;', Node, Idx) end).&quot;;
 transform(sequence, Node, _Index) -&gt;
   Tail = [lists:nth(2, S) || S &lt;- proplists:get_value(tail, Node)],
   Statements = [proplists:get_value(head, Node)|Tail],
-  &quot;peg:seq([&quot;++ string:join(Statements, &quot;, &quot;) ++ &quot;])&quot;;
+  &quot;p_seq([&quot;++ string:join(Statements, &quot;, &quot;) ++ &quot;])&quot;;
 transform(choice, Node, _Index) -&gt;
   Tail = [lists:last(S) || S &lt;- proplists:get_value(tail, Node)],
   Statements = [proplists:get_value(head, Node)|Tail],
-  &quot;peg:choose([&quot; ++ string:join(Statements, &quot;, &quot;) ++ &quot;])&quot;;
+  &quot;p_choose([&quot; ++ string:join(Statements, &quot;, &quot;) ++ &quot;])&quot;;
 transform(label, Node, _Index) -&gt;
   String = lists:flatten(Node),
   lists:sublist(String, length(String)-1);
 transform(labeled_sequence_primary, Node, _Index) -&gt;
   case hd(Node) of
     [] -&gt; lists:nth(2, Node);
-    Label -&gt; &quot;peg:label('&quot; ++ Label ++ &quot;', &quot;++lists:nth(2, Node)++&quot;)&quot;
+    Label -&gt; &quot;p_label('&quot; ++ Label ++ &quot;', &quot;++lists:nth(2, Node)++&quot;)&quot;
   end;
 transform(single_quoted_string, Node, Index) -&gt;
   transform(double_quoted_string, Node, Index);
 transform(double_quoted_string, Node, _Index) -&gt;
-  &quot;peg:string(\&quot;&quot;++escape_quotes(lists:flatten(proplists:get_value(string, Node)))++&quot;\&quot;)&quot;;
+  &quot;p_string(\&quot;&quot;++escape_quotes(lists:flatten(proplists:get_value(string, Node)))++&quot;\&quot;)&quot;;
 transform(character_class, Node, _Index) -&gt;
-  &quot;peg:charclass(\&quot;[&quot; ++ escape_quotes(lists:flatten(proplists:get_value(characters, Node))) ++ &quot;]\&quot;)&quot;;
+  &quot;p_charclass(\&quot;[&quot; ++ escape_quotes(lists:flatten(proplists:get_value(characters, Node))) ++ &quot;]\&quot;)&quot;;
 transform(parenthesized_expression, Node, _Index) -&gt;
   lists:nth(3, Node);
 transform(atomic, {nonterminal, Symbol}, Index) -&gt;
   add_nt(Symbol, Index),
-  &quot;fun &quot; ++ escape_symbol(Symbol) ++ &quot;/2&quot;;
+  &quot;fun '&quot; ++ Symbol ++ &quot;'/2&quot;;
 transform(primary, [Atomic, one_or_more], _Index) -&gt;
-  &quot;peg:one_or_more(&quot;++Atomic++&quot;)&quot;;
+  &quot;p_one_or_more(&quot;++Atomic++&quot;)&quot;;
 transform(primary, [Atomic, zero_or_more], _Index) -&gt;
-  &quot;peg:zero_or_more(&quot;++Atomic++&quot;)&quot;;
+  &quot;p_zero_or_more(&quot;++Atomic++&quot;)&quot;;
 transform(primary, [Atomic, optional], _Index) -&gt;
-  &quot;peg:optional(&quot;++Atomic++&quot;)&quot;;
+  &quot;p_optional(&quot;++Atomic++&quot;)&quot;;
 transform(primary, [assert, Atomic], _Index)-&gt;
-  &quot;peg:assert(&quot;++Atomic++&quot;)&quot;;
+  &quot;p_assert(&quot;++Atomic++&quot;)&quot;;
 transform(primary, [not_, Atomic], _Index) -&gt;
-  &quot;peg:not_(&quot;++Atomic++&quot;)&quot;;
+  &quot;p_not(&quot;++Atomic++&quot;)&quot;;
 transform(nonterminal, Node, _Index) -&gt;
   {nonterminal, lists:flatten(Node)};
 transform(anything_symbol, _Node, _Index) -&gt;
-  &quot;peg:anything()&quot;;
+  &quot;p_anything()&quot;;
 transform(suffix, Node, _Index) -&gt;
   case Node of
     &quot;*&quot; -&gt; zero_or_more;
@@ -96,7 +99,7 @@ add_nt(Symbol, Index) -&gt;
 verify_rules() -&gt;
   LHS = erase(lhs),
   NTs = erase(nts),
-  NonRoots = tl(lists:reverse(LHS)),
+  [Root|NonRoots] = lists:reverse(LHS),
   lists:foreach(fun({Sym,Idx}) -&gt;
                     case proplists:is_defined(Sym, NTs) of
                       true -&gt;
@@ -110,38 +113,8 @@ verify_rules() -&gt;
                       true -&gt;
                         ok;
                       _ -&gt;
-                        io:format(&quot;neotoma error: symbol '~s' has no reduction. (found at ~p) No parser will be generated!~n&quot;, [S,I]),
+                        io:format(&quot;neotoma error: nonterminal '~s' has no reduction. (found at ~p) No parser will be generated!~n&quot;, [S,I]),
                         exit({neotoma, {no_reduction, list_to_atom(S)}})
                     end
-                end, NTs).
-
-escape_symbol(&quot;after&quot;)   -&gt; &quot;'after'&quot;;
-escape_symbol(&quot;and&quot;)     -&gt; &quot;'and'&quot;;
-escape_symbol(&quot;andalso&quot;) -&gt; &quot;'andalso'&quot;;
-escape_symbol(&quot;band&quot;)    -&gt; &quot;'band'&quot;;
-escape_symbol(&quot;begin&quot;)   -&gt; &quot;'begin'&quot;;
-escape_symbol(&quot;bnot&quot;)    -&gt; &quot;'bnot'&quot;;
-escape_symbol(&quot;bor&quot;)     -&gt; &quot;'bor'&quot;;
-escape_symbol(&quot;bsl&quot;)     -&gt; &quot;'bsl'&quot;;
-escape_symbol(&quot;bsr&quot;)     -&gt; &quot;'bsr'&quot;;
-escape_symbol(&quot;bxor&quot;)    -&gt; &quot;'bxor'&quot;;
-escape_symbol(&quot;case&quot;)    -&gt; &quot;'case'&quot;;
-escape_symbol(&quot;catch&quot;)   -&gt; &quot;'catch'&quot;;
-escape_symbol(&quot;cond&quot;)    -&gt; &quot;'cond'&quot;;
-escape_symbol(&quot;div&quot;)     -&gt; &quot;'div'&quot;;
-escape_symbol(&quot;end&quot;)     -&gt; &quot;'end'&quot;;
-escape_symbol(&quot;fun&quot;)     -&gt; &quot;'fun'&quot;;
-escape_symbol(&quot;if&quot;)      -&gt; &quot;'if'&quot;;
-escape_symbol(&quot;let&quot;)     -&gt; &quot;'let'&quot;;
-escape_symbol(&quot;not&quot;)     -&gt; &quot;'not'&quot;;
-escape_symbol(&quot;of&quot;)      -&gt; &quot;'of'&quot;;
-escape_symbol(&quot;or&quot;)      -&gt; &quot;'or'&quot;;
-escape_symbol(&quot;orelse&quot;)  -&gt; &quot;'orelse'&quot;;
-escape_symbol(&quot;query&quot;)   -&gt; &quot;'query'&quot;;
-escape_symbol(&quot;receive&quot;) -&gt; &quot;'receive'&quot;;
-escape_symbol(&quot;rem&quot;)     -&gt; &quot;'rem'&quot;;
-escape_symbol(&quot;try&quot;)     -&gt; &quot;'try'&quot;;
-escape_symbol(&quot;when&quot;)    -&gt; &quot;'when'&quot;;
-escape_symbol(&quot;xor&quot;)     -&gt; &quot;'xor'&quot;;
-
-escape_symbol(Symbol) -&gt; Symbol.
+                end, NTs),
+    Root.</diff>
      <filename>src/peg_meta_gen.erl</filename>
    </modified>
    <modified>
      <diff>@@ -6,77 +6,77 @@
 -define(STARTINDEX, {{line,1},{column,1}}).
 eof_test_() -&gt;
   [
-   ?_assertEqual({fail,{expected,eof,?STARTINDEX}}, (peg:eof())(&quot;abc&quot;,?STARTINDEX)),
-   ?_assertEqual({eof, [], ?STARTINDEX}, (peg:eof())(&quot;&quot;,?STARTINDEX))
+   ?_assertEqual({fail,{expected,eof,?STARTINDEX}}, (peg:p_eof())(&quot;abc&quot;,?STARTINDEX)),
+   ?_assertEqual({eof, [], ?STARTINDEX}, (peg:p_eof())(&quot;&quot;,?STARTINDEX))
   ].
 
 optional_test_() -&gt;
   [
-   ?_assertEqual({[], &quot;xyz&quot;,?STARTINDEX}, (peg:optional(peg:string(&quot;abc&quot;)))(&quot;xyz&quot;,?STARTINDEX)),
-   ?_assertEqual({&quot;abc&quot;, &quot;xyz&quot;,{{line,1},{column,4}}}, (peg:optional(peg:string(&quot;abc&quot;)))(&quot;abcxyz&quot;,?STARTINDEX))
+   ?_assertEqual({[], &quot;xyz&quot;,?STARTINDEX}, (peg:p_optional(peg:p_string(&quot;abc&quot;)))(&quot;xyz&quot;,?STARTINDEX)),
+   ?_assertEqual({&quot;abc&quot;, &quot;xyz&quot;,{{line,1},{column,4}}}, (peg:p_optional(peg:p_string(&quot;abc&quot;)))(&quot;abcxyz&quot;,?STARTINDEX))
   ].
 
 not_test_() -&gt;
   [
-   ?_assertEqual({[], &quot;xyzabc&quot;,?STARTINDEX}, (peg:not_(peg:string(&quot;abc&quot;)))(&quot;xyzabc&quot;,?STARTINDEX)),
-   ?_assertEqual({fail,{expected, {no_match, &quot;abc&quot;}, ?STARTINDEX}}, (peg:not_(peg:string(&quot;abc&quot;)))(&quot;abcxyz&quot;,?STARTINDEX))
+   ?_assertEqual({[], &quot;xyzabc&quot;,?STARTINDEX}, (peg:p_not(peg:p_string(&quot;abc&quot;)))(&quot;xyzabc&quot;,?STARTINDEX)),
+   ?_assertEqual({fail,{expected, {no_match, &quot;abc&quot;}, ?STARTINDEX}}, (peg:p_not(peg:p_string(&quot;abc&quot;)))(&quot;abcxyz&quot;,?STARTINDEX))
   ].
 
 assert_test_() -&gt;
   [
-   ?_assertEqual({fail,{expected, {string, &quot;abc&quot;}, ?STARTINDEX}}, (peg:assert(peg:string(&quot;abc&quot;)))(&quot;xyzabc&quot;,?STARTINDEX)),
-   ?_assertEqual({[], &quot;abcxyz&quot;,?STARTINDEX}, (peg:assert(peg:string(&quot;abc&quot;)))(&quot;abcxyz&quot;,?STARTINDEX))
+   ?_assertEqual({fail,{expected, {string, &quot;abc&quot;}, ?STARTINDEX}}, (peg:p_assert(peg:p_string(&quot;abc&quot;)))(&quot;xyzabc&quot;,?STARTINDEX)),
+   ?_assertEqual({[], &quot;abcxyz&quot;,?STARTINDEX}, (peg:p_assert(peg:p_string(&quot;abc&quot;)))(&quot;abcxyz&quot;,?STARTINDEX))
   ].
 
 seq_test_() -&gt;
   [
-   ?_assertEqual({[&quot;abc&quot;,&quot;def&quot;], &quot;xyz&quot;,{{line,1},{column,7}}}, (peg:seq([peg:string(&quot;abc&quot;), peg:string(&quot;def&quot;)]))(&quot;abcdefxyz&quot;,?STARTINDEX)),
-   ?_assertEqual({fail,{expected, {string, &quot;def&quot;}, {{line,1},{column,4}}}}, (peg:seq([peg:string(&quot;abc&quot;), peg:string(&quot;def&quot;)]))(&quot;abcxyz&quot;,?STARTINDEX))
+   ?_assertEqual({[&quot;abc&quot;,&quot;def&quot;], &quot;xyz&quot;,{{line,1},{column,7}}}, (peg:p_seq([peg:p_string(&quot;abc&quot;), peg:p_string(&quot;def&quot;)]))(&quot;abcdefxyz&quot;,?STARTINDEX)),
+   ?_assertEqual({fail,{expected, {string, &quot;def&quot;}, {{line,1},{column,4}}}}, (peg:p_seq([peg:p_string(&quot;abc&quot;), peg:p_string(&quot;def&quot;)]))(&quot;abcxyz&quot;,?STARTINDEX))
   ].
 
 choose_test_() -&gt;
   [
-   ?_assertEqual({&quot;abc&quot;, &quot;xyz&quot;, {{line,1},{column,4}}}, (peg:choose([peg:string(&quot;abc&quot;), peg:string(&quot;def&quot;)]))(&quot;abcxyz&quot;,?STARTINDEX)),
-   ?_assertEqual({&quot;def&quot;, &quot;xyz&quot;, {{line,1},{column,4}}}, (peg:choose([peg:string(&quot;abc&quot;), peg:string(&quot;def&quot;)]))(&quot;defxyz&quot;,?STARTINDEX)),
-   ?_assertEqual({&quot;xyz&quot;, &quot;xyz&quot;, {{line,1},{column,4}}}, (peg:choose([peg:string(&quot;abc&quot;), peg:string(&quot;def&quot;), peg:string(&quot;xyz&quot;)]))(&quot;xyzxyz&quot;,?STARTINDEX)),
-   ?_assertEqual({fail,{expected,{string,&quot;abc&quot;},?STARTINDEX}}, (peg:choose([peg:string(&quot;abc&quot;),peg:string(&quot;def&quot;)]))(&quot;xyz&quot;, ?STARTINDEX))
+   ?_assertEqual({&quot;abc&quot;, &quot;xyz&quot;, {{line,1},{column,4}}}, (peg:p_choose([peg:p_string(&quot;abc&quot;), peg:p_string(&quot;def&quot;)]))(&quot;abcxyz&quot;,?STARTINDEX)),
+   ?_assertEqual({&quot;def&quot;, &quot;xyz&quot;, {{line,1},{column,4}}}, (peg:p_choose([peg:p_string(&quot;abc&quot;), peg:p_string(&quot;def&quot;)]))(&quot;defxyz&quot;,?STARTINDEX)),
+   ?_assertEqual({&quot;xyz&quot;, &quot;xyz&quot;, {{line,1},{column,4}}}, (peg:p_choose([peg:p_string(&quot;abc&quot;), peg:p_string(&quot;def&quot;), peg:p_string(&quot;xyz&quot;)]))(&quot;xyzxyz&quot;,?STARTINDEX)),
+   ?_assertEqual({fail,{expected,{string,&quot;abc&quot;},?STARTINDEX}}, (peg:p_choose([peg:p_string(&quot;abc&quot;),peg:p_string(&quot;def&quot;)]))(&quot;xyz&quot;, ?STARTINDEX))
   ].
 
 zero_or_more_test_() -&gt;
   [
-   ?_assertEqual({[], [], ?STARTINDEX}, (peg:zero_or_more(peg:string(&quot;abc&quot;)))(&quot;&quot;,?STARTINDEX)),
-   ?_assertEqual({[], &quot;def&quot;,?STARTINDEX}, (peg:zero_or_more(peg:string(&quot;abc&quot;)))(&quot;def&quot;,?STARTINDEX)),
-   ?_assertEqual({[&quot;abc&quot;], &quot;def&quot;,{{line,1},{column,4}}}, (peg:zero_or_more(peg:string(&quot;abc&quot;)))(&quot;abcdef&quot;,?STARTINDEX)),
-   ?_assertEqual({[&quot;abc&quot;, &quot;abc&quot;], &quot;def&quot;,{{line,1},{column,7}}}, (peg:zero_or_more(peg:string(&quot;abc&quot;)))(&quot;abcabcdef&quot;,?STARTINDEX))
+   ?_assertEqual({[], [], ?STARTINDEX}, (peg:p_zero_or_more(peg:p_string(&quot;abc&quot;)))(&quot;&quot;,?STARTINDEX)),
+   ?_assertEqual({[], &quot;def&quot;,?STARTINDEX}, (peg:p_zero_or_more(peg:p_string(&quot;abc&quot;)))(&quot;def&quot;,?STARTINDEX)),
+   ?_assertEqual({[&quot;abc&quot;], &quot;def&quot;,{{line,1},{column,4}}}, (peg:p_zero_or_more(peg:p_string(&quot;abc&quot;)))(&quot;abcdef&quot;,?STARTINDEX)),
+   ?_assertEqual({[&quot;abc&quot;, &quot;abc&quot;], &quot;def&quot;,{{line,1},{column,7}}}, (peg:p_zero_or_more(peg:p_string(&quot;abc&quot;)))(&quot;abcabcdef&quot;,?STARTINDEX))
   ].
 
 one_or_more_test_() -&gt;
   [
-   ?_assertEqual({fail,{expected, {at_least_one, {string, &quot;abc&quot;}}, ?STARTINDEX}}, (peg:one_or_more(peg:string(&quot;abc&quot;)))(&quot;def&quot;,?STARTINDEX)),
-   ?_assertEqual({[&quot;abc&quot;], &quot;def&quot;,{{line,1},{column,4}}}, (peg:one_or_more(peg:string(&quot;abc&quot;)))(&quot;abcdef&quot;,?STARTINDEX)),
-   ?_assertEqual({[&quot;abc&quot;,&quot;abc&quot;], &quot;def&quot;,{{line,1},{column,7}}}, (peg:one_or_more(peg:string(&quot;abc&quot;)))(&quot;abcabcdef&quot;,?STARTINDEX))
+   ?_assertEqual({fail,{expected, {at_least_one, {string, &quot;abc&quot;}}, ?STARTINDEX}}, (peg:p_one_or_more(peg:p_string(&quot;abc&quot;)))(&quot;def&quot;,?STARTINDEX)),
+   ?_assertEqual({[&quot;abc&quot;], &quot;def&quot;,{{line,1},{column,4}}}, (peg:p_one_or_more(peg:p_string(&quot;abc&quot;)))(&quot;abcdef&quot;,?STARTINDEX)),
+   ?_assertEqual({[&quot;abc&quot;,&quot;abc&quot;], &quot;def&quot;,{{line,1},{column,7}}}, (peg:p_one_or_more(peg:p_string(&quot;abc&quot;)))(&quot;abcabcdef&quot;,?STARTINDEX))
   ].
 
 label_test_() -&gt;
   [
-   ?_assertEqual({fail,{expected, {string, &quot;!&quot;}, ?STARTINDEX}}, (peg:label(bang, peg:string(&quot;!&quot;)))(&quot;?&quot;,?STARTINDEX)),
-   ?_assertEqual({{bang, &quot;!&quot;}, &quot;&quot;,{{line,1},{column,2}}}, (peg:label(bang, peg:string(&quot;!&quot;)))(&quot;!&quot;,?STARTINDEX))
+   ?_assertEqual({fail,{expected, {string, &quot;!&quot;}, ?STARTINDEX}}, (peg:p_label(bang, peg:p_string(&quot;!&quot;)))(&quot;?&quot;,?STARTINDEX)),
+   ?_assertEqual({{bang, &quot;!&quot;}, &quot;&quot;,{{line,1},{column,2}}}, (peg:p_label(bang, peg:p_string(&quot;!&quot;)))(&quot;!&quot;,?STARTINDEX))
   ].
 
 string_test_() -&gt;
   [
-   ?_assertEqual({&quot;abc&quot;, &quot;def&quot;,{{line,1},{column,4}}}, (peg:string(&quot;abc&quot;))(&quot;abcdef&quot;,?STARTINDEX)),
-   ?_assertEqual({fail,{expected, {string, &quot;abc&quot;}, ?STARTINDEX}}, (peg:string(&quot;abc&quot;))(&quot;defabc&quot;,?STARTINDEX))
+   ?_assertEqual({&quot;abc&quot;, &quot;def&quot;,{{line,1},{column,4}}}, (peg:p_string(&quot;abc&quot;))(&quot;abcdef&quot;,?STARTINDEX)),
+   ?_assertEqual({fail,{expected, {string, &quot;abc&quot;}, ?STARTINDEX}}, (peg:p_string(&quot;abc&quot;))(&quot;defabc&quot;,?STARTINDEX))
   ].
 
 anything_test_() -&gt;
   [
-   ?_assertEqual({$a,&quot;bcde&quot;,{{line,1},{column,2}}}, (peg:anything())(&quot;abcde&quot;,?STARTINDEX)),
-   ?_assertEqual({fail,{expected, any_character, ?STARTINDEX}}, (peg:anything())(&quot;&quot;,?STARTINDEX))
+   ?_assertEqual({$a,&quot;bcde&quot;,{{line,1},{column,2}}}, (peg:p_anything())(&quot;abcde&quot;,?STARTINDEX)),
+   ?_assertEqual({fail,{expected, any_character, ?STARTINDEX}}, (peg:p_anything())(&quot;&quot;,?STARTINDEX))
   ].
 
 charclass_test_() -&gt;
   [
-   ?_assertEqual({$+,&quot;----&quot;,{{line,1},{column,2}}}, (peg:charclass(&quot;[+]&quot;))(&quot;+----&quot;,?STARTINDEX)),
-   ?_assertEqual({fail,{expected, {character_class, &quot;[+]&quot;}, ?STARTINDEX}}, (peg:charclass(&quot;[+]&quot;))(&quot;----&quot;,?STARTINDEX))
+   ?_assertEqual({$+,&quot;----&quot;,{{line,1},{column,2}}}, (peg:p_charclass(&quot;[+]&quot;))(&quot;+----&quot;,?STARTINDEX)),
+   ?_assertEqual({fail,{expected, {character_class, &quot;[+]&quot;}, ?STARTINDEX}}, (peg:p_charclass(&quot;[+]&quot;))(&quot;----&quot;,?STARTINDEX))
   ].</diff>
      <filename>tests/test_combinators.erl</filename>
    </modified>
    <modified>
      <diff>@@ -15,7 +15,7 @@ release_memo_test() -&gt;
 
 step_memo_test() -&gt;
   peg:setup_memo(?MODULE),
-  Result = peg:p(&quot;abcdefghi&quot;, {{line,1},{column,1}}, anything, peg:anything()),
+  Result = peg:p(&quot;abcdefghi&quot;, {{line,1},{column,1}}, anything, peg:p_anything()),
   ?assertEqual({$a, &quot;bcdefghi&quot;, {{line,1},{column,2}}}, Result),
   Result2 = peg:p(&quot;abcdefghi&quot;, {{line,1},{column,1}}, anything, fun(_) -&gt;
                                              throw(bork) end),</diff>
      <filename>tests/test_memoization.erl</filename>
    </modified>
    <modified>
      <diff>@@ -3,4 +3,4 @@
 -include_lib(&quot;eunit/include/eunit.hrl&quot;).
 
 all_test_() -&gt;
-  [{module, test_combinators},{module, test_memoization},{module, test_transform}].
+  [{module, test_combinators},{module, test_memoization}].</diff>
      <filename>tests/test_suite.erl</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>include/peg.hrl</filename>
    </removed>
    <removed>
      <filename>include/peg_i.hrl</filename>
    </removed>
    <removed>
      <filename>src/peg_itransform.erl</filename>
    </removed>
    <removed>
      <filename>src/peg_transform.erl</filename>
    </removed>
    <removed>
      <filename>tests/examples/Emakefile</filename>
    </removed>
    <removed>
      <filename>tests/examples/arithmetic.erl</filename>
    </removed>
    <removed>
      <filename>tests/examples/arithmetic_xf.erl</filename>
    </removed>
    <removed>
      <filename>tests/test_transform.erl</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>84057b99def0825dc6a600c6528d1789f56c71eb</id>
    </parent>
  </parents>
  <author>
    <name>Sean Cribbs</name>
    <email>seancribbs@gmail.com</email>
  </author>
  <url>http://github.com/seancribbs/neotoma/commit/86e09575b6e6abdad173ff78303718309006724b</url>
  <id>86e09575b6e6abdad173ff78303718309006724b</id>
  <committed-date>2009-10-31T12:16:06-07:00</committed-date>
  <authored-date>2009-10-31T12:16:06-07:00</authored-date>
  <message>Big spike: standalone parsers, escape NTs, rename combinators, remove parse_transforms.</message>
  <tree>e036429b13f85b32ff86f6fe1dccf8569f2de711</tree>
  <committer>
    <name>Sean Cribbs</name>
    <email>seancribbs@gmail.com</email>
  </committer>
</commit>
