using Nemerle;
using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;
using Nemerle.Peg;
using Nemerle.Macros;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PegParser
{
public variant TaplAst
{
| Data { data : string }
| Group { data : TaplAst.Sequence }
| Sequence { words : List[TaplAst] }
| UnaryOp { op : string; arg: TaplAst }
| IfElse { cond : TaplAst; arg1: TaplAst; arg2: TaplAst }
}
[PegGrammar(Option = EmitDebugSources, ast,
grammar
{
s = ' '*;
const = ['0'..'9']+ / "false" / "true";
unaries = "succ" / "pred" / "iszero";
unary : TaplAst = unaries s ast;
ifelse : TaplAst = "if" s ast "then" s ast "else" s ast;
data : TaplAst = const s;
word : TaplAst = data / group / ifelse;
group : TaplAst = '(' s ast ')' s;
ast : TaplAst.Sequence = word+;
})]
class TaplParser
{
private data(arg : NToken, _ : NToken) : TaplAst
{
TaplAst.Data(GetText(arg))
}
private unary(op : NToken, _ : NToken, arg : TaplAst.Sequence) : TaplAst
{
TaplAst.UnaryOp(GetText(op), arg)
}
private ifelse(_ : NToken, _ : NToken, cond : TaplAst.Sequence,
_ : NToken, _ : NToken, arg1 : TaplAst.Sequence,
_ : NToken, _ : NToken, arg2 : TaplAst.Sequence) : TaplAst
{
TaplAst.IfElse(cond,arg1,arg2);
}
private word(arg : TaplAst) : TaplAst
{
arg
}
private group(_ : NToken, _ : NToken, ast : TaplAst.Sequence, _ : NToken, _ : NToken) : TaplAst
{
TaplAst.Group(ast)
}
private ast(data : List[TaplAst]) : TaplAst.Sequence
{
TaplAst.Sequence(data)
}
}
module Program
{
Main() : void
{
def myParser = TaplParser();
def myText = "if false then 0 else 1";
def (mpos, mast) = myParser.TryParse(myText);
WriteLine(mpos);
WriteLine(mast);
}
}
}
dXNpbmcgTmVtZXJsZTsKdXNpbmcgTmVtZXJsZS5Db2xsZWN0aW9uczsKdXNpbmcgTmVtZXJsZS5UZXh0Owp1c2luZyBOZW1lcmxlLlV0aWxpdHk7CnVzaW5nIE5lbWVybGUuUGVnOwp1c2luZyBOZW1lcmxlLk1hY3JvczsKCnVzaW5nIFN5c3RlbTsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIFN5c3RlbS5MaW5xOwoKbmFtZXNwYWNlIFBlZ1BhcnNlcgp7CgogICAgcHVibGljIHZhcmlhbnQgVGFwbEFzdAogICAgewogICAgICAgIHwgRGF0YSAgICAgeyBkYXRhICA6IHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgIHwgR3JvdXAgICAgeyBkYXRhICA6IFRhcGxBc3QuU2VxdWVuY2UgICAgICAgICAgICAgICAgICAgICAgfSAKICAgICAgICB8IFNlcXVlbmNlIHsgd29yZHMgOiBMaXN0W1RhcGxBc3RdICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICB8IFVuYXJ5T3AgIHsgb3AgICAgOiBzdHJpbmc7ICBhcmc6ICBUYXBsQXN0ICAgICAgICAgICAgICAgIH0KICAgICAgICB8IElmRWxzZSAgIHsgY29uZCAgOiBUYXBsQXN0OyBhcmcxOiBUYXBsQXN0OyBhcmcyOiBUYXBsQXN0IH0KICAgIH0KCiAgICBbUGVnR3JhbW1hcihPcHRpb24gPSBFbWl0RGVidWdTb3VyY2VzLCBhc3QsCiAgICBncmFtbWFyCiAgICB7CiAgICAgICAgcyAgICAgICAgICAgICAgICAgICAgICAgICA9ICcgJyo7IAogICAgICAgIGNvbnN0ICAgICAgICAgICAgICAgICAgICAgPSBbJzAnLi4nOSddKyAvICJmYWxzZSIgLyAidHJ1ZSI7CiAgICAgICAgdW5hcmllcyAgICAgICAgICAgICAgICAgICA9ICJzdWNjIiAvICJwcmVkIiAvICJpc3plcm8iOwogICAgICAgIHVuYXJ5ICA6IFRhcGxBc3QgICAgICAgICAgPSB1bmFyaWVzIHMgYXN0OwogICAgICAgIGlmZWxzZSA6IFRhcGxBc3QgICAgICAgICAgPSAiaWYiIHMgYXN0ICJ0aGVuIiBzIGFzdCAiZWxzZSIgcyBhc3Q7IAogICAgICAgIGRhdGEgICA6IFRhcGxBc3QgICAgICAgICAgPSBjb25zdCBzOwogICAgICAgIHdvcmQgICA6IFRhcGxBc3QgICAgICAgICAgPSBkYXRhIC8gZ3JvdXAgLyBpZmVsc2U7CiAgICAgICAgZ3JvdXAgIDogVGFwbEFzdCAgICAgICAgICA9ICcoJyBzIGFzdCAnKScgczsKICAgICAgICBhc3QgICAgOiBUYXBsQXN0LlNlcXVlbmNlID0gd29yZCs7CiAgICB9KV0KICAgIGNsYXNzIFRhcGxQYXJzZXIKICAgIHsKCiAgICAgICAgcHJpdmF0ZSBkYXRhKGFyZyA6IE5Ub2tlbiwgXyA6IE5Ub2tlbikgOiBUYXBsQXN0CiAgICAgICAgewogICAgICAgICAgICBUYXBsQXN0LkRhdGEoR2V0VGV4dChhcmcpKQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB1bmFyeShvcCA6IE5Ub2tlbiwgXyA6IE5Ub2tlbiwgYXJnIDogVGFwbEFzdC5TZXF1ZW5jZSkgOiBUYXBsQXN0CiAgICAgICAgewogICAgICAgICAgICBUYXBsQXN0LlVuYXJ5T3AoR2V0VGV4dChvcCksIGFyZykKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaWZlbHNlKF8gOiBOVG9rZW4sIF8gOiBOVG9rZW4sIGNvbmQgOiBUYXBsQXN0LlNlcXVlbmNlLCAKICAgICAgICAgICAgICAgICAgICAgICBfIDogTlRva2VuLCBfIDogTlRva2VuLCBhcmcxIDogVGFwbEFzdC5TZXF1ZW5jZSwgCiAgICAgICAgICAgICAgICAgICAgICAgXyA6IE5Ub2tlbiwgXyA6IE5Ub2tlbiwgYXJnMiA6IFRhcGxBc3QuU2VxdWVuY2UpIDogVGFwbEFzdAogICAgICAgIHsKICAgICAgICAgICAgVGFwbEFzdC5JZkVsc2UoY29uZCxhcmcxLGFyZzIpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB3b3JkKGFyZyA6IFRhcGxBc3QpIDogVGFwbEFzdAogICAgICAgIHsKICAgICAgICAgICAgYXJnCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGdyb3VwKF8gOiBOVG9rZW4sIF8gOiBOVG9rZW4sIGFzdCA6IFRhcGxBc3QuU2VxdWVuY2UsIF8gOiBOVG9rZW4sIF8gOiBOVG9rZW4pIDogVGFwbEFzdAogICAgICAgIHsKICAgICAgICAgICAgVGFwbEFzdC5Hcm91cChhc3QpCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGFzdChkYXRhIDogTGlzdFtUYXBsQXN0XSkgOiBUYXBsQXN0LlNlcXVlbmNlCiAgICAgICAgewogICAgICAgICAgICBUYXBsQXN0LlNlcXVlbmNlKGRhdGEpCiAgICAgICAgfQogICAgfQoKbW9kdWxlIFByb2dyYW0KewogICAgTWFpbigpIDogdm9pZAogICAgewogICAgICAgIGRlZiBteVBhcnNlciA9IFRhcGxQYXJzZXIoKTsKICAgICAgICBkZWYgbXlUZXh0ID0gImlmIGZhbHNlIHRoZW4gMCBlbHNlIDEiOwogICAgICAgIGRlZiAobXBvcywgbWFzdCkgPSBteVBhcnNlci5UcnlQYXJzZShteVRleHQpOwogICAgICAgIFdyaXRlTGluZShtcG9zKTsKICAgICAgICBXcml0ZUxpbmUobWFzdCk7CiAgICB9Cn0KCn0K