/// <summary> /// Generates a production that converts the parsing result of a terminal using a specific converting rule. /// In other words, generates a 'mapping' production from a token /// </summary> /// <typeparam name="TResult">The type of the converted parsing result</typeparam> /// <param name="token">The token used as the source terminal production whose parsing result will be converted.</param> /// <param name="selector">The delegate that represents the converting rule</param> /// <returns>The generated 'mapping' production object</returns> /// <example> /// The following code converts the parsing result of a terminal into string with some formatting. /// <code language="C#"> /// Token T; //initialized in somewhere /// /// var formatting = /// from z in T /// select String.Format("Token is {0}", z.Value); /// </code> /// </example> public static ProductionBase <TResult> Select <TResult>(this Token token, Func <Lexeme, TResult> selector) { CodeContract.RequiresArgumentNotNull(token, "token"); CodeContract.RequiresArgumentNotNull(selector, "selector"); return(new MappingProduction <Lexeme, TResult>(token.AsTerminal(), selector)); }
public static ProductionBase <TResult> SelectMany <TResult>(this Token token, Func <Lexeme, Token> productionSelector, Func <Lexeme, Lexeme, TResult> resultSelector) { CodeContract.RequiresArgumentNotNull(token, "token"); CodeContract.RequiresArgumentNotNull(productionSelector, "productionSelector"); CodeContract.RequiresArgumentNotNull(resultSelector, "resultSelector"); return(new ConcatenationProduction <Lexeme, Lexeme, TResult>(token.AsTerminal(), v => productionSelector(v).AsTerminal(), resultSelector)); }
protected override ProductionBase <IEnumerable <StatementNode> > OnDefineGrammar() { Production <IEnumerable <StatementNode> > Statements = new Production <IEnumerable <StatementNode> >(); Production <StatementNode> Statement = new Production <StatementNode>(); Production <StatementNode> VarDeclStatement = new Production <StatementNode>(); Production <StatementNode> ExpressionStatement = new Production <StatementNode>(); Production <ExpressionNode> Expression = new Production <ExpressionNode>(); Production <ExpressionNode> Comparison = new Production <ExpressionNode>(); Statements.Rule = Statement.Many(); Statement.Rule = VarDeclStatement | ExpressionStatement; Statement.AmbiguityAggregator = (s1, s2) => new AmbiguityStatementNode(s1, s2); VarDeclStatement.Rule = from typename in ID from _less in LESS from genericTypename in ID from _greater in GREATER from varname in ID from _st in SEMICOLON select new VarDeclStatementNode(typename, genericTypename, varname) as StatementNode; ExpressionStatement.Rule = from expression in Expression from _st in SEMICOLON select new ExpressionStatementNode(expression) as StatementNode; var BasicExpression = from exp in ID.AsTerminal() | NUM.AsTerminal() select new BasicExpressionNode(exp) as ExpressionNode; Expression.Rule = BasicExpression | Comparison; Comparison.Rule = BasicExpression | from left in Comparison from op in LESS.AsTerminal() | GREATER.AsTerminal() from right in BasicExpression select new BinaryExpressionNode(op, left, right) as ExpressionNode; return(Statements); }
protected override ProductionBase <Program> OnDefineGrammar() { PProgram.Rule = // MainClass ClassDecl* from main in PMainClass from classes in PClassDecl.Many() select new Program(main, classes.ToArray()); PMainClass.Rule = // static class id { public static void Main(string[] id) { statement }} from _static1 in K_STATIC from _class in K_CLASS from className in ID from _1 in LEFT_BR from _public in K_PUBLIC from _static2 in K_STATIC from _void in K_VOID from _main in K_MAIN from _2 in LEFT_PH from _string in K_STRING from _3 in LEFT_BK from _4 in RIGHT_BK from arg in ID from _5 in RIGHT_PH from _6 in LEFT_BR from statements in PStatement.Many1() from _7 in RIGHT_BR from _8 in RIGHT_BR select new MainClass(className.Value, arg.Value, statements.ToArray()); var classMembers = from _1 in LEFT_BR from varDecls in PFieldDecl.Many() from methodDecls in PMethodDecl.Many() from _2 in RIGHT_BR select new { Fields = varDecls.ToArray(), Methods = methodDecls.ToArray() }; var classDeclSimple = // { VarDecl* MethodDecl* } from members in classMembers select new { BaseClassName = default(Lexeme), Members = members }; var classDeclInherits = //: id { VarDecl* MethodDecl* } from _1 in COLON from baseClassName in ID from members in classMembers select new { BaseClassName = baseClassName, Members = members }; PClassDecl.Rule = //class id from _class in K_CLASS from className in ID from def in (classDeclSimple | classDeclInherits) select new ClassDecl(className.Value, def.BaseClassName.GetValue(), def.Members.Fields, def.Members.Methods); PFieldDecl.Rule = // Type id; from type in PType from varName in ID from _sc in SEMICOLON select new FieldDecl(type, varName.Value); var methodBody = from _1 in LEFT_BR from statements in PStatement.Many() from _return in K_RETURN from returnExp in PExp from _sc in SEMICOLON from _2 in RIGHT_BR select new { Statements = statements.ToArray(), ReturnExp = returnExp }; var methodNoBody = from _sc in SEMICOLON select new { Statements = default(Statement[]), ReturnExp = default(Expression) }; PMethodDecl.Rule = // public Type id (FormalList) { Statement* return Exp; } from _public in K_PUBLIC from type in PType from methodName in ID from _1 in LEFT_PH from formals in PFormalList from _2 in RIGHT_PH from body in (methodBody | methodNoBody) select new MethodDecl(methodName.Value, type, formals, body.Statements, body.ReturnExp); var paramFormal = from paramType in PType from paramName in ID select new Formal(paramType, paramName.Value); PFormalList.Rule = // Type id FormalRest* | <empty> from list in paramFormal.Many(COMMA) select list.ToArray(); PType.Rule = // int[] | bool | int | id PIntArrayType | PBoolType | PIntType | PIdType; PIntArrayType.Rule = //int[] from _int in K_INT from _lb in LEFT_BK from _rb in RIGHT_BK select(Ast.Type) new IntArrayType(); PBoolType.Rule = // bool from _bool in K_BOOL select(Ast.Type) new BooleanType(); PIntType.Rule = // int from _int in K_INT select(Ast.Type) new IntegerType(); PIdType.Rule = // id from type in ID select(Ast.Type) new IdentifierType(type.Value); //statements PStatement.Rule = // { statement*} | ifelse | while | writeline | assign | array assign | var decl (from _1 in LEFT_BR from stmts in PStatement.Many() from _2 in RIGHT_BR select(Statement) new Block(stmts.ToArray())) | PIfElse | PWhile | PWriteLine | PAssignment | PArrayAssignment | PVarDeclStmt; PIfElse.Rule = // if ( exp ) statement else statement from _if in K_IF from _1 in LEFT_PH from condExp in PExp from _2 in RIGHT_PH from truePart in PStatement from _else in K_ELSE from falsePart in PStatement select(Statement) new IfElse(condExp, truePart, falsePart, _if.Value.Span, _else.Value.Span); PWhile.Rule = // while ( exp ) statement from _while in K_WHILE from _1 in LEFT_PH from condExp in PExp from _2 in RIGHT_PH from loopBody in PStatement select(Statement) new While(condExp, loopBody, _while.Value.Span); PWriteLine.Rule = // System.Console.WriteLine( exp ); from _sys in K_SYSTEM from _1 in DOT from _console in K_CONSOLE from _2 in DOT from _wl in K_WRITELINE from _3 in LEFT_PH from exp in PExp from _4 in RIGHT_PH from _sc in SEMICOLON select(Statement) new WriteLine(exp, new SourceSpan(_sys.Value.Span.StartLocation, _wl.Value.Span.EndLocation)); PAssignment.Rule = // id = exp; from variable in ID from _eq in ASSIGN from value in PExp from _sc in SEMICOLON select(Statement) new Assign(variable.Value, value); PArrayAssignment.Rule = // id[ exp ] = exp ; from variable in ID from _1 in LEFT_BK from index in PExp from _2 in RIGHT_BK from _eq in ASSIGN from value in PExp from _sc in SEMICOLON select(Statement) new ArrayAssign(variable.Value, index, value); PVarDeclStmt.Rule = // Type id; from type in PType from varName in ID from _sc in SEMICOLON select(Statement) new VarDecl(type, varName.Value); //expressions //basic PNumberLiteral.Rule = // number from intvalue in INTEGER_LITERAL select(Expression) new IntegerLiteral(intvalue.Value); PBoolLiteral.Rule = // true | false from b in K_TRUE.AsTerminal() | K_FALSE.AsTerminal() select(Expression) new BooleanLiteral(b.Value); PThis.Rule = // this from _this in K_THIS select(Expression) new This(_this.Value.Span); PVariable.Rule = // id from varName in ID select(Expression) new Variable(varName.Value); PNewObj.Rule = // new id() from _new in K_NEW from typeName in ID from _1 in LEFT_PH from _2 in RIGHT_PH select(Expression) new NewObject(typeName.Value); PNewArray.Rule = // new int [exp] from _new in K_NEW from _int in K_INT from _1 in LEFT_BK from length in PExp from _2 in RIGHT_BR select(Expression) new NewArray(length, new SourceSpan(_1.Value.Span.EndLocation, _2.Value.Span.StartLocation)); var foundationExp = // (exp) | number literal | true | false | this | id | new PNumberLiteral | PBoolLiteral | PThis | PVariable | PNewObj | PNewArray | PExp.PackedBy(LEFT_PH, RIGHT_PH); PCall.Rule = // exp.id(explist) from exp in foundationExp from _d in DOT from methodName in ID from _1 in LEFT_PH from args in PExpList from _2 in RIGHT_PH select(Expression) new Call(exp, methodName.Value, args); PArrayLookup.Rule = // exp[exp] from exp in foundationExp from _1 in LEFT_BK from index in PExp from _2 in RIGHT_BK select(Expression) new ArrayLookup(exp, index, new SourceSpan(_1.Value.Span.EndLocation, _2.Value.Span.StartLocation)); PArrayLength.Rule = // exp.Length from exp in foundationExp from _d in DOT from _length in K_LENGTH select(Expression) new ArrayLength(exp, _length.Value.Span); var basicExp = foundationExp | PCall | PArrayLookup | PArrayLength; //foundation >> call | id[exp] | id.Length //unary PNot.Rule = // ! exp basicExp | from _n in LOGICAL_NOT from exp in PNot select(Expression) new Not(exp, _n.Value.Span); //binary PFactor.Rule = // exp | !exp PNot; PTerm.Rule = // term * factor | factor PFactor | from term in PTerm from op in (ASTERISK.AsTerminal() | SLASH.AsTerminal()) from factor in PFactor select(Expression) new Binary(op.Value, term, factor); PComparand.Rule = // comparand + term | term PTerm | from comparand in PComparand from op in (PLUS.AsTerminal() | MINUS.AsTerminal()) from term in PTerm select(Expression) new Binary(op.Value, comparand, term); PComparison.Rule =// comparison < comparand | comparand PComparand | from comparison in PComparison from op in (LESS.AsTerminal() | GREATER.AsTerminal() | EQUAL.AsTerminal()) from comparand in PComparand select(Expression) new Binary(op.Value, comparison, comparand); PAnd.Rule = // andexp && comparison | comparison PComparison | from andexp in PAnd from op in LOGICAL_AND from comparison in PComparison select(Expression) new Binary(op.Value, andexp, comparison); POr.Rule = PAnd | from orexp in POr from op in LOGICAL_OR from andexp in PAnd select(Expression) new Binary(op.Value, orexp, andexp); PExp.Rule = POr; PExpList.Rule = from list in PExp.Many(COMMA) select list.ToArray(); return(PProgram); }
public static ProductionBase <Lexeme> Optional(this Token token) { CodeContract.RequiresArgumentNotNull(token, "token"); return(token.AsTerminal().Optional()); }
public static ProductionBase <IEnumerable <Lexeme> > Many1(this Token token, Token separator) { CodeContract.RequiresArgumentNotNull(token, "token"); return(token.AsTerminal().Many1(separator.AsTerminal())); }
public static ProductionBase <IEnumerable <T> > Many1 <T>(this ProductionBase <T> production, Token seperator) { CodeContract.RequiresArgumentNotNull(production, "production"); return(production.Many1(seperator.AsTerminal())); }
public static ProductionBase <Lexeme> Where(this Token token, Expression <Func <Lexeme, bool> > predicate) { return(token.AsTerminal().Where(predicate)); }