private static Identifier IdentifierMatch(SlimChainParser cp, params string[] match) { var value = string.Empty; return cp.Begin .Text(t => value = t.Text, match).Lt() .End(tp => new Identifier(tp, value, TokenType.Unknoun)); }
private static IReadOnlyList<Element> ExpressionList(SlimChainParser cp, bool isBlock) { var child = new List<Element>(); InsideParser cond; if (isBlock) { cp = cp.Type(TokenType.LeftBrace); cond = icp => icp.Not.Type(TokenType.RightBrace); } else { cond = icp => icp.Readable(); } cp.Opt.Call(ExpressionSeparators) .Any( iicp => iicp.Transfer(e => child.Add(e), Expression), iicp => iicp.AddError() ) .Loop(cond, icp => { icp.Opt.Call(ExpressionSeparators) .Opt.Any( iicp => iicp.Transfer(e => child.Add(e), Expression), iicp => iicp.AddError() ); }) .Opt.Call(ExpressionSeparators); return child; }
private static GotoStatement GotoStatement(SlimChainParser cp) { Element exp = null; return cp.Begin .Text("goto").Lt() .Opt.Transfer(e => exp = e, Expression) .End(tp => new GotoStatement(tp, exp)); }
private static ProgramContext BlockContext(SlimChainParser cp) { IReadOnlyList<Element> child = null; var result = cp.Begin .Call(c => child = c, icp => ExpressionList(icp, true)) .End(tp => new ProgramContext(tp, child, false)); return result; }
private static GroupingExpression GroupingExpression(SlimChainParser cp) { Element exp = null; return cp.Begin .Type(TokenType.LeftParenthesis).Lt() .Transfer(e => exp = e, Expression) .Type(TokenType.RightParenthesis).Lt() .End(tp => new GroupingExpression(tp, exp)); }
private static Identifier Identifier(SlimChainParser cp) { var identType = TokenType.Unknoun; var value = string.Empty; return cp.Begin .Opt.Type(t => identType = t.TokenType, TokenType.Pragma, TokenType.Macro, TokenType.Nullable).Lt() .Type(t => value = t.Text, TokenType.LetterStartString).Lt() .End(tp => new Identifier(tp, value, identType)); }
private static Element MemberAccess(Element current, SlimChainParser cp) { var member = string.Empty; var ret = cp.Begin .Type(TokenType.Access).Lt() .Take(t => member = t.Text).Lt() .End(tp => new MemberAccess(tp, current, member)); return ret == null ? WithExpression(current, cp) : Postfix(ret, cp); }
private static CatchStatement CatchStatement(SlimChainParser cp) { Element use = null; ProgramContext block = null; return cp.Begin .Text("catch") .Transfer(e => use = e, Expression) .Transfer(e => block = e, InlineContext) .End(tp => new CatchStatement(tp, use, block)); }
private static AliasDeclaration AliasDeclaration(SlimChainParser cp) { Identifier from = null; Identifier to = null; return cp.Begin .Text("alias").Lt() .Opt.Transfer(e => to = e, Identifier) .Opt.Transfer(e => from = e, Identifier) .End(tp => new AliasDeclaration(tp, from, to)); }
private static NumericLiteral NumericLiteral(SlimChainParser cp) { var integral = string.Empty; var fraction = string.Empty; return cp.Begin .Type(t => integral = t.Text, TokenType.DigitStartString).Lt() .If(icp => icp.Type(TokenType.Access).Lt()) .Then(icp => icp.Type(t => fraction = t.Text, TokenType.DigitStartString).Lt()) .End(tp => new NumericLiteral(tp, integral, fraction)); }
private static AssociatePair AssociatePair(SlimChainParser cp) { Element left = null; Element right = null; return cp.Begin .Transfer(e => left = e, NakedRangeLiteral) .Type(TokenType.Pair) .Transfer(e => right = e, NakedRangeLiteral) .End(tp => new AssociatePair(tp, left, right)); }
private static Element NakedRangeLiteral(SlimChainParser cp) { Element left = null; Element right = null; var ret = cp.Begin .Transfer(e => left = e, LeftCompose) .Type(TokenType.Range) .Transfer(e => right = e, LeftCompose) .End(tp => new RangeLiteral(tp, left, right)); return ret ?? LeftCompose(cp); }
private static EnsureStatement EnsureStatement(SlimChainParser cp) { Element use = null; ProgramContext block = null; return cp.Begin .Text("ensure") .If(icp => icp.Transfer(e => use = e, Expression)) .Then(icp => icp.Transfer(e => block = e, InlineContext)) .Else(icp => icp.Transfer(e => block = e, DirectContext)) .End(tp => new EnsureStatement(tp, use, block)); }
private static TupleLiteral NakedArgument(SlimChainParser cp) { Element literal = null; return cp.Begin .Any( icp => icp.Transfer(e => literal = e, StringLiteral), icp => icp.Transfer(e => literal = e, HereDocument), icp => icp.Transfer(e => literal = e, RangeLiteral), icp => icp.Transfer(e => literal = e, LambdaLiteral) ) .End(tp => new TupleLiteral(tp, literal)); }
private static ProgramContext EnumContext(SlimChainParser cp) { IReadOnlyList<Element> child = null; var isInline = true; return cp.Begin .Any( icp => icp.Opt.Type(TokenType.Separator).Type(TokenType.EndExpression), icp => icp.Type(TokenType.Separator).Transfer(e => child = new Element[] { e }, EnumField).Lt().Opt.Type(TokenType.EndExpression), icp => icp.Opt.Type(TokenType.Separator).Call(c => child = c, EnumList).Self(() => isInline = false) ) .End(tp => new ProgramContext(tp, child, isInline)); }
private static DictionaryLiteral DictionaryLiteral(SlimChainParser cp) { var pairs = new List<AssociatePair>(); return cp.Begin .Type(TokenType.LeftBracket).Lt() .Loop(icp => { icp.Transfer(e => pairs.Add(e), AssociatePair) .Type(TokenType.List).Lt(); }) .Type(TokenType.RightBracket).Lt() .End(tp => new DictionaryLiteral(tp, pairs)); }
private static ArrayLiteral ArrayLiteral(SlimChainParser cp) { var values = new List<Element>(); return cp.Begin .Type(TokenType.LeftBracket).Lt() .Loop(icp => { icp.Transfer(e => values.Add(e), NakedRangeLiteral) .Type(TokenType.List).Lt(); }) .Type(TokenType.RightBracket).Lt() .End(tp => new ArrayLiteral(tp, values)); }
private static TupleLiteral ArgumentList(SlimChainParser cp) { var child = new List<Element>(); var ret = cp.Begin .Type(TokenType.LeftParenthesis).Lt() .Loop(icp => { icp .Transfer(e => child.Add(e), ArgumentDeclaration) .Type(TokenType.List).Lt(); }) .Type(TokenType.RightParenthesis).Lt() .End(tp => new TupleLiteral(tp, child)); return ret ?? new TupleLiteral(); }
private static ArgumentDeclaration ArgumentDeclaration(SlimChainParser cp) { var type = VariantType.Var; var name = string.Empty; TupleLiteral attr = null; Element expli = null; Element def = null; return cp.Begin .Any( icp => icp.Call(iicp => ArgumentPart(iicp, out type, out name, out attr, out expli)).Type(TokenType.LeftPipeline).Transfer(e => def = e, NakedRangeLiteral), icp => icp.Transfer(e => def = e, NakedRangeLiteral).Type(TokenType.RightPipeline).Call(iicp => ArgumentPart(iicp, out type, out name, out attr, out expli)), icp => icp.Call(iicp => ArgumentPart(iicp, out type, out name, out attr, out expli)) ) .End(tp => new ArgumentDeclaration(tp, type, name, attr, expli, def)); }
private static ForStatement ForStatement(SlimChainParser cp) { Element cond = null; Element of = null; Element at = null; ProgramContext block = null; return cp.Begin .Text("for").Lt() .Opt.Transfer(e => cond = e, Expression) .If(icp => icp.Text("of").Lt()) .Then(icp => icp.Transfer(e => of = e, DefaultValueVariantDeclaration)) .If(icp => icp.Text("at").Lt()) .Then(icp => icp.Transfer(e => at = e, DefaultValueVariantDeclaration)) .Transfer(e => block = e, InlineContext) .End(tp => new ForStatement(tp, cond, of, at, block)); }
private static IReadOnlyList<Element> EnumList(SlimChainParser cp) { var child = new List<Element>(); cp.Opt.Call(ExpressionSeparators) .Any( iicp => iicp.Transfer(e => child.Add(e), EnumField), iicp => iicp.AddError() ) .Loop(icp => icp.Not.Type(TokenType.RightBrace), icp => { icp.Opt.Call(ExpressionSeparators) .Opt.Any( iicp => iicp.Transfer(e => child.Add(e), EnumField), iicp => iicp.AddError() ); }) .Opt.Call(ExpressionSeparators); return child; }
public void Else(string text, int expected) { var tc = Lexer.Lex(text, string.Empty); var cp = new SlimChainParser(tc); var ret = cp.Begin.Text("test") .If(icp => icp.Type(TokenType.LeftParenthesis)) .Then(icp => icp.Type(TokenType.LetterStartString).Type(TokenType.RightParenthesis)) .Else(icp => icp.Type(TokenType.LeftBracket).Type(TokenType.LetterStartString).Type(TokenType.RightBracket)) .End(tp => new TupleLiteral(tp, (Element)null)); if (expected == 0) { Assert.That(ret, Is.Null); } else { Assert.That(ret, Is.Not.Null); Assert.That(ret.Position.Length, Is.EqualTo(expected)); } }
private static void ArgumentPart(SlimChainParser cp, out VariantType type, out string name, out TupleLiteral attr, out Element expli) { var ty = VariantType.Var; var n = string.Empty; TupleLiteral a = null; Element ex = null; cp.Transfer(e => a = e, AttributeList) .Opt.Any( icp => icp.Text("var").Self(() => ty = VariantType.Var), icp => icp.Text("let").Self(() => ty = VariantType.Let), icp => icp.Text("const").Self(() => ty = VariantType.Const) ).Lt() .Type(t => n = t.Text, TokenType.LetterStartString).Lt() .If(icp => icp.Type(TokenType.Pair).Lt()) .Then(icp => icp.Transfer(e => ex = e, Prefix)); type = ty; name = n; attr = a; expli = ex; }
private static Element CallExpression(Element current, SlimChainParser cp) { TupleLiteral args = null; var ret = cp.Begin .If(icp => icp.Transfer(e => args = e, NakedArgument).Lt()) .ElseIf(icp => icp.Type(TokenType.LeftParenthesis).Lt()) .Then(icp => { icp.Transfer(e => args = e, TupleLiteral) .Type(TokenType.RightParenthesis).Lt(); }) .Else(icp => { icp.Type(TokenType.LeftBracket).Lt() .Transfer(e => args = e, TupleLiteral) .Type(TokenType.RightBracket).Lt(); }) .End(tp => new CallExpression(tp, current, args)); return ret == null ? TemplateInstance(current, cp) : Postfix(ret, cp); }
public void Any(string text, int expected) { var tc = Lexer.Lex(text, string.Empty); var cp = new SlimChainParser(tc); var ret = cp.Begin.Text("test") .Any( icp => icp.Type(TokenType.LetterStartString), icp => icp.Type(TokenType.DigitStartString) ) .End(tp => new TupleLiteral(tp, (Element)null)); if (expected == 0) { Assert.That(ret, Is.Null); } else { Assert.That(ret, Is.Not.Null); Assert.That(ret.Position.Length, Is.EqualTo(expected)); } }
private static Element Postfix(Element current, SlimChainParser cp) { var op = TokenType.Unknoun; var ret = cp.Begin .Type(t => op = t.TokenType, TokenType.Refer, TokenType.Typeof, TokenType.Reject).Lt() .End(tp => new Postfix(tp, op, current)); return ret == null ? MemberAccess(current, cp) : Postfix(ret, cp); }
private static Element Postfix(SlimChainParser cp) { var current = Primary(cp); return current == null ? null : Postfix(current, cp); }
private static Element Multiplicative(SlimChainParser cp) { return LeftAssociative(cp, (tp, op, l, r) => new Calculate(tp, op, l, r), Prefix, TokenType.Multiply, TokenType.Divide, TokenType.Modulo); }
private static Element Logical(SlimChainParser cp) { return LeftAssociative(cp, (tp, op, l, r) => new Logical(tp, op, l, r), Compare, TokenType.And, TokenType.Or); }
private static Element LeftPipeline(SlimChainParser cp) { return RightAssociative(cp, (tp, op, l, r) => new LeftPipeline(tp, op, l, r), RightPipeline, TokenType.LeftPipeline); }