private static Grammar MakeParser() { // Literals var ws = Terminals.WhiteSpace.Repeat(0); var comma = ws.Then(Terminals.Set(','), ws); var subExpressionAccess = ws.Then(Terminals.Set('.'), ws); var number = new NumberParser { AllowDecimal = true, AllowExponent = true, AllowSign = true, ValueType = typeof(float) }; var identifier = Terminals.Letter.Or(Terminals.Set(_identifierAllowedCharacters)) .Then(Terminals.LetterOrDigit.Or(Terminals.Set(_identifierAllowedCharacters)).Repeat(0)); // Expressions var expression = new UnaryParser(); var subExpression = expression.Named(ElementAST.SubExpressionRoot) .Then(subExpressionAccess, identifier.Named(ElementAST.SubExpressionName)); var arguments = expression.Named(ElementAST.CallArgument).Repeat(0).SeparatedBy(comma); var call = expression.Named(ElementAST.Callee) .Then(ws, Terminals.Set('('), ws, arguments.Named(ElementAST.CallArguments), ws, Terminals.Set(')')); expression.Inner = new AlternativeParser( number.Named(ElementAST.NumberExpression), identifier.Named(ElementAST.VariableExpression), subExpression.Named(ElementAST.SubExpression), call.Named(ElementAST.CallExpression) ); // Functions var portType = ws.Then(Terminals.Literal(":"), ws, identifier.Named(ElementAST.PortType)).Optional(); var port = identifier.Named(ElementAST.PortName).Then(portType).Named(ElementAST.Port); var ports = port.Repeat(0).SeparatedBy(comma); var fnInputs = Terminals.Set('(') .Then(ws, ports.Named(ElementAST.FunctionInputs), ws, Terminals.Set(')')).Optional(); var fnOutputs = Terminals.Literal("->").Then(ws, ports.Named(ElementAST.FunctionOutputs)).Or(portType); var fnSignature = identifier.Named(ElementAST.FunctionName).Then(ws, fnInputs, ws, fnOutputs, ws); // Statements var statement = new UnaryParser(); var body = Terminals.Set('{').Then(ws, statement.Then(ws).Repeat(0).Named(ElementAST.FunctionBody), ws, Terminals.Set('}')); var assign = Terminals.Set('=').Then(ws, expression.Named(ElementAST.AssignmentStatement), ws, Terminals.Set(';')); statement.Inner = fnSignature .Then(body.Or(assign).Or(Terminals.Set(';').Named(ElementAST.TypeStatement))) .Named(ElementAST.Statement); var start = ws.Then(statement, ws).Repeat(0); start.Until = Terminals.End; return(new Grammar(start)); }