public static Parser <char, T> Next <T>(Parser <char, T> parser) { return (SkipWhitespaces .Then(Try(CommentParser.SkipBlockComment(String("/*"), String("*/")) .Or(CommentParser.SkipLineComment(String("//")))).Optional() .Then(SkipWhitespaces)) .Then(parser)); }
public static string ParseTomlComment(string input) { // Build parser Parser <char, char> hash = Char('#'); Parser <char, string> comment = hash .Then(SkipWhitespaces.Then(AnyCharExcept('\r', '\n').ManyString())); // Parse var output = comment.ParseOrThrow(input); return(output); }
private void InitScripts() { Input = from t in Path.Before(Whitespace.AtLeastOnce()) from n in Name select new StringInput() { Type = t, Name = n }; Script = from v in OneOf(Try(Public.ThenReturn(true)), Try(Private.ThenReturn(false))).Before(Whitespace.AtLeastOnce()).Optional() from t in Path.Before(Whitespace.AtLeastOnce()) from n in Name.Before(SkipWhitespaces) from i in Input.Separated(Comma.Between(SkipWhitespaces)).Between(OpenParenthesis, CloseParenthesis) from cs in Block(SkipWhitespaces.Then(Lines)) select new StringScript() { IsPublic = v.GetValueOrDefault(false), ReturnType = t, Name = n, Inputs = i, Commands = cs } as StringChild; }
/// <summary> /// Creates and initializes a new <see cref="CommandCompiler"/>. /// </summary> public CommandCompiler() { CommentHead = String("//"); LiteralMarker = Char('#'); CharMarker = Char('\''); StringMarker = Char('\"'); AddressMarker = Char('$'); DirectiveMarker = Char('.'); ReferenceMarker = Char('?'); AnyCommandMarker = OneOf(LiteralMarker, AddressMarker, ReferenceMarker); EnumStart = Char('{'); EnumEnd = Char('}'); ExceptEndLine = AnyCharExcept('\r', '\n'); TrueString = String("true"); FalseString = String("false"); NullString = String("null"); ReservedCommandNames = new string[] { "Define", "Var", "Constant" }; NumLiteral = from l in CurrentPos from n in LiteralMarker.Then(Digit.Or(Char('.')).Or(Char('-')).ManyString()) select new ValueToken() { Value = n, Type = ValueType.Immediate, Position = l }; CharLiteral = from l in CurrentPos from c in Any.Between(CharMarker) select new ValueToken() { Value = c.ToString(), Type = ValueType.Immediate, Position = l }; StringLiteral = from l in CurrentPos from c in AnyCharExcept('\"').ManyString().Between(StringMarker) select new ValueToken() { Value = c.ToString(), Type = ValueType.Immediate, Position = l }; BoolLiteral = from l in CurrentPos from b in OneOf(Try(TrueString), FalseString) select new ValueToken() { Value = b, Type = ValueType.Immediate, Position = l }; EnumLiteral = from l in CurrentPos from e in LetterOrDigit.ManyString().Between(EnumStart, EnumEnd) select new ValueToken() { Value = e, Type = ValueType.Immediate, Position = l }; NullLiteral = from l in CurrentPos from n in NullString select new ValueToken() { Value = string.Empty, Type = ValueType.Immediate, Position = l }; Address = from l in CurrentPos from a in AddressMarker from n in Num select new ValueToken() { Value = n.ToString(), Type = ValueType.Address, Position = l }; Directive = from l in CurrentPos from d in DirectiveMarker from n in LetterOrDigit.Or(DirectiveMarker).ManyString() select new ValueToken() { Value = n, Type = ValueType.Directive, Position = l }; Reference = from l in CurrentPos from r in ReferenceMarker from n in LetterOrDigit.Or(DirectiveMarker).ManyString() select new ValueToken() { Value = n, Type = ValueType.Reference, Position = l }; Value = OneOf( NumLiteral.Labelled("number"), CharLiteral.Labelled("char"), StringLiteral.Labelled("string"), EnumLiteral.Labelled("enum"), Try(BoolLiteral).Labelled("bool"), Try(NullLiteral).Labelled("null"), Address.Labelled("address"), Directive.Labelled("directive"), Reference.Labelled("reference")); CompilerCommand = from l in CurrentPos from c in LetterOrDigit.AtLeastOnceString().Where(n => ReservedCommandNames.Contains(n)).Labelled("reserved command") from v in Try(SkipWhitespaces.Then(Value)).Many() select new CommandCall() { Name = c, Inputs = v.ToArray(), Type = CallType.Compiler, Position = l }; CallCommand = from l in CurrentPos from c in LetterOrDigit.Or(AnyCommandMarker).AtLeastOnceString().Where(n => KnownCommandNames.Contains(n)).Labelled("known command") from v in Try(SkipWhitespaces.Then(Value)).Many() select new CommandCall() { Name = c, Inputs = v.ToArray(), Type = CallType.Command, Position = l }; Command = OneOf(Try(CompilerCommand).Labelled("compiler call"), CallCommand.Labelled("command call")); Code = OneOf( Try(CommentHead.Then(ExceptEndLine.SkipMany())).ThenReturn <CommandCall?>(null).Labelled("comment"), Command.Select <CommandCall?>(c => c)) .SeparatedAndOptionallyTerminatedAtLeastOnce(SkipWhitespaces); }
private static Tuple <Parser <char, Expr>, Stack <bool>, Stack <bool> > BuildExprParser() { Parser <char, Expr> exprParser = null; var listParser = Rec(() => exprParser).Separated(Comma.Before(SkipWhitespaces)); var funcHead = Id.Or(If).Between(SkipWhitespaces).Before(LParen.Between(SkipWhitespaces)); var funcParser = Try(Lookahead(funcHead)).Then(Map((id, prms) => (Expr) new Function(id, prms), funcHead, listParser.Before(RParen))).Labelled("func"); var termParser = funcParser .Or(Try(Bool.Select <Expr>(x => new BoolLit(x))) .Or(Num.Select <Expr>(x => new NumLit(x))) .Or(Str.Select <Expr>(x => new StringLit(x))) .Or(Chr.Select <Expr>(x => new CharLit(x))) .Or(Id.Select <Expr>(x => new Identifier(x))) .Or(Rec(() => listParser) .Between(LBrace.Then(SkipWhitespaces), SkipWhitespaces.Then(RBrace)) .Select <Expr>(x => new Membership(x))) .Or(Rec(() => exprParser) .Between(LParen.Then(SkipWhitespaces), SkipWhitespaces.Then(RParen)) .Select <Expr>(x => new Nested(x))) ).Labelled("term") .Between(SkipWhitespaces.Or(End())); var cTerStack = new Stack <bool>(); var pyTerStack = new Stack <bool>(); exprParser = ExpressionParser.Build(termParser, new[] { // arithmatic new[] { Operator.Prefix(Char('+').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr> >(x => new Positive(x)))), Operator.Prefix(Char('-').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr> >(x => new Negative(x)))), }, new[] { Operator.InfixR(Char('^').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Power(x, y)))), }, new[] { Operator.InfixL(Char('*').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Mult(x, y)))), Operator.InfixL(Char('/').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Div(x, y)))), }, new[] { Operator.InfixL(Char('%').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Mod(x, y)))), }, new[] { Operator.InfixL(Char('+').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Plus(x, y)))), Operator.InfixL(Char('-').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Minus(x, y)))), }, new[] { // VB string cat Operator.InfixL(Try(Lookahead(Not(Char('&').Before(Char('&'))))).Then(Char('&').Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Cat(x, y)))), }, new[] { Operator.InfixL(Try(Lookahead(String("??"))).Then(String("??").Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new NullCoalesce(x, y)))), }, // comparision. TODO: check how to separate arithmatic, comparison and logical ops new[] { Operator.InfixL(Try(String(">=").Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Ge(x, y)))), Operator.InfixL(Try(String("<=").Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Le(x, y)))), Operator.InfixL(Try(String("<>").Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Ne("<>", x, y)))), Operator.InfixL(String("!=").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Ne(x, y)))), Operator.InfixL(String(">").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Gt(x, y)))), Operator.InfixL(String("<").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Lt(x, y)))), Operator.InfixL(Try(String("==")).Or(String("=")).Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Eq(x, y)))), Operator.InfixL(Try(String("in").Between(SkipWhitespaces).Before(Lookahead(LBrace))).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new In(x, y)))), }, // logical. TODO: check how to separate arithmatic, comparison and logical ops new[] { Operator.Prefix(Char('!').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr> >(x => new Not(x)))), }, new[] { Operator.InfixL(String("&&").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new And(x, y)))), }, new[] { Operator.InfixL(String("||").Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => new Or(x, y)))), }, new[] { Operator.InfixR(If.Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => { if (pyTerStack.Count == 0) { throw new InvalidOperationException("Unbalanced Python-style Ternary Operators, fewer 'else' parts than 'then' parts"); } pyTerStack.Pop(); return(TerUtils.FormPyTerExpr(x, y)); }))), Operator.InfixR(Else.Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => { pyTerStack.Push(true); return(new PyTerExprElse(x, y)); }))), Operator.InfixR(Try(Lookahead(Not(Char('?').Before(Char('?'))))).Then(Char('?').Between(SkipWhitespaces)).Then(Return <Func <Expr, Expr, Expr> >((x, y) => { if (cTerStack.Count == 0) { throw new InvalidOperationException("Unbalanced C-style Ternary Operators, fewer 'else' parts than 'then' parts"); } cTerStack.Pop(); return(TerUtils.FormCTerExpr(x, y)); }))), Operator.InfixR(Char(':').Between(SkipWhitespaces).Then(Return <Func <Expr, Expr, Expr> >((x, y) => { cTerStack.Push(true); return(new CTerElseExpr(x, y)); }))), }, }); return(Tuple.Create(exprParser, cTerStack, pyTerStack)); }
private static Parser <char, T> Trim <T>(Parser <char, T> parser) { return(SkipWhitespaces.Then(parser)); }