public void Define() { /* case <expression>: * <expression> */ var caseBlock = new NonTerminal("case_block"); caseBlock.Rule = grammar.Keywords.Case + grammar.expression + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; // List of case block expressions. var caseBlockList = new NonTerminal("case_block_list"); caseBlockList.Rule = grammar.MakeStarRule(caseBlockList, caseBlock); // The list of case block expressions is optional. var caseBlockListOpt = new NonTerminal("case_block_list_opt"); caseBlockListOpt.Rule = (grammar.Indent + caseBlockList + grammar.Dedent) | grammar.Empty; /* switch <expression>: * case <expression>: * <expression> */ SwitchBlock.Rule = grammar.Keywords.Switch + grammar.expression + grammar.ToTerm(":") + grammar.Eos + caseBlockListOpt; }
public void Define() { // the valid modifiers for an enum: public or internal var validModifiers = new NonTerminal("enum_valid_modifiers"); validModifiers.Rule = grammar.Keywords.Public | grammar.Keywords.Internal; grammar.MarkTransient(validModifiers); // Enums can have no or multiple modifiers var modifier = new NonTerminal("enum_modifiers"); modifier.Rule = grammar.MakeStarRule(modifier, validModifiers); // A constant that simply a name, and that will have a value automatically assigned. var identifierConstant = new NonTerminal("identifier_constant"); identifierConstant.Rule = grammar.Identifier + grammar.Eos; // A constant that is assigned a value by the programmer var assignmentConstant = new NonTerminal("assignment_constant"); assignmentConstant.Rule = grammar.Identifier + grammar.ToTerm("=") + grammar.Literals.NumberLiteral + grammar.Eos; // List of valid members of an enum: the previous two constant rules. var enumValidMembers = new NonTerminal("enum_valid_members"); enumValidMembers.Rule = identifierConstant | assignmentConstant; // The list of members in the enum. var enumMemberList = new NonTerminal("enum_member_list"); enumMemberList.Rule = grammar.MakeStarRule(enumMemberList, enumValidMembers); // The enum body is an indent, the list of members, and a dedent. var enumBody = new NonTerminal("enum_body"); enumBody.Rule = grammar.Indent + enumMemberList + grammar.Dedent; grammar.MarkTransient(enumBody); // The enum body is optional var enumListOpt = new NonTerminal("enum_list_opt"); enumListOpt.Rule = grammar.Empty | enumBody; /* enum foo: * bar * bar2 = 24 */ EnumDeclaration.Rule = modifier + grammar.Keywords.Enum + grammar.Identifier + grammar.ToTerm(":") + grammar.Eos + enumListOpt; }
public void Define() { var validParameters = new NonTerminal("valid_parameters"); var simpleParameter = new NonTerminal("simple_parameter"); var outParameter = new NonTerminal("out_parameter"); var arrayParameter = new NonTerminal("array_parameter"); var genericParameter = new NonTerminal("generic_parameter"); var methodStatementsList = new NonTerminal("method_statements_list"); var methodBody = new NonTerminal("method_body"); var genericTypeListEos = new NonTerminal("generic_type_list_eos"); // Comma separated list of zero or more valid method parameters ParameterList.Rule = grammar.MakeStarRule(ParameterList, grammar.ToTerm(","), validParameters); // Valid parameters are simple ones: "int i", arrays "int [] i", directioned "ref int i" or generic "List{int} i" validParameters.Rule = simpleParameter | outParameter | arrayParameter | genericParameter; simpleParameter.Rule = grammar.Identifier + grammar.Identifier; outParameter.Rule = (grammar.Keywords.Out | grammar.Keywords.Ref) + grammar.Identifier + grammar.Identifier; arrayParameter.Rule = grammar.Identifier + grammar.ToTerm("[") + grammar.ToTerm("]") + grammar.Identifier; genericParameter.Rule = grammar.GenericIdentifier + grammar.Identifier; var validModifiers = new NonTerminal("valid_method_modifiers"); validModifiers.Rule = grammar.Keywords.Public | grammar.Keywords.Internal | grammar.Keywords.Abstract | grammar.Keywords.Shared | grammar.Keywords.Protected | grammar.Keywords.Private | grammar.Keywords.Virtual | grammar.Keywords.Final | grammar.Keywords.Override; grammar.MarkTransient(validModifiers); // Modifiers are zero or more from the list of valid ones. Modifier.Rule = grammar.MakeStarRule(Modifier, validModifiers); // "member header" is a Modifier followed by two identifiers. MemberHeader.Rule = Modifier + grammar.TwoIdentifiers; // Method body is a list of statements between an indent and a dedent. methodBody.Rule = grammar.Indent + methodStatementsList + grammar.Dedent; OptionalMethodBody.Rule = grammar.Empty | methodBody; // The list of statements in a method is a list of zero or more expressions. methodStatementsList.Rule = grammar.MakeStarRule(methodStatementsList, grammar.expression); MethodDeclaration.Rule = MemberHeader + grammar.Classes.GenericTypeListOpt + grammar.OpenParenthese + ParameterList + grammar.CloseParenthese + grammar.ToTerm(":") + grammar.Eos + OptionalMethodBody; }
public void Define() { // throw <expression> ThrowStatement.Rule = grammar.Keywords.Throw + grammar.expression + (grammar.Eos | grammar.Empty); // try: var tryBlock = new NonTerminal("try_block"); tryBlock.Rule = grammar.Keywords.Try + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; // catch Exception e: var catchBlock = new NonTerminal("catch_block"); catchBlock.Rule = grammar.Keywords.Catch + grammar.Identifier + grammar.Identifier + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; // The catch blocks are optional var catchBlockOpt = new NonTerminal("catch_block_opt"); catchBlockOpt.Rule = grammar.MakeStarRule(catchBlockOpt, catchBlock); // finally: var finallyBlock = new NonTerminal("finally_block"); finallyBlock.Rule = grammar.Keywords.Finally + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; // The finally block is optional var finallyBlockOpt = new NonTerminal("finally_block_opt"); finallyBlockOpt.Rule = finallyBlock | grammar.Empty; /* * try: * catch Exception ex: * finally: */ ExceptionHandlingBlock.Rule = tryBlock + catchBlockOpt + finallyBlockOpt; }
public void Define() { // The valid modifiers for a constructor: public, proteted, or private. var ctorValidModifiers = new NonTerminal("constructor_modifiers"); ctorValidModifiers.Rule = grammar.Keywords.Public | grammar.Keywords.Protected | grammar.Keywords.Private; // The call to the base constructor. var ctorBase = new NonTerminal("constructor_base"); ctorBase.Rule = grammar.ToTerm("base") + grammar.OpenParenthese + grammar.ArgumentList + grammar.CloseParenthese + grammar.ToTerm(":"); // The call to another constructor in the same class. var ctorThis = new NonTerminal("constructor_this"); ctorThis.Rule = grammar.ToTerm("this") + grammar.OpenParenthese + grammar.ArgumentList + grammar.CloseParenthese + grammar.ToTerm(":"); // Optional call to base or this constructors. var ctorSubOpt = new NonTerminal("constructor_sub_opt"); ctorSubOpt.Rule = ctorBase | ctorThis | grammar.Empty; /* new(int foo):base(foo):*/ ConstructorDeclaration.Rule = grammar.MethodDeclarations.Modifier + grammar.Keywords.New + grammar.OpenParenthese + grammar.MethodDeclarations.ParameterList + grammar.CloseParenthese + grammar.ToTerm(":") + ctorSubOpt + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; }
public void Define() { // get: // <expression> var getBlock = new NonTerminal("get_block"); getBlock.Rule = grammar.Keywords.Get + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; // set: // <expression> var setBlock = new NonTerminal("set_block"); setBlock.Rule = grammar.Keywords.Set + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; // The set block is optional. var setBlockOpt = new NonTerminal("set_block_opt"); setBlockOpt.Rule = setBlock | grammar.Empty; /* public int foo: * get: * return i * set: * i = value */ PropertyDeclaration.Rule = grammar.MethodDeclarations.MemberHeader + grammar.ToTerm(":") + grammar.Eos + grammar.Indent + getBlock + setBlockOpt + grammar.Dedent; }
public void Define() { // The else block is optional. var elseBlockOpt = new NonTerminal("else_block_opt"); elseBlockOpt.Rule = grammar.Empty | SimpleElseBlock | BodiedElseBlock; SimpleElseBlock.Rule = grammar.Keywords.Else + grammar.expression; BodiedElseBlock.Rule = grammar.Keywords.Else + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; SimpleIfBlock.Rule = grammar.Keywords.If + grammar.ValidConditionals + grammar.expression + elseBlockOpt; BodiedIfBlock.Rule = grammar.Keywords.If + grammar.ValidConditionals + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody + elseBlockOpt; }
public void Define() { // while <condition> <expression> SimpleWhileLoop.Rule = grammar.Keywords.While + grammar.ValidConditionals + grammar.expression; /* while <condition>: * <expression> */ BodiedWhileLoop.Rule = grammar.Keywords.While + grammar.ValidConditionals + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; }
public void Define() { // A method interface contracted by the interface var methodInterface = new NonTerminal("method_interface"); methodInterface.Rule = grammar.TwoIdentifiers + grammar.Classes.GenericTypeListOpt + grammar.OpenParenthese + grammar.MethodDeclarations.ParameterList + grammar.CloseParenthese + grammar.Eos; // A property interface contracted by the interface var propertyInterface = new NonTerminal("property_interface"); propertyInterface.Rule = grammar.TwoIdentifiers + grammar.Eos; // Valid inteface members are the method and property interfaces var validInterfaceMembers = new NonTerminal("valid_interface_members"); validInterfaceMembers.Rule = methodInterface | propertyInterface; // The member list can be zero or more of the previous var interfaceMembersList = new NonTerminal("interface_members"); interfaceMembersList.Rule = grammar.MakeStarRule(interfaceMembersList, validInterfaceMembers); // The member body is an indent, the member list, and a dedent. var interfaceBody = new NonTerminal("interface_body"); interfaceBody.Rule = grammar.Indent + interfaceMembersList + grammar.Dedent; // The body is optional. var interfaceBodyOpt = new NonTerminal("interface_body_opt"); interfaceBodyOpt.Rule = interfaceBody | grammar.Empty; InterfaceDeclaration.Rule = grammar.Classes.Modifier + grammar.Keywords.Interface + grammar.Identifier + grammar.Classes.GenericTypeListOpt + grammar.Classes.BaseTypeListOpt + grammar.ToTerm(":") + grammar.Eos + interfaceBodyOpt; }
public void Define() { // The increment/decrement statement "step 1" var step = new NonTerminal("for_loop_step"); step.Rule = grammar.Keywords.Step + grammar.expression; // The step is optional (defaults to step 1) var step_opt = new NonTerminal("for_loop_step_opt"); step_opt.Rule = grammar.Empty | step; // The initialization statement var for_init = new NonTerminal("for_init"); for_init.Rule = grammar.ExplicitVariableDeclaration | grammar.Identifier; // The range of values to iterate over var for_range = new NonTerminal("for_range"); for_range.Rule = grammar.expression + grammar.Keywords.To + grammar.expression; // The conditional of the for loop is either some expression, or the range of values being looped over. var for_condition = new NonTerminal("for_condition"); for_condition.Rule = grammar.expression | for_range; SimpleForLoop.Rule = grammar.Keywords.For + for_init + grammar.Keywords.In + for_condition + step_opt + grammar.expression; BodiedForLoop.Rule = grammar.Keywords.For + for_init + grammar.Keywords.In + for_condition + step_opt + grammar.ToTerm(":") + grammar.Eos + grammar.MethodDeclarations.OptionalMethodBody; }
public LiteralRules(PieGrammar grammar) { this.grammar = grammar; NumberLiteral = new NumberLiteral("number_literal", NumberOptions.AllowStartEndDot) { // Define types to assign if the parser can't determine. DefaultIntTypes = new[] { TypeCode.Int32 }, DefaultFloatType = TypeCode.Double }; // The pre and post fixes for different number types and formats. NumberLiteral.AddPrefix("0x", NumberOptions.Hex); NumberLiteral.AddSuffix("b", TypeCode.Byte); NumberLiteral.AddSuffix("B", TypeCode.Byte); NumberLiteral.AddSuffix("s", TypeCode.Int16); NumberLiteral.AddSuffix("S", TypeCode.Int16); NumberLiteral.AddSuffix("u", TypeCode.UInt32); NumberLiteral.AddSuffix("U", TypeCode.UInt32); NumberLiteral.AddSuffix("us", TypeCode.UInt16); NumberLiteral.AddSuffix("US", TypeCode.UInt16); NumberLiteral.AddSuffix("l", TypeCode.Int64); NumberLiteral.AddSuffix("L", TypeCode.Int64); NumberLiteral.AddSuffix("ul", TypeCode.UInt64); NumberLiteral.AddSuffix("UL", TypeCode.UInt64); NumberLiteral.AddSuffix("F", TypeCode.Single); NumberLiteral.AddSuffix("f", TypeCode.Single); NumberLiteral.AddSuffix("d", TypeCode.Double); NumberLiteral.AddSuffix("D", TypeCode.Double); NumberLiteral.AddSuffix("m", TypeCode.Decimal); NumberLiteral.AddSuffix("M", TypeCode.Decimal); StringLiteral = new StringLiteral("string_literal", "\"", StringOptions.AllowsAllEscapes); CharLiteral = new StringLiteral("char_literal", "'", StringOptions.IsChar); BoolLiteral = new NonTerminal("bool_literal"); BoolLiteral.Rule = grammar.Keywords.True | grammar.Keywords.False; Null = grammar.ToTerm("null", "null_literal"); }
public void Define() { // import System, System.IO Import.Rule = grammar.Keywords.Import + grammar.Lists.StarIdentifierList + grammar.Eos; // The namespace body is optional. var namespaceBodyOpt = new NonTerminal("namespace_body_opt"); namespaceBodyOpt.Rule = (NamespaceBody | grammar.Empty); grammar.MarkTransient(NamespaceBody); // namespace foo: NamespaceDeclaration.Rule = grammar.Keywords.NamespaceKeyword + grammar.Identifier + grammar.ToTerm(":") + grammar.Eos + namespaceBodyOpt; // Valid namespace members are: namespaces, imports, enums, delegates, interfaces, classes NamespaceValidMembers.Rule = NamespaceDeclaration | grammar.Classes.ClassDeclaration | Import | grammar.Enums.EnumDeclaration | grammar.Delegates.DelegateDeclaration | grammar.Interfaces.InterfaceDeclaration; grammar.MarkTransient(NamespaceValidMembers); // The list of members in the namespace. NamespaceMembersList.Rule = grammar.MakeStarRule(NamespaceMembersList, NamespaceValidMembers); grammar.MarkTransient(NamespaceMembersList); // The body of the namespace is an indent, a member list, and a dedent. NamespaceBody.Rule = grammar.Indent + NamespaceMembersList + grammar.Dedent; }
public OperatorRules(PieGrammar grammar) { this.grammar = grammar; ValidBinaryOperators = new NonTerminal("binary_operators"); BinaryOperator = new NonTerminal("binary_operator"); ValidUnaryOperators = new NonTerminal("valid_unary_operators"); UnaryOperator = new NonTerminal("unary_operator"); Multiply = grammar.ToTerm("*"); Modulo = grammar.ToTerm("%"); Divide = grammar.ToTerm("/"); Add = grammar.ToTerm("+"); Subtract = grammar.ToTerm("-"); LessOrEqual = grammar.ToTerm("<="); GreaterOrEqual = grammar.ToTerm(">="); Greater = grammar.ToTerm(">"); Less = grammar.ToTerm("<"); Equal = grammar.ToTerm("=="); NotEqual = grammar.ToTerm("!="); Assignment = new NonTerminal("assignment"); EqualsAssignment = grammar.ToTerm("="); BitwiseAnd = grammar.ToTerm("&"); BitwiseXor = grammar.ToTerm("^"); BitwiseOr = grammar.ToTerm("|"); BitwiseShiftLeft = grammar.ToTerm("<<"); BitwiseShiftRight = grammar.ToTerm(">>"); Not = grammar.ToTerm("!"); Negate = grammar.ToTerm("-"); As = grammar.ToTerm("as"); AddAssignment = grammar.ToTerm("+="); SubtractAssignment = grammar.ToTerm("-="); DivideAssignment = grammar.ToTerm("/="); MultiplyAssignment = grammar.ToTerm("*="); OrAssignment = grammar.ToTerm("|="); AndAssignment = grammar.ToTerm("&="); XorAssignment = grammar.ToTerm("^="); }
public void Define() { // The rule describing all valid binary operators. ValidBinaryOperators.Rule = Add | Modulo | Divide | LessOrEqual | Less | Greater | GreaterOrEqual | Equal | NotEqual | grammar.Keywords.And | grammar.Keywords.Or | BitwiseShiftRight | BitwiseShiftLeft | BitwiseOr | BitwiseAnd | BitwiseXor | Subtract | Multiply | As; grammar.MarkTransient(ValidBinaryOperators); // Set operators precedence and associativity, in increasing order of precedence. int precedence = 1; grammar.RegisterOperators(precedence += 1, Associativity.Right, "=", "+=", "-=", "/=", "*=", "|=", "&=", "^="); grammar.RegisterOperators(precedence += 1, Associativity.Left, "||"); grammar.RegisterOperators(precedence += 1, Associativity.Left, "&&"); grammar.RegisterOperators(precedence += 1, Associativity.Left, "|"); grammar.RegisterOperators(precedence += 1, Associativity.Left, "^"); grammar.RegisterOperators(precedence += 1, Associativity.Left, "&"); grammar.RegisterOperators(precedence += 1, Associativity.Left, "==", "!="); grammar.RegisterOperators(precedence += 1, Associativity.Left, "<", ">", ">=", "<="); grammar.RegisterOperators(precedence += 1, Associativity.Left, "<<", ">>"); grammar.RegisterOperators(precedence += 1, Associativity.Left, "+", "-"); grammar.RegisterOperators(precedence += 1, Associativity.Left, "*", "/", "%"); grammar.RegisterOperators(precedence += 1, Associativity.Right, "!", "-"); grammar.RegisterOperators(precedence += 1, As); // Casting // Set comma and closing brace as operators so that lists can continue on the next line. grammar.RegisterOperators(0, grammar.ToTerm("}")); grammar.RegisterOperators(0, grammar.ToTerm(",")); // An operator expression: two expressions with the operator between BinaryOperator.Rule = grammar.expression + ValidBinaryOperators + grammar.expression; // The list of valid assignment operators: +=, -=, *=, /=, |*, &=, ^= var validAssigments = new NonTerminal("valid_assigments"); validAssigments.Rule = EqualsAssignment | AddAssignment | SubtractAssignment | MultiplyAssignment | DivideAssignment | OrAssignment | AndAssignment | XorAssignment; grammar.MarkTransient(validAssigments); // Assignment expression is an expression that can be assigned to, the operator, and the assigned expression. Assignment.Rule = grammar.Assignable + validAssigments + grammar.expression + (grammar.Empty | grammar.Eos); // Valid unary operators. ValidUnaryOperators.Rule = Not | Negate; // Unary operator + expression UnaryOperator.Rule = ValidUnaryOperators + grammar.expression + (grammar.Empty | grammar.Eos); grammar.MarkReservedWords("As"); }
public KeywordRules(PieGrammar grammar) { this.grammar = grammar; Partial = grammar.ToTerm("partial"); Import = grammar.ToTerm("import"); Public = grammar.ToTerm("public"); Private = grammar.ToTerm("private"); Internal = grammar.ToTerm("internal"); Protected = grammar.ToTerm("protected"); Final = grammar.ToTerm("final"); NamespaceKeyword = grammar.ToTerm("namespace"); Module = grammar.ToTerm("module"); Class = grammar.ToTerm("class"); Struct = grammar.ToTerm("struct"); Enum = grammar.ToTerm("enum"); As = grammar.ToTerm("as"); Of = grammar.ToTerm("of"); Abstract = grammar.ToTerm("abstract"); And = grammar.ToTerm("&&"); Or = grammar.ToTerm("||"); If = grammar.ToTerm("if"); Else = grammar.ToTerm("else"); Shared = grammar.ToTerm("shared"); Def = grammar.ToTerm("def"); Virtual = grammar.ToTerm("virtual"); Override = grammar.ToTerm("override"); For = grammar.ToTerm("for"); Step = grammar.ToTerm("step"); While = grammar.ToTerm("while"); In = grammar.ToTerm("in"); To = grammar.ToTerm("to"); True = grammar.ToTerm("true"); False = grammar.ToTerm("false"); Ref = grammar.ToTerm("ref"); Out = grammar.ToTerm("out"); New = grammar.ToTerm("new"); Super = grammar.ToTerm("super"); Get = grammar.ToTerm("get"); Set = grammar.ToTerm("set"); Value = grammar.ToTerm("value"); Try = grammar.ToTerm("try"); Catch = grammar.ToTerm("catch"); Finally = grammar.ToTerm("finally"); Throw = grammar.ToTerm("throw"); Switch = grammar.ToTerm("switch"); Case = grammar.ToTerm("case"); Break = grammar.ToTerm("break"); Delegate = grammar.ToTerm("delegate"); Event = grammar.ToTerm("event"); Interface = grammar.ToTerm("interface"); Var = grammar.ToTerm("var"); // Mark them as "reserved" so that the parser can tell the syntax highlighter how to color them in the IDE. grammar.MarkReservedWords("partial", "import", "public", "private", "internal", "protected", "def", "shared", "virtual", "enum"); grammar.MarkReservedWords("final", "namespace", "class", "module", "struct", "as", "of", "abstract", "and", "or", "if", "else"); grammar.MarkReservedWords("for", "step", "true", "false", "in", "to", "while", "const", "new", "base", "this"); grammar.MarkReservedWords("override", "get", "set", "value", "try", "catch", "finally", "throw", "switch", "case", "break"); grammar.MarkReservedWords("delegate", "event", "interface", "var"); }
public void Define() { StarIdentifierList.Rule = grammar.MakeStarRule(StarIdentifierList, grammar.ToTerm(","), grammar.Identifier); PlusIdentifierList.Rule = grammar.MakePlusRule(PlusIdentifierList, grammar.ToTerm(","), grammar.Identifier); grammar.MarkTransient(StarIdentifierList); }
// Define the rules (declaration and definition must be separate). public void Define() { // List of base types var baseTypeList = new NonTerminal("base_type_list"); // List of members in the class body var membersList = new NonTerminal("class_members_list"); // The members that may go into a member list. var validMembers = new NonTerminal("class_valid_members"); // The optional body of the class var memberBodyOpt = new NonTerminal("member_body_opt"); // The modifiers that may make up a class. var validClassModifiers = new NonTerminal("valid_class_modifiers"); // The rule describing which modifiers can be applied to a class variable. var classVariableValidModifers = new NonTerminal("classVariableValidModifiers"); classVariableValidModifers.Rule = grammar.Keywords.Public | grammar.Keywords.Private | grammar.Keywords.Protected | grammar.Keywords.Internal | grammar.Keywords.Final | grammar.Keywords.Shared; // A list rule is needed as there can be more than one modifier. ClassVariableModifierList.Rule = grammar.MakeStarRule(ClassVariableModifierList, classVariableValidModifers); // The rule to declare a class varible: public int foo var classVariable = new NonTerminal("class_variable"); classVariable.Rule = grammar.MethodDeclarations.MemberHeader + grammar.Eos; // The rule describing which modifiers can be used for a class declaration validClassModifiers.Rule = grammar.Keywords.Public | grammar.Keywords.Internal | grammar.Keywords.Final | grammar.Keywords.Partial | grammar.Keywords.Abstract; grammar.MarkTransient(validClassModifiers); // A list rule since there can be more than on modifier. Modifier.Rule = grammar.MakeStarRule(Modifier, validClassModifiers); // Could be a class, struct, or module var classStructOrModule = new NonTerminal("class_or_module"); classStructOrModule.Rule = grammar.Keywords.Class | grammar.Keywords.Module | grammar.Keywords.Struct; grammar.MarkTransient(classStructOrModule); // (basetype1, basetype2) baseTypeList.Rule = grammar.OpenParenthese + grammar.Lists.PlusIdentifierList + grammar.CloseParenthese; // Base type list is optional: it may be empty BaseTypeListOpt.Rule = grammar.Empty | baseTypeList; // {T,L} GenericTypeList.Rule = grammar.ToTerm("{") + grammar.Lists.PlusIdentifierList + grammar.ToTerm("}"); // Generic type list is optional. GenericTypeListOpt.Rule = grammar.Empty | GenericTypeList; // Class body is a list of members between an indent and a dedent var memberBody = new NonTerminal("member_body"); memberBody.Rule = (grammar.Indent + membersList + grammar.Dedent); grammar.MarkTransient(memberBody); // member list is optional: it may be empty. var optionalMembersList = new NonTerminal("optional_members_list"); optionalMembersList.Rule = grammar.Empty | membersList; // Body of the class is optional memberBodyOpt.Rule = grammar.Empty | memberBody; /* class foo{T,K}(basetype1,basetype2}: * memberlist */ ClassDeclaration.Rule = Modifier + classStructOrModule + grammar.Identifier + GenericTypeListOpt + BaseTypeListOpt + grammar.ToTerm(":") + grammar.Eos + memberBodyOpt; // Valid class members are methods, constructors, variables, properties, and events. validMembers.Rule = grammar.MethodDeclarations.MethodDeclaration | classVariable | grammar.Constructors.ConstructorDeclaration | grammar.Properties.PropertyDeclaration | grammar.Delegates.EventMember; membersList.Rule = grammar.MakeStarRule(membersList, validMembers); }