// It is loosely based on R6RS specs. // See Grammar Errors tab in GrammarExplorer for remaining conflicts. public SchemeGrammar() { #region Terminals ConstantTerminal Constant = new ConstantTerminal("Constant"); Constant.Add("#T", 1); Constant.Add("#t", 1); Constant.Add("#F", null); Constant.Add("#f", null); Constant.Add("'()", null); Constant.Add(@"#\nul", '\u0000'); Constant.Add(@"#\alarm", '\u0007'); Constant.Add(@"#\backspace", '\b'); Constant.Add(@"#\tab", '\t'); Constant.Add(@"#\linefeed", '\n'); Constant.Add(@"#\vtab", '\v'); Constant.Add(@"#\page", '\f'); Constant.Add(@"#\return", '\r'); Constant.Add(@"#\esc", '\u001B'); Constant.Add(@"#\space", ' '); Constant.Add(@"#\delete", '\u007F'); // TODO: build SchemeCharLiteral // the following is nonsense, just to put something there var charLiteral = new StringLiteral("Char", "'", StringOptions.None); var stringLiteral = new StringLiteral("String", "\"", StringOptions.AllowsAllEscapes); //Identifiers. Note: added "-", just to allow IDs starting with "->" var SimpleIdentifier = new IdentifierTerminal("SimpleIdentifier", "_+-*/.@?!<>=", "_+-*/.@?!<>=$%&:^~"); // name extraChars extraFirstChars var Number = TerminalFactory.CreateSchemeNumber("Number"); var Byte = new NumberLiteral("Byte", NumberOptions.IntOnly); //Comments Terminal Comment = new CommentTerminal("Comment", "#|", "|#"); Terminal LineComment = new CommentTerminal("LineComment", ";", "\n"); NonGrammarTerminals.Add(Comment); //add comments explicitly to this list as it is not reachable from Root NonGrammarTerminals.Add(LineComment); #endregion #region NonTerminals var Module = new NonTerminal("Module"); var Library = new NonTerminal("Library"); var LibraryList = new NonTerminal("Library+"); var Script = new NonTerminal("Script"); var Abbreviation = new NonTerminal("Abbreviation"); var Vector = new NonTerminal("Vector"); var ByteList = new NonTerminal("ByteList"); var ByteVector = new NonTerminal("ByteVector"); var Datum = new NonTerminal("Datum"); //Datum in R6RS terms var DatumOpt = new NonTerminal("DatumOpt"); //Datum in R6RS terms var DatumList = new NonTerminal("Datum+"); var DatumListOpt = new NonTerminal("Datum*"); var Statement = new NonTerminal("Statement"); var Atom = new NonTerminal("Atom"); var CompoundDatum = new NonTerminal("CompoundDatum"); var AbbrevPrefix = new NonTerminal("AbbrevPrefix"); var LibraryName = new NonTerminal("LibraryName"); var LibraryBody = new NonTerminal("LibraryBody"); var ImportSection = new NonTerminal("ImportSection"); var ExportSection = new NonTerminal("ExportSection"); var ImportSpec = new NonTerminal("ImportSpec"); var ImportSpecList = new NonTerminal("ImportSpecList"); var ExportSpec = new NonTerminal("ExportSpec"); var ExportSpecList = new NonTerminal("ExportSpecList"); var LP = new NonTerminal("LP"); //"(" or "[" var RP = new NonTerminal("RP"); // ")" or "]" var Identifier = new NonTerminal("Identifier"); var IdentifierList = new NonTerminal("IdentifierList"); var IdentifierListOpt = new NonTerminal("IdentifierListOpt"); var PeculiarIdentifier = new NonTerminal("PeculiarIdentifier"); var LibraryVersion = new NonTerminal("LibraryVersion"); var VersionListOpt = new NonTerminal("VersionListOpt"); var FunctionCall = new NonTerminal("FunctionCall"); var FunctionRef = new NonTerminal("FunctionRef"); var SpecialForm = new NonTerminal("SpecialForm"); var DefineVarForm = new NonTerminal("DefineVarForm"); var DefineFunForm = new NonTerminal("DefineFunForm"); var LambdaForm = new NonTerminal("LambdaForm"); var IfForm = new NonTerminal("IfForm"); var CondForm = new NonTerminal("CondForm"); var CondClause = new NonTerminal("CondClause"); var CondClauseList = new NonTerminal("CondClauseList"); var CondElseOpt = new NonTerminal("CondElseOpt"); var BeginForm = new NonTerminal("BeginForm"); var LetForm = new NonTerminal("LetForm"); //not implemented var LetRecForm = new NonTerminal("LetRecForm"); //not implemented var LetPair = new NonTerminal("LetPair"); var LetPairList = new NonTerminal("LetPairList"); #endregion #region Rules base.Root = Module; LP.Rule = ToTerm("(") | "["; //R6RS allows mix & match () and [] RP.Rule = ToTerm(")") | "]"; // Module.Rule = LibraryListOpt + Script; -- this brings conflicts Module.Rule = LibraryList + Script | Script; LibraryList.Rule = MakePlusRule(LibraryList, Library); Script.Rule = ImportSection + DatumList | DatumList; //Library // the following doesn't work - brings conflicts that incorrectly resolved by default shifting //Library.Rule = LP + "library" + LibraryName + ExportSectionOpt + ImportSectionOpt + DatumListOpt + RP; Library.Rule = LP + "library" + LibraryName + LibraryBody + RP; //Note - we should be using DatumListOpt, but that brings 2 conflicts, so for now it is just DatumList //Note that the following style of BNF expressions is strongly discouraged - all productions should be of the same length, // so that the process of mapping child nodes to parent's properties is straightforward. LibraryBody.Rule = ExportSection + ImportSection + DatumList | ExportSection + DatumList | ImportSection + DatumList | DatumList; LibraryName.Rule = LP + IdentifierList + LibraryVersion.Q() + RP; LibraryVersion.Rule = LP + VersionListOpt + RP; //zero or more subversion numbers VersionListOpt.Rule = MakeStarRule(VersionListOpt, Number); ExportSection.Rule = LP + "export" + ExportSpecList + RP; ImportSection.Rule = LP + "import" + ImportSpecList + RP; ExportSpecList.Rule = MakePlusRule(ExportSpecList, ExportSpec); ImportSpecList.Rule = MakePlusRule(ImportSpecList, ImportSpec); ExportSpec.Rule = Identifier | LP + "rename" + LP + Identifier + Identifier + RP + RP; ImportSpec.Rule = LP + Identifier + RP; // - much more complex in R6RS //Datum Datum.Rule = Atom | CompoundDatum; DatumOpt.Rule = Empty | Datum; DatumList.Rule = MakePlusRule(DatumList, Datum); DatumListOpt.Rule = MakeStarRule(DatumListOpt, Datum); Atom.Rule = Number | Identifier | stringLiteral | Constant | charLiteral | "."; CompoundDatum.Rule = Statement | Abbreviation | Vector | ByteVector; Identifier.Rule = SimpleIdentifier | PeculiarIdentifier; IdentifierList.Rule = MakePlusRule(IdentifierList, Identifier); IdentifierListOpt.Rule = MakeStarRule(IdentifierListOpt, Identifier); //TODO: create PeculiarIdentifier custom terminal instead of var // or just custom SchemeIdentifier terminal PeculiarIdentifier.Rule = ToTerm("+") | "-" | "..."; // |"->" + subsequent; (should be!) Abbreviation.Rule = AbbrevPrefix + Datum; AbbrevPrefix.Rule = ToTerm("'") | "`" | ",@" | "," | "#'" | "#`" | "#,@" | "#,"; Vector.Rule = "#(" + DatumListOpt + ")"; ByteVector.Rule = "#vu8(" + ByteList + ")"; ByteList.Rule = MakeStarRule(ByteList, Byte); Statement.Rule = FunctionCall | SpecialForm; FunctionCall.Rule = LP + FunctionRef + DatumListOpt + RP; FunctionRef.Rule = Identifier | Statement; SpecialForm.Rule = DefineVarForm | DefineFunForm | LambdaForm | IfForm | CondForm | BeginForm | LetForm | LetRecForm; DefineVarForm.Rule = LP + "define" + Identifier + Datum + RP; DefineFunForm.Rule = LP + "define" + LP + Identifier + IdentifierListOpt + RP + DatumList + RP; LambdaForm.Rule = LP + "lambda" + LP + IdentifierListOpt + RP + DatumList + RP; IfForm.Rule = LP + "if" + Datum + Datum + DatumOpt + RP; CondForm.Rule = LP + "cond" + CondClauseList + CondElseOpt + RP; CondClauseList.Rule = MakePlusRule(CondClauseList, CondClause); CondClause.Rule = LP + Datum + DatumList + RP; CondElseOpt.Rule = Empty | LP + "else" + DatumList + RP; LetForm.Rule = LP + "let" + LP + LetPairList + RP + DatumList + RP; LetRecForm.Rule = LP + "letrec" + LP + LetPairList + RP + DatumList + RP; BeginForm.Rule = LP + "begin" + DatumList + RP; LetPairList.Rule = MakePlusRule(LetPairList, LetPair); LetPair.Rule = LP + Identifier + Datum + RP; #endregion //Register brace pairs RegisterBracePair("(", ")"); RegisterBracePair("[", "]"); MarkPunctuation(LP, RP); MarkTransient(Datum, CompoundDatum, Statement, SpecialForm, Atom); //Scheme is tail-recursive language base.LanguageFlags |= LanguageFlags.TailRecursive; }//constructor
TerminalSet _skipTokensInPreview = new TerminalSet(); //used in token preview for conflict resolution #endregion Fields #region Constructors public CSharpGrammar() { this.GrammarComments = "NOTE: This grammar is just a demo, and it is a broken demo.\r\n" + "Demonstrates token preview technique to help parser resolve conflicts.\r\n"; #region Lexical structure StringLiteral StringLiteral = TerminalFactory.CreateCSharpString("StringLiteral"); StringLiteral CharLiteral = TerminalFactory.CreateCSharpChar("CharLiteral"); NumberLiteral Number = TerminalFactory.CreateCSharpNumber("Number"); IdentifierTerminal identifier = TerminalFactory.CreateCSharpIdentifier("Identifier"); CommentTerminal SingleLineComment = new CommentTerminal("SingleLineComment", "//", "\r", "\n", "\u2085", "\u2028", "\u2029"); CommentTerminal DelimitedComment = new CommentTerminal("DelimitedComment", "/*", "*/"); NonGrammarTerminals.Add(SingleLineComment); NonGrammarTerminals.Add(DelimitedComment); //Temporarily, treat preprocessor instructions like comments CommentTerminal ppInstruction = new CommentTerminal("ppInstruction", "#", "\n"); NonGrammarTerminals.Add(ppInstruction); //Symbols KeyTerm colon = ToTerm(":", "colon"); KeyTerm semi = ToTerm(";", "semi"); NonTerminal semi_opt = new NonTerminal("semi?"); semi_opt.Rule = Empty | semi; KeyTerm dot = ToTerm(".", "dot"); KeyTerm comma = ToTerm(",", "comma"); NonTerminal comma_opt = new NonTerminal("comma_opt", Empty | comma); NonTerminal commas_opt = new NonTerminal("commas_opt"); commas_opt.Rule = MakeStarRule(commas_opt, null, comma); KeyTerm qmark = ToTerm("?", "qmark"); NonTerminal qmark_opt = new NonTerminal("qmark_opt", Empty | qmark); KeyTerm Lbr = ToTerm("{"); KeyTerm Rbr = ToTerm("}"); KeyTerm Lpar = ToTerm("("); KeyTerm Rpar = ToTerm(")"); KeyTerm tgoto = ToTerm("goto"); KeyTerm yld = ToTerm("yield"); KeyTerm Lparx = ToTerm("(*"); #endregion #region NonTerminals //B.2.1. Basic concepts var qual_name_with_targs = new NonTerminal("qual_name_with_targs"); var base_type_list = new NonTerminal("base_type_list"); var generic_dimension_specifier = new NonTerminal("generic_dimension_specifier"); var qual_name_segment = new NonTerminal("qual_name_segment"); var qual_name_segments_opt = new NonTerminal("qual_name_segments_opt"); var type_or_void = new NonTerminal("type_or_void", "type or void"); var builtin_type = new NonTerminal("builtin_type", "built-in type"); var type_ref_list = new NonTerminal("type_ref_list"); var identifier_ext = new NonTerminal("identifier_ext"); var identifier_or_builtin = new NonTerminal("identifier_or_builtin"); //B.2.2. Types var type_ref = new NonTerminal("type_ref"); var new_type_ref = new NonTerminal("new_type_ref"); var type_argument_list = new NonTerminal("type_argument_list"); var typearg_or_gendimspec_list = new NonTerminal("typearg_or_gendimspec_list"); var type_argument_list_opt = new NonTerminal("type_argument_list_opt"); var integral_type = new NonTerminal("integral_type"); //B.2.4. Expressions var argument = new NonTerminal("argument"); var argument_list = new NonTerminal("argument_list"); var argument_list_opt = new NonTerminal("argument_list_opt"); var expression = new NonTerminal("expression", "expression"); var expression_list = new NonTerminal("expression_list"); var expression_opt = new NonTerminal("expression_opt"); var conditional_expression = new NonTerminal("conditional_expression"); var lambda_expression = new NonTerminal("lambda_expression"); var query_expression = new NonTerminal("query_expression"); var unary_operator = new NonTerminal("unary_operator"); var assignment_operator = new NonTerminal("assignment_operator"); var primary_expression = new NonTerminal("primary_expression"); var unary_expression = new NonTerminal("unary_expression"); var pre_incr_decr_expression = new NonTerminal("pre_incr_decr_expression"); var post_incr_decr_expression = new NonTerminal("post_incr_decr_expression"); var primary_no_array_creation_expression = new NonTerminal("primary_no_array_creation_expression"); var literal = new NonTerminal("literal"); var parenthesized_expression = new NonTerminal("parenthesized_expression"); var member_access = new NonTerminal("member_access"); var member_access_segment = new NonTerminal("member_access_segment"); var member_access_segments_opt = new NonTerminal("member_access_segments_opt"); var array_indexer = new NonTerminal("array_indexer"); var argument_list_par = new NonTerminal("argument_list_par"); var argument_list_par_opt = new NonTerminal("argument_list_par_opt"); var incr_or_decr = new NonTerminal("incr_or_decr"); var incr_or_decr_opt = new NonTerminal("incr_or_decr_opt"); var creation_args = new NonTerminal("creation_args"); var object_creation_expression = new NonTerminal("object_creation_expression"); // delegate creation is syntactically equiv to object creation //var delegate_creation_expression = new NonTerminal("delegate_creation_expression"); var anonymous_object_creation_expression = new NonTerminal("anonymous_object_creation_expression"); var typeof_expression = new NonTerminal("typeof_expression"); var checked_expression = new NonTerminal("checked_expression"); var unchecked_expression = new NonTerminal("unchecked_expression"); var default_value_expression = new NonTerminal("default_value_expression"); var anonymous_method_expression = new NonTerminal("anonymous_method_expression"); var elem_initializer = new NonTerminal("elem_initializer"); var elem_initializer_list = new NonTerminal("elem_initializer_list"); var elem_initializer_list_ext = new NonTerminal("elem_initializer_list_ext"); var initializer_value = new NonTerminal("initializer_value"); var anonymous_object_initializer = new NonTerminal("anonymous_object_initializer"); var member_declarator = new NonTerminal("member_declarator"); var member_declarator_list = new NonTerminal("member_declarator_list"); var unbound_type_name = new NonTerminal("unbound_type_name"); var generic_dimension_specifier_opt = new NonTerminal("generic_dimension_specifier_opt"); var anonymous_function_signature = new NonTerminal("anonymous_function_signature"); var anonymous_function_signature_opt = new NonTerminal("anonymous_function_signature_opt"); var anonymous_function_parameter = new NonTerminal("anonymous_function_parameter"); var anonymous_function_parameter_decl = new NonTerminal("anonymous_function_parameter_decl"); var anonymous_function_parameter_list_opt = new NonTerminal("anonymous_function_parameter_list_opt"); var anonymous_function_parameter_modifier_opt = new NonTerminal("anonymous_function_parameter_modifier_opt"); var anonymous_function_body = new NonTerminal("anonymous_function_body"); var lambda_function_signature = new NonTerminal("lambda_function_signature"); var bin_op_expression = new NonTerminal("bin_op_expression"); var typecast_expression = new NonTerminal("typecast_expression"); var bin_op = new NonTerminal("bin_op", "operator symbol"); //B.2.5. Statements var statement = new NonTerminal("statement", "statement"); var statement_list = new NonTerminal("statement_list"); var statement_list_opt = new NonTerminal("statement_list_opt"); var labeled_statement = new NonTerminal("labeled_statement"); var declaration_statement = new NonTerminal("declaration_statement"); var embedded_statement = new NonTerminal("embedded_statement"); var selection_statement = new NonTerminal("selection_statement"); var iteration_statement = new NonTerminal("iteration_statement"); var jump_statement = new NonTerminal("jump_statement"); var try_statement = new NonTerminal("try_statement"); var checked_statement = new NonTerminal("checked_statement"); var unchecked_statement = new NonTerminal("unchecked_statement"); var lock_statement = new NonTerminal("lock_statement"); var using_statement = new NonTerminal("using_statement"); var yield_statement = new NonTerminal("yield_statement"); var block = new NonTerminal("block"); var statement_expression = new NonTerminal("statement_expression"); var statement_expression_list = new NonTerminal("statement_expression_list"); var local_variable_declaration = new NonTerminal("local_variable_declaration"); var local_constant_declaration = new NonTerminal("local_constant_declaration"); var local_variable_type = new NonTerminal("local_variable_type"); var local_variable_declarator = new NonTerminal("local_variable_declarator"); var local_variable_declarators = new NonTerminal("local_variable_declarators"); var if_statement = new NonTerminal("if_statement"); var switch_statement = new NonTerminal("switch_statement"); var else_clause_opt = new NonTerminal("else_clause_opt"); var switch_section = new NonTerminal("switch_section"); var switch_sections_opt = new NonTerminal("switch_sections_opt"); var switch_label = new NonTerminal("switch_label"); var switch_labels = new NonTerminal("switch_labels"); var while_statement = new NonTerminal("while_statement"); var do_statement = new NonTerminal("do_statement"); var for_statement = new NonTerminal("for_statement"); var foreach_statement = new NonTerminal("foreach_statement"); var for_initializer_opt = new NonTerminal("for_initializer_opt"); var for_condition_opt = new NonTerminal("for_condition_opt"); var for_iterator_opt = new NonTerminal("for_iterator_opt"); var break_statement = new NonTerminal("break_statement"); var continue_statement = new NonTerminal("continue_statement"); var goto_statement = new NonTerminal("goto_statement"); var return_statement = new NonTerminal("return_statement"); var throw_statement = new NonTerminal("throw_statement"); var try_clause = new NonTerminal("try_clause"); var try_clauses = new NonTerminal("try_clauses"); var catch_clause = new NonTerminal("catch_clause"); var finally_clause = new NonTerminal("finally_clause"); var catch_specifier_opt = new NonTerminal("catch_specifier_opt"); var identifier_opt = new NonTerminal("identifier_opt"); var resource_acquisition = new NonTerminal("resource_acquisition"); //namespaces, compilation units var compilation_unit = new NonTerminal("compilation_unit"); var extern_alias_directive = new NonTerminal("extern_alias_directive"); var extern_alias_directives_opt = new NonTerminal("extern_alias_directives_opt"); var using_directive = new NonTerminal("using_directive"); var using_directives = new NonTerminal("using_directives"); var using_directives_opt = new NonTerminal("using_directives_opt"); var namespace_declaration = new NonTerminal("namespace_declaration"); var namespace_declarations_opt = new NonTerminal("namespace_declarations_opt"); var qualified_identifier = new NonTerminal("qualified_identifier"); var namespace_body = new NonTerminal("namespace_body"); var namespace_member_declaration = new NonTerminal("namespace_member_declaration"); var namespace_member_declarations = new NonTerminal("namespace_member_declarations"); var using_alias_directive = new NonTerminal("using_alias_directive"); var using_ns_directive = new NonTerminal("using_ns_directive"); var type_declaration = new NonTerminal("type_declaration"); var class_declaration = new NonTerminal("class_declaration"); var delegate_declaration = new NonTerminal("delegate_declaration"); var qualified_alias_member = new NonTerminal("qualified_alias_member"); var class_body = new NonTerminal("class_body"); //B.2.7 Classes Terminal partial = ToTerm("partial"); var type_parameter_list_opt = new NonTerminal("type_parameter_list_opt"); var type_parameter = new NonTerminal("type_parameter"); var type_parameters = new NonTerminal("type_parameters"); var bases_opt = new NonTerminal("bases_opt"); var type_parameter_constraints_clause = new NonTerminal("type_parameter_constraints_clause"); var type_parameter_constraints_clauses_opt = new NonTerminal("type_parameter_constraints_clauses"); var type_parameter_constraint = new NonTerminal("type_parameter_constraint"); var type_parameter_constraints = new NonTerminal("type_parameter_constraints"); var member_declaration = new NonTerminal("member_declaration"); var member_declarations_opt = new NonTerminal("member_declarations_opt"); var constant_declaration = new NonTerminal("constant_declaration"); var field_declaration = new NonTerminal("field_declaration"); var method_declaration = new NonTerminal("method_declaration"); var property_declaration = new NonTerminal("property_declaration"); var event_declaration = new NonTerminal("event_declaration"); var indexer_declaration = new NonTerminal("indexer_declaration"); var constructor_declaration = new NonTerminal("constructor_declaration"); var destructor_declaration = new NonTerminal("destructor_declaration"); var constant_declarator = new NonTerminal("constant_declarator"); var constant_declarators = new NonTerminal("constant_declarators"); var modifier = new NonTerminal("modifier"); var modifiers_opt = new NonTerminal("modifiers_opt"); var member_header = new NonTerminal("member_header"); var accessor_name = new NonTerminal("accessor_name"); var accessor_declaration = new NonTerminal("accessor_declaration"); var accessor_declarations = new NonTerminal("accessor_declarations"); var accessor_modifier_opt = new NonTerminal("accessor_modifier_opt"); var event_body = new NonTerminal("event_body"); var event_accessor_declarations = new NonTerminal("event_accessor_declarations"); var add_accessor_declaration = new NonTerminal("add_accessor_declaration"); var remove_accessor_declaration = new NonTerminal("remove_accessor_declaration"); var indexer_name = new NonTerminal("indexer_name"); var operator_declaration = new NonTerminal("operator_declaration"); var conversion_operator_declaration = new NonTerminal("conversion_operator_declaration"); var overloadable_operator = new NonTerminal("overloadable_operator"); var operator_parameter = new NonTerminal("operator_parameter"); var operator_parameters = new NonTerminal("operator_parameters"); var conversion_operator_kind = new NonTerminal("conversion_operator_kind"); var constructor_initializer_opt = new NonTerminal("constructor_initializer_opt"); var constructor_base = new NonTerminal("constructor_base"); var variable_declarator = new NonTerminal("variable_declarator"); var variable_declarators = new NonTerminal("variable_declarators"); var method_body = new NonTerminal("method_body"); var formal_parameter_list = new NonTerminal("formal_parameter_list"); var formal_parameter_list_par = new NonTerminal("formal_parameter_list_par"); var fixed_parameter = new NonTerminal("fixed_parameter"); var fixed_parameters = new NonTerminal("fixed_parameters"); var parameter_modifier_opt = new NonTerminal("parameter_modifier_opt"); var parameter_array = new NonTerminal("parameter_array"); //B.2.8 struct var struct_declaration = new NonTerminal("struct_declaration"); var struct_body = new NonTerminal("struct_body"); //B.2.9. Arrays var rank_specifier = new NonTerminal("rank_specifier"); var rank_specifiers = new NonTerminal("rank_specifiers"); var rank_specifiers_opt = new NonTerminal("rank_specifiers_opt"); var dim_specifier = new NonTerminal("dim_specifier"); var dim_specifier_opt = new NonTerminal("dim_specifier_opt"); var list_initializer = new NonTerminal("array_initializer"); var list_initializer_opt = new NonTerminal("array_initializer_opt"); //B.2.10 Interfaces var interface_declaration = new NonTerminal("interface_declaration"); var interface_body = new NonTerminal("interface_body"); var interface_member_declaration = new NonTerminal("interface_member_declaration"); var interface_member_declarations = new NonTerminal("interface_member_declarations"); var interface_method_declaration = new NonTerminal("interface_method_declaration"); var interface_property_declaration = new NonTerminal("interface_property_declaration"); var interface_event_declaration = new NonTerminal("interface_event_declaration"); var interface_indexer_declaration = new NonTerminal("interface_indexer_declaration"); var new_opt = new NonTerminal("new_opt"); var interface_accessor = new NonTerminal("interface_get_accessor"); var interface_accessors = new NonTerminal("interface_accessors"); //B.2.11 Enums var enum_declaration = new NonTerminal("enum_declaration"); var enum_base_opt = new NonTerminal("enum_base_opt"); var enum_member_declaration = new NonTerminal("enum_member_declaration"); var enum_member_declarations = new NonTerminal("enum_member_declarations"); //B.2.13 Attributes var attribute_section = new NonTerminal("attribute_section"); var attributes_opt = new NonTerminal("attributes_opt"); var attribute_target_specifier_opt = new NonTerminal("attribute_target_specifier_opt"); var attribute_target = new NonTerminal("attribute_target"); var attribute = new NonTerminal("attribute"); var attribute_list = new NonTerminal("attribute_list"); var attribute_arguments_opt = new NonTerminal("attribute_arguments"); var named_argument = new NonTerminal("named_argument"); var attr_arg = new NonTerminal("attr_arg"); var attribute_arguments_par_opt = new NonTerminal("attribute_arguments_par_opt"); #endregion #region operators, punctuation and delimiters RegisterOperators(1, "||"); RegisterOperators(2, "&&"); RegisterOperators(3, "|"); RegisterOperators(4, "^"); RegisterOperators(5, "&"); RegisterOperators(6, "==", "!="); RegisterOperators(7, "<", ">", "<=", ">=", "is", "as"); RegisterOperators(8, "<<", ">>"); RegisterOperators(9, "+", "-"); RegisterOperators(10, "*", "/", "%"); //RegisterOperators(11, "."); // RegisterOperators(12, "++", "--"); #region comments //The following makes sense, if you think about "?" in context of operator precedence. // What we say here is that "?" has the lowest priority among arithm operators. // Therefore, the parser should prefer reduce over shift when input symbol is "?". // For ex., when seeing ? in expression "a + b?...", the parser will perform Reduce: // (a + b)->expr // and not shift the "?" symbol. // Same goes for ?? symbol #endregion RegisterOperators(-3, "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="); RegisterOperators(-2, "?"); RegisterOperators(-1, "??"); this.Delimiters = "{}[](),:;+-*/%&|^!~<>="; this.MarkPunctuation(";", ",", "(", ")", "{", "}", "[", "]", ":"); this.MarkTransient(namespace_member_declaration, member_declaration, type_declaration, statement, embedded_statement, expression, literal, bin_op, primary_expression, expression); this.AddTermsReportGroup("assignment", "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="); this.AddTermsReportGroup("typename", "bool", "decimal", "float", "double", "string", "object", "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "char"); this.AddTermsReportGroup("statement", "if", "switch", "do", "while", "for", "foreach", "continue", "goto", "return", "try", "yield", "break", "throw", "unchecked", "using"); this.AddTermsReportGroup("type declaration", "public", "private", "protected", "static", "internal", "sealed", "abstract", "partial", "class", "struct", "delegate", "interface", "enum"); this.AddTermsReportGroup("member declaration", "virtual", "override", "readonly", "volatile", "extern"); this.AddTermsReportGroup("constant", Number, StringLiteral, CharLiteral); this.AddTermsReportGroup("constant", "true", "false", "null"); this.AddTermsReportGroup("unary operator", "+", "-", "!", "~"); this.AddToNoReportGroup(comma, semi); this.AddToNoReportGroup("var", "const", "new", "++", "--", "this", "base", "checked", "lock", "typeof", "default", "{", "}", "["); // #endregion #region "<" conflict resolution var gen_lt = new NonTerminal("gen_lt"); gen_lt.Rule = CustomActionHere(this.ResolveLessThanConflict) + "<"; #endregion /* #region Keywords string strKeywords = "abstract as base bool break byte case catch char checked " + "class const continue decimal default delegate do double else enum event explicit extern false finally " + "fixed float for foreach goto if implicit in int interface internal is lock long namespace " + "new null object operator out override params private protected public " + "readonly ref return sbyte sealed short sizeof stackalloc static string " + "struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual void " + "volatile while"; AddKeywordList(strKeywords); #endregion */ // RULES //B.2.1. Basic concepts //qual_name_with_targs is an alias for namespace-name, namespace-or-type-name, type-name, generic_dimension_specifier.Rule = gen_lt + commas_opt + ">"; qual_name_segments_opt.Rule = MakeStarRule(qual_name_segments_opt, null, qual_name_segment); identifier_or_builtin.Rule = identifier | builtin_type; identifier_ext.Rule = identifier_or_builtin | "this" | "base"; qual_name_segment.Rule = dot + identifier | "::" + identifier | type_argument_list; //generic_dimension_specifier.Rule = lt + commas_opt + ">"; generic_dimension_specifier.Rule = gen_lt + commas_opt + ">"; qual_name_with_targs.Rule = identifier_or_builtin + qual_name_segments_opt; type_argument_list.Rule = gen_lt + type_ref_list + ">"; type_argument_list_opt.Rule = Empty | type_argument_list; typearg_or_gendimspec_list.Rule = type_argument_list | generic_dimension_specifier_opt; //B.2.2. Types type_or_void.Rule = qual_name_with_targs | "void"; builtin_type.Rule = integral_type | "bool" | "decimal" | "float" | "double" | "string" | "object"; type_ref.Rule = type_or_void + qmark_opt + rank_specifiers_opt + typearg_or_gendimspec_list; type_ref_list.Rule = MakePlusRule(type_ref_list, comma, type_ref); var comma_list_opt = new NonTerminal("comma_list_opt"); comma_list_opt.Rule = MakeStarRule(comma_list_opt, comma); rank_specifier.Rule = "[" + comma_list_opt + "]"; rank_specifiers.Rule = MakePlusRule(rank_specifiers, null, rank_specifier); rank_specifiers_opt.Rule = rank_specifiers.Q(); integral_type.Rule = ToTerm("sbyte") | "byte" | "short" | "ushort" | "int" | "uint" | "long" | "ulong" | "char"; //B.2.4. Variables //Quite strange in specs - // variable-reference: // expression // Is that case it would be possible to do the following: // GetMyStuff(out (a+b)); // but MS c# rejects it //B.2.4. Expressions argument.Rule = expression | "ref" + identifier | "out" + identifier; argument_list.Rule = MakePlusRule(argument_list, comma, argument); argument_list_opt.Rule = Empty | argument_list; expression.Rule = conditional_expression | bin_op_expression | typecast_expression | primary_expression; expression_opt.Rule = Empty | expression; expression_list.Rule = MakePlusRule(expression_list, comma, expression); unary_operator.Rule = ToTerm("+") | "-" | "!" | "~" | "*"; assignment_operator.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>="; conditional_expression.Rule = expression + PreferShiftHere() + qmark + expression + colon + expression;// + ReduceThis(); bin_op_expression.Rule = expression + bin_op + expression; typecast_expression.Rule = parenthesized_expression + primary_expression; primary_expression.Rule = literal | unary_expression | parenthesized_expression | member_access | pre_incr_decr_expression | post_incr_decr_expression | object_creation_expression | anonymous_object_creation_expression | typeof_expression | checked_expression | unchecked_expression | default_value_expression | anonymous_method_expression; unary_expression.Rule = unary_operator + primary_expression; dim_specifier.Rule = "[" + expression_list + "]"; dim_specifier_opt.Rule = dim_specifier.Q(); literal.Rule = Number | StringLiteral | CharLiteral | "true" | "false" | "null"; parenthesized_expression.Rule = Lpar + expression + Rpar; pre_incr_decr_expression.Rule = incr_or_decr + member_access; post_incr_decr_expression.Rule = member_access + incr_or_decr; //joined invocation_expr and member_access; for member access left the most general variant member_access.Rule = identifier_ext + member_access_segments_opt; member_access_segments_opt.Rule = MakeStarRule(member_access_segments_opt, null, member_access_segment); member_access_segment.Rule = dot + identifier | array_indexer | argument_list_par | type_argument_list; array_indexer.Rule = "[" + expression_list + "]"; argument_list_par.Rule = Lpar + argument_list_opt + Rpar; argument_list_par_opt.Rule = Empty | argument_list_par; list_initializer.Rule = Lbr + elem_initializer_list_ext + Rbr; list_initializer_opt.Rule = list_initializer.Q(); elem_initializer.Rule = initializer_value | identifier + "=" + initializer_value; elem_initializer_list.Rule = MakePlusRule(elem_initializer_list, comma, elem_initializer); elem_initializer_list_ext.Rule = Empty | elem_initializer_list + comma_opt; initializer_value.Rule = expression | list_initializer; //delegate, anon-object, object object_creation_expression.Rule = "new" + qual_name_with_targs + qmark_opt + creation_args + list_initializer_opt; creation_args.Rule = dim_specifier | rank_specifier | argument_list_par; anonymous_object_creation_expression.Rule = "new" + anonymous_object_initializer; anonymous_object_initializer.Rule = Lbr + Rbr | Lbr + member_declarator_list + comma_opt + Rbr; member_declarator.Rule = expression | identifier + "=" + expression; member_declarator_list.Rule = MakePlusRule(member_declarator_list, comma, member_declarator); //typeof typeof_expression.Rule = "typeof" + Lpar + type_ref + Rpar; generic_dimension_specifier_opt.Rule = Empty | gen_lt + commas_opt + ">"; //checked, unchecked checked_expression.Rule = "checked" + parenthesized_expression; unchecked_expression.Rule = "unchecked" + parenthesized_expression; //default-value default_value_expression.Rule = "default" + Lpar + type_ref + Rpar; //note: we treat ?? as bin-operation, so null-coalesce-expr used in spec as first (condition) component is replaced with expression // we resolve all this expr hierarchies of binary expressions using precedence //anonymous method and lambda - we join explicit and implicit param definitions, making 'type' element optional // TODO: add after-parse check for this anonymous_method_expression.Rule = "delegate" + anonymous_function_signature_opt + block; lambda_expression.Rule = lambda_function_signature + "=>" + anonymous_function_body; lambda_function_signature.Rule = anonymous_function_signature | identifier; anonymous_function_signature.Rule = Lpar + anonymous_function_parameter_list_opt + Rpar; anonymous_function_signature_opt.Rule = anonymous_function_signature.Q(); anonymous_function_parameter_modifier_opt.Rule = Empty | "ref" | "out"; anonymous_function_parameter.Rule = anonymous_function_parameter_modifier_opt + anonymous_function_parameter_decl; anonymous_function_parameter_decl.Rule = identifier | type_ref + identifier; anonymous_function_parameter_list_opt.Rule = MakeStarRule(anonymous_function_parameter_list_opt, comma, anonymous_function_parameter_decl); anonymous_function_body.Rule = expression | block; //we don't use grammar expressions to specify operator precedence, so we combine all these grammar elements together // and define just bin_op_expression. Where to put it? // In spec: non_assignment_expression.Rule = conditional_expression | lambda_expression | query_expression; //I think it's a mistake; there must be additional entry here for arithm expressions, so we put them here. // We also have to add "is" and "as" expressions here, as we don't build entire hierarchy of elements for expressing // precedence (where they appear in original spec); so we put them here bin_op.Rule = ToTerm("<") | "||" | "&&" | "|" | "^" | "&" | "==" | "!=" | ">" | "<=" | ">=" | "<<" | ">>" | "+" | "-" | "*" | "/" | "%" | "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "is" | "as" | "??"; //type_check_expression.Rule = expression + "is" + type_ref | expression + "as" + type_ref; //Queries query_expression.Rule = "from"; //B.2.5. Statements statement.Rule = labeled_statement | declaration_statement | embedded_statement; statement.ErrorRule = SyntaxError + semi; //skip all until semicolon statement_list.Rule = MakePlusRule(statement_list, null, statement); statement_list_opt.Rule = Empty | statement_list; //labeled_statement labeled_statement.Rule = identifier + colon + embedded_statement; //declaration_statement declaration_statement.Rule = local_variable_declaration + semi | local_constant_declaration + semi; local_variable_declaration.Rule = local_variable_type + local_variable_declarators; //!!! local_variable_type.Rule = member_access | "var"; // | builtin_type; //to fix the conflict, changing to member-access here local_variable_declarator.Rule = identifier | identifier + "=" + initializer_value; local_variable_declarators.Rule = MakePlusRule(local_variable_declarators, comma, local_variable_declarator); local_constant_declaration.Rule = "const" + type_ref + constant_declarators; //embedded_statement embedded_statement.Rule = block | semi /*empty_statement*/ | statement_expression + semi | selection_statement | iteration_statement | jump_statement | try_statement | checked_statement | unchecked_statement | lock_statement | using_statement | yield_statement; block.Rule = Lbr + statement_list_opt + Rbr; //selection (if and switch) selection_statement.Rule = if_statement | switch_statement; if_statement.Rule = ToTerm("if") + Lpar + expression + Rpar + embedded_statement + else_clause_opt; else_clause_opt.Rule = Empty | PreferShiftHere() + "else" + embedded_statement; switch_statement.Rule = "switch" + parenthesized_expression + Lbr + switch_sections_opt + Rbr; switch_section.Rule = switch_labels + statement_list; switch_sections_opt.Rule = MakeStarRule(switch_sections_opt, null, switch_section); switch_label.Rule = "case" + expression + colon | "default" + colon; switch_labels.Rule = MakePlusRule(switch_labels, null, switch_label); //iteration statements iteration_statement.Rule = while_statement | do_statement | for_statement | foreach_statement; while_statement.Rule = "while" + parenthesized_expression + embedded_statement; do_statement.Rule = "do" + embedded_statement + "while" + parenthesized_expression + semi; for_statement.Rule = "for" + Lpar + for_initializer_opt + semi + for_condition_opt + semi + for_iterator_opt + Rpar + embedded_statement; for_initializer_opt.Rule = Empty | local_variable_declaration | statement_expression_list; for_condition_opt.Rule = Empty | expression; for_iterator_opt.Rule = Empty | statement_expression_list; foreach_statement.Rule = "foreach" + Lpar + local_variable_type + identifier + "in" + expression + Rpar + embedded_statement; //jump-statement jump_statement.Rule = break_statement | continue_statement | goto_statement | return_statement | throw_statement; break_statement.Rule = "break" + semi; continue_statement.Rule = "continue" + semi; goto_statement.Rule = tgoto + identifier + semi | tgoto + "case" + expression + semi | tgoto + "default" + semi; return_statement.Rule = "return" + expression_opt + semi; throw_statement.Rule = "throw" + expression_opt + semi; //try-statement //changed to avoid conflicts; need to check correct ordering of catch/finally clause in after-parse validation try_statement.Rule = "try" + block + try_clauses; try_clause.Rule = catch_clause | finally_clause; try_clauses.Rule = MakePlusRule(try_clauses, null, try_clause); catch_clause.Rule = "catch" + catch_specifier_opt + block; finally_clause.Rule = "finally" + block; catch_specifier_opt.Rule = Empty | Lpar + qual_name_with_targs + identifier_opt + Rpar; identifier_opt.Rule = Empty | identifier; //checked, unchecked, locked, using checked_statement.Rule = "checked" + block; unchecked_statement.Rule = "unchecked" + block; lock_statement.Rule = "lock" + parenthesized_expression + embedded_statement; using_statement.Rule = "using" + Lpar + resource_acquisition + Rpar + embedded_statement; resource_acquisition.Rule = local_variable_declaration | expression; //yield statement yield_statement.Rule = yld + "return" + expression + semi | yld + "break" + semi; //expression statement // expression_statement.Rule = statement_expression + semi; statement_expression.Rule = object_creation_expression | member_access | member_access + assignment_operator + expression | pre_incr_decr_expression | post_incr_decr_expression ; statement_expression_list.Rule = MakePlusRule(statement_expression_list, comma, statement_expression); incr_or_decr_opt.Rule = Empty | ToTerm("++") | "--"; incr_or_decr.Rule = ToTerm("++") | "--"; //B.2.6. Namespaces this.Root = compilation_unit; compilation_unit.Rule = extern_alias_directives_opt + using_directives_opt + attributes_opt + namespace_declarations_opt; extern_alias_directive.Rule = PreferShiftHere() + ToTerm("extern") + "alias" + identifier + semi; extern_alias_directives_opt.Rule = MakeStarRule(extern_alias_directives_opt, null, extern_alias_directive); namespace_declaration.Rule = "namespace" + qualified_identifier + namespace_body + semi_opt; namespace_declarations_opt.Rule = MakeStarRule(namespace_declarations_opt, null, namespace_declaration); qualified_identifier.Rule = MakePlusRule(qualified_identifier, dot, identifier); namespace_body.Rule = "{" + extern_alias_directives_opt + using_directives_opt + namespace_member_declarations + "}"; using_directive.Rule = using_alias_directive | using_ns_directive; using_directives.Rule = MakePlusRule(using_directives, null, using_directive); using_directives_opt.Rule = Empty | using_directives; using_alias_directive.Rule = "using" + identifier + "=" + qual_name_with_targs + semi; using_ns_directive.Rule = "using" + qual_name_with_targs + semi; namespace_member_declaration.Rule = namespace_declaration | type_declaration; namespace_member_declarations.Rule = MakePlusRule(namespace_member_declarations, null, namespace_member_declaration); type_declaration.Rule = class_declaration | struct_declaration | interface_declaration | enum_declaration | delegate_declaration; //B.2.7. Classes class_declaration.Rule = member_header + "class" + identifier + type_parameter_list_opt + bases_opt + type_parameter_constraints_clauses_opt + class_body; class_body.Rule = Lbr + member_declarations_opt + Rbr; bases_opt.Rule = Empty | colon + base_type_list; base_type_list.Rule = MakePlusRule(base_type_list, comma, qual_name_with_targs); //Type parameters type_parameter.Rule = attributes_opt + identifier; type_parameters.Rule = MakePlusRule(type_parameters, comma, type_parameter); type_parameter_list_opt.Rule = Empty | gen_lt + type_parameters + ">"; type_parameter_constraints_clause.Rule = "where" + type_parameter + colon + type_parameter_constraints; type_parameter_constraints.Rule = MakePlusRule(type_parameter_constraints, comma, type_parameter_constraint); type_parameter_constraints_clauses_opt.Rule = MakeStarRule(type_parameter_constraints_clauses_opt, null, type_parameter_constraints_clause); //Note for post-processing - make sure the order is correct: new() is always last, etc. See p.503 of the spec type_parameter_constraint.Rule = qual_name_with_targs | "class" | "struct" | ToTerm("new") + Lpar + Rpar; //Class members //Note: we split operator-declaration into two separate operator elements: bin/unary and conversion operators // to avoid possible ambiguities and conflicts member_declaration.Rule = constant_declaration | field_declaration | method_declaration | property_declaration | event_declaration | indexer_declaration | operator_declaration | conversion_operator_declaration | constructor_declaration | destructor_declaration | type_declaration; member_declaration.ErrorRule = SyntaxError + ";" | SyntaxError + "}" ; member_declarations_opt.Rule = MakeStarRule(member_declarations_opt, null, member_declaration); //Modifiers - see note #1 in Notes.txt file modifier.Rule = ToTerm("new") | "public" | "protected" | "internal" | "private" | "static" | "virtual" | "sealed" | "override" | "abstract" | "readonly" | "volatile" | "partial" | "extern"; //!!! modifiers_opt.Rule = MakeStarRule(modifiers_opt, null, modifier); //Joined member header - see note #2 member_header.Rule = attributes_opt + modifiers_opt; constant_declaration.Rule = member_header + "const" + type_ref + constant_declarators + semi; constant_declarator.Rule = identifier + "=" + expression; constant_declarators.Rule = MakePlusRule(constant_declarators, comma, constant_declarator); field_declaration.Rule = member_header + type_ref + variable_declarators + semi; variable_declarator.Rule = identifier | identifier + "=" + elem_initializer; variable_declarators.Rule = MakePlusRule(variable_declarators, comma, variable_declarator); //See note #3 about merging type_parameter_list into type_arguments of the preceding qual_name. method_declaration.Rule = member_header + type_ref + qual_name_with_targs // + type_parameter_list.Q() + formal_parameter_list_par + type_parameter_constraints_clauses_opt + method_body; formal_parameter_list.Rule = fixed_parameters | fixed_parameters + comma + parameter_array | parameter_array; formal_parameter_list_par.Rule = Lpar + Rpar | Lpar + formal_parameter_list + Rpar; fixed_parameter.Rule = attributes_opt + parameter_modifier_opt + type_ref + identifier; fixed_parameters.Rule = MakePlusRule(fixed_parameters, comma, fixed_parameter); parameter_modifier_opt.Rule = Empty | "ref" | "out" | "this"; parameter_array.Rule = attributes_opt + "params" + type_ref + /*"[" + "]" + */ identifier; method_body.Rule = block | semi; // See note #4 about member-name //TODO: add after-parse validation that no more than one accessor of each type is there. property_declaration.Rule = member_header + type_ref + qual_name_with_targs/*member-name*/ + Lbr + accessor_declarations + Rbr; accessor_declaration.Rule = attributes_opt + accessor_modifier_opt + accessor_name + block; accessor_declarations.Rule = MakePlusRule(accessor_declarations, null, accessor_declaration); accessor_name.Rule = ToTerm("get") | "set"; accessor_modifier_opt.Rule = Empty | "protected" | "internal" | "private" | ToTerm("protected") + "internal" | ToTerm("internal") + "protected"; event_declaration.Rule = member_header + "event" + type_ref + event_body; event_body.Rule = variable_declarators + semi | qual_name_with_targs + Lbr + event_accessor_declarations + Rbr; event_accessor_declarations.Rule = add_accessor_declaration + remove_accessor_declaration | remove_accessor_declaration + add_accessor_declaration; add_accessor_declaration.Rule = attributes_opt + "add" + block; remove_accessor_declaration.Rule = attributes_opt + "remove" + block; //indexer indexer_declaration.Rule = member_header + type_ref + indexer_name + "[" + formal_parameter_list + "]" + Lbr + accessor_declarations + Rbr; indexer_name.Rule = "this" | qual_name_with_targs + dot + "this"; //operator // note: difference with specs - we separate unary/binary operators from conversion operator, // and join binary and unary operator definitions, see note #5 operator_declaration.Rule = member_header + type_ref + "operator" + overloadable_operator + Lpar + operator_parameters + Rpar + block; overloadable_operator.Rule = ToTerm("+") | "-" | "!" | "~" | "++" | "--" | "true" | "false" //unary operators | "*" | "/" | "%" | "&" | "|" | "^" | "<<" | ">>" | "==" | "!=" | ">" | "<" | ">=" | "<="; operator_parameters.Rule = operator_parameter | operator_parameter + comma + operator_parameter; operator_parameter.Rule = type_ref + identifier; conversion_operator_declaration.Rule = member_header + conversion_operator_kind + "operator" + type_ref + Lpar + operator_parameter + Rpar + block; conversion_operator_kind.Rule = ToTerm("implicit") | "explicit"; //constructor - also covers static constructor; the only difference is the word static constructor_declaration.Rule = member_header + identifier + formal_parameter_list_par + constructor_initializer_opt + block; constructor_initializer_opt.Rule = Empty | colon + constructor_base + argument_list_par; constructor_base.Rule = ToTerm("this") | "base"; destructor_declaration.Rule = member_header + // changed from Symbol("extern").Q() "~" + identifier + Lpar + Rpar + block; //B.2.8 struct_declaration.Rule = member_header + "struct" + identifier + type_parameter_list_opt + bases_opt + type_parameter_constraints_clauses_opt + struct_body; struct_body.Rule = Lbr + member_declarations_opt + Rbr; //B.2.9. Arrays //B.2.10 Interface interface_declaration.Rule = member_header + "interface" + identifier + type_parameter_list_opt + bases_opt + type_parameter_constraints_clauses_opt + interface_body; interface_body.Rule = Lbr + interface_member_declarations + Rbr; interface_member_declaration.Rule = interface_method_declaration | interface_property_declaration | interface_event_declaration | interface_indexer_declaration; interface_member_declarations.Rule = MakePlusRule(interface_member_declarations, null, interface_member_declaration); interface_method_declaration.Rule = attributes_opt + new_opt + type_ref + identifier + type_parameter_list_opt + formal_parameter_list_par + type_parameter_constraints_clauses_opt + semi; //NOte: changing type to type_ref to fix the conflict //Note: add after-parse validation that no more than one accessor of each type is there. interface_property_declaration.Rule = attributes_opt + new_opt + type_ref + identifier + Lbr + interface_accessors + Rbr; interface_accessor.Rule = attributes_opt + accessor_name + semi; interface_accessors.Rule = MakePlusRule(interface_accessors, null, interface_accessor); interface_event_declaration.Rule = attributes_opt + new_opt + "event" + type_ref + identifier; interface_indexer_declaration.Rule = attributes_opt + new_opt + type_ref + "this" + "[" + formal_parameter_list + "]" + Lbr + interface_accessors + Rbr; new_opt.Rule = Empty | "new"; //B.2.11 Enums enum_declaration.Rule = member_header + "enum" + identifier + enum_base_opt + Lbr + enum_member_declarations + Rbr + semi_opt; enum_base_opt.Rule = Empty | colon + integral_type; enum_member_declaration.Rule = attributes_opt + identifier | attributes_opt + identifier + "=" + expression; enum_member_declarations.Rule = MakeListRule(enum_member_declarations, comma, enum_member_declaration, TermListOptions.PlusList | TermListOptions.AllowTrailingDelimiter); //B.2.12 Delegates delegate_declaration.Rule = member_header + "delegate" + type_ref + identifier + type_parameter_list_opt + formal_parameter_list_par + type_parameter_constraints_clauses_opt + semi; //B.2.13. Attributes attributes_opt.Rule = MakeStarRule(attributes_opt, null, attribute_section); attribute_section.Rule = "[" + attribute_target_specifier_opt + attribute_list + comma_opt + "]"; attribute_list.Rule = MakePlusRule(attribute_list, comma, attribute); attribute.Rule = qual_name_with_targs + attribute_arguments_par_opt; attribute_target_specifier_opt.Rule = Empty | attribute_target + colon; attribute_target.Rule = ToTerm("field") | "event" | "method" | "param" | "property" | "return" | "type"; attribute_arguments_par_opt.Rule = Empty | Lpar + attribute_arguments_opt + Rpar; attribute_arguments_opt.Rule = MakeStarRule(attribute_arguments_opt, comma, attr_arg); attr_arg.Rule = identifier + "=" + expression | expression; //Prepare term set for conflict resolution _skipTokensInPreview.UnionWith(new Terminal[] { dot, identifier, comma, ToTerm("::"), comma, ToTerm("["), ToTerm("]") }); }
public LuaGrammar() : base(true) { #region Declare Terminals Here StringLiteral STRING = CreateLuaString("string"); NumberLiteral NUMBER = CreateLuaNumber("number"); LuaLongStringTerminal LONGSTRING = new LuaLongStringTerminal("long-string"); // This includes both single-line and block comments var Comment = new LuaCommentTerminal("block-comment"); // Regular Operators // Member Select Operators var DOT = Operator("."); DOT.EditorInfo = new TokenEditorInfo(TokenType.Operator, TokenColor.Text, TokenTriggers.MemberSelect); var COLON = Operator(":"); COLON.EditorInfo = new TokenEditorInfo(TokenType.Operator, TokenColor.Text, TokenTriggers.MemberSelect); // Standard Operators var EQ = Operator("="); //yujiang: Ignore comment NonGrammarTerminals.Add(Comment); #region Keywords var LOCAL = Keyword("local"); var DO = Keyword("do"); var END = Keyword("end"); var WHILE = Keyword("while"); var REPEAT = Keyword("repeat"); var UNTIL = Keyword("until"); var IF = Keyword("if"); var THEN = Keyword("then"); var ELSEIF = Keyword("elseif"); var ELSE = Keyword("else"); var FOR = Keyword("for"); var IN = Keyword("in"); var FUNCTION = Keyword("function"); var RETURN = Keyword("return"); var BREAK = Keyword("break"); var NIL = Keyword("nil"); var FALSE = Keyword("false"); var TRUE = Keyword("true"); var NOT = Keyword("not"); var AND = Keyword("and"); var OR = Keyword("or"); #endregion IdentifierTerminal Name = new IdentifierTerminal("identifier"); #endregion #region Declare NonTerminals Here NonTerminal Chunk = new NonTerminal("chunk"); NonTerminal Block = new NonTerminal("block"); NonTerminal Statement = new NonTerminal("statement"); NonTerminal LastStatement = new NonTerminal("last statement"); NonTerminal FuncName = new NonTerminal("function name"); NonTerminal VarList = new NonTerminal("var list"); NonTerminal Var = new NonTerminal("var"); NonTerminal NameList = new NonTerminal("name list"); NonTerminal ExprList = new NonTerminal("expr list"); NonTerminal Expr = new NonTerminal("expr"); NonTerminal PrefixExpr = new NonTerminal("prefix expr"); NonTerminal FunctionCall = new NonTerminal("function call"); NonTerminal Args = new NonTerminal("args"); NonTerminal NamedFunction = new NonTerminal("named function"); NonTerminal NamelessFunction = new NonTerminal("nameless function"); NonTerminal FuncBody = new NonTerminal("function body"); NonTerminal ParList = new NonTerminal("parlist"); NonTerminal TableConstructor = new NonTerminal("table constructor"); NonTerminal FieldList = new NonTerminal("field list"); NonTerminal Field = new NonTerminal("field"); NonTerminal FieldSep = new NonTerminal("field seperator"); NonTerminal BinOp = new NonTerminal("binop"); NonTerminal UnOp = new NonTerminal("unop"); #endregion #region Place Rules Here //Using Lua 5.1 grammar as defined in //http://www.lua.org/manual/5.1/manual.html#8 this.Root = Chunk; //chunk ::= {stat [`;´]} [laststat [`;´]] Chunk.Rule = (Statement + ToTerm(";").Q()).Star() + (LastStatement + ToTerm(";").Q()).Q(); //block ::= chunk Block = Chunk; //stat ::= varlist `=´ explist | // functioncall | // do block end | // while exp do block end | // repeat block until exp | // if exp then block {elseif exp then block} [else block] end | // for Name `=´ exp `,´ exp [`,´ exp] do block end | // for namelist in explist do block end | // function funcname funcbody | // local function Name funcbody | // local namelist [`=´ explist] Statement.Rule = VarList + "=" + ExprList | FunctionCall | DO + Block + END | WHILE + Expr + DO + Block + END | REPEAT + Block + UNTIL + Expr | IF + Expr + THEN + Block + (ELSEIF + Expr + THEN + Block).Star() + (ELSE + Block).Q() + END | FOR + Name + "=" + Expr + "," + Expr + ("," + Expr).Q() + DO + Block + END | FOR + NameList + IN + ExprList + DO + Block + END | NamedFunction | LOCAL + NamedFunction | LOCAL + NameList + ("=" + ExprList).Q(); //laststat ::= return [explist] | break LastStatement.Rule = RETURN + ExprList.Q() | BREAK; //funcname ::= Name {`.´ Name} [`:´ Name] FuncName.Rule = Name + (DOT + Name).Star() + (COLON + Name).Q(); //NamedFunction = 'function' + FuncName + FuncBody NamedFunction.Rule = FUNCTION + FuncName + FuncBody; //varlist ::= var {`,´ var} VarList.Rule = MakePlusRule(VarList, ToTerm(","), Var); //namelist ::= Name {`,´ Name} NameList.Rule = MakePlusRule(NameList, ToTerm(","), Name); //explist ::= {exp `,´} exp ExprList.Rule = MakePlusRule(ExprList, ToTerm(","), Expr); //exp ::= nil | false | true | Number | String | `...´ | function | // prefixexp | tableconstructor | exp binop exp | unop exp Expr.Rule = NIL | FALSE | TRUE | NUMBER | STRING | LONGSTRING | "..." | NamelessFunction | PrefixExpr | TableConstructor | Expr + BinOp + Expr | UnOp + Expr; //var ::= Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name Var.Rule = Name | PrefixExpr + "[" + Expr + "]" | PrefixExpr + DOT + Name; //prefixexp ::= var | functioncall | `(´ exp `)´ PrefixExpr.Rule = Var | FunctionCall | "(" + Expr + ")"; //functioncall ::= prefixexp args | prefixexp `:´ Name args FunctionCall.Rule = PrefixExpr + Args | PrefixExpr + COLON + Name + Args; //args ::= `(´ [explist] `)´ | tableconstructor | String Args.Rule = "(" + ExprList.Q() + ")" | TableConstructor | STRING | LONGSTRING; //function ::= function funcbody NamelessFunction.Rule = FUNCTION + FuncBody; //funcbody ::= `(´ [parlist] `)´ block end FuncBody.Rule = "(" + ParList.Q() + ")" + Block + END; //parlist ::= namelist [`,´ `...´] | `...´ ParList.Rule = NameList + (ToTerm(",") + "...").Q() | "..."; //tableconstructor ::= `{´ [fieldlist] `}´ TableConstructor.Rule = "{" + FieldList.Q() + "}"; //fieldlist ::= field {fieldsep field} [fieldsep] FieldList.Rule = Field + (FieldSep + Field).Star() + FieldSep.Q(); //field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp Field.Rule = "[" + Expr + "]" + "=" + Expr | Name + "=" + Expr | Expr; //fieldsep ::= `,´ | `;´ FieldSep.Rule = ToTerm(",") | ";"; //binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ | // `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ | // and | or BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "^" | "%" | ".." | "<" | "<=" | ">" | ">=" | "==" | "~=" | AND | OR; //unop ::= `-´ | not | `#´ UnOp.Rule = ToTerm("-") | NOT | "#"; #endregion #region Define Keywords and Register Symbols this.RegisterBracePair("(", ")"); this.RegisterBracePair("{", "}"); this.RegisterBracePair("[", "]"); this.MarkPunctuation(",", ";"); this.RegisterOperators(1, OR); this.RegisterOperators(2, AND); this.RegisterOperators(3, "<",">","<=",">=","~=","=="); this.RegisterOperators(4, Associativity.Right, ".."); this.RegisterOperators(5, "+", "-"); this.RegisterOperators(6, "*", "/", "%"); this.RegisterOperators(7, NOT); //also -(unary) this.RegisterOperators(8, Associativity.Right, "^"); #endregion //yujiang: register lua functions //this.LuaRegisterFunctions(); }
private LuaGrammar() : base(true) { #region Declare Terminals Here StringLiteral STRING = CreateLuaString(LuaTerminalNames.String); NumberLiteral NUMBER = CreateLuaNumber(LuaTerminalNames.Number); LuaLongStringTerminal LONGSTRING = new LuaLongStringTerminal(LuaTerminalNames.LongString); // This includes both single-line and block comments var Comment = new LuaCommentTerminal(LuaTerminalNames.Comment); // Regular Operators var DOT = ToTerm(LuaTerminalNames.Dot); var COLON = ToTerm(LuaTerminalNames.Colon); var SEMIC = ToTerm(LuaTerminalNames.Semic); var COMMA = ToTerm(LuaTerminalNames.Comma); // Standard Operators var EQ = Operator(LuaTerminalNames.Equal); var OpeAdd = Operator("+"); var OpeSub = Operator("-"); var OpeMul = Operator("*"); var OpeDiv = Operator("/"); var OpePow = Operator("^"); var OpeEQ = Operator("=="); var OpeNEQ = Operator("~="); var OpeBig = Operator(">"); var OpeBigEQ = Operator(">="); var OpeSm = Operator("<"); var OpeSmEQ = Operator("<="); var OpeLink = Operator(".."); var OpePre = Operator("%"); var OpeWell = Operator("#"); NonGrammarTerminals.Add(Comment); #region Keywords var LOCAL = Keyword("local"); var DO = Keyword("do"); var END = Keyword("end"); var WHILE = Keyword("while"); var REPEAT = Keyword("repeat"); var UNTIL = Keyword("until"); var IF = Keyword("if"); var THEN = Keyword("then"); var ELSEIF = Keyword("elseif"); var ELSE = Keyword("else"); var FOR = Keyword("for"); var IN = Keyword("in"); var FUNCTION = Keyword("function"); var RETURN = Keyword("return"); var BREAK = Keyword("break"); var NIL = Keyword("nil"); var FALSE = Keyword("false"); var TRUE = Keyword("true"); var NOT = Keyword("not"); var AND = Keyword("and"); var OR = Keyword("or"); //var CLASS = Keyword("class"); //var NEW = Keyword("new"); #endregion IdentifierTerminal Name = new IdentifierTerminal(LuaTerminalNames.Identifier); #endregion #region Declare NonTerminals Here NonTerminal Chunk = new NonTerminal(LuaTerminalNames.Chunk); NonTerminal Block = new NonTerminal(LuaTerminalNames.Block); NonTerminal Statement = new NonTerminal(LuaTerminalNames.Statement); NonTerminal LastStatement = new NonTerminal(LuaTerminalNames.LastStatement); NonTerminal FuncName = new NonTerminal(LuaTerminalNames.FunctionName); NonTerminal VarList = new NonTerminal(LuaTerminalNames.VarList); NonTerminal Var = new NonTerminal(LuaTerminalNames.Var); NonTerminal NameList = new NonTerminal(LuaTerminalNames.NameList); NonTerminal ExprList = new NonTerminal(LuaTerminalNames.ExprList); NonTerminal Expr = new NonTerminal(LuaTerminalNames.Expr); NonTerminal PrefixExpr = new NonTerminal(LuaTerminalNames.PrefixExpr); NonTerminal FunctionCall = new NonTerminal(LuaTerminalNames.FunctionCall); NonTerminal Args = new NonTerminal(LuaTerminalNames.Args); NonTerminal NamedFunction = new NonTerminal(LuaTerminalNames.NamedFunction); NonTerminal NamelessFunction = new NonTerminal(LuaTerminalNames.NamelessFunction); NonTerminal FuncBody = new NonTerminal(LuaTerminalNames.FunctionBody); NonTerminal ParList = new NonTerminal(LuaTerminalNames.ParList); NonTerminal TableConstructor = new NonTerminal(LuaTerminalNames.TableConstructor); NonTerminal FieldList = new NonTerminal(LuaTerminalNames.FieldList); NonTerminal Field = new NonTerminal(LuaTerminalNames.Field); NonTerminal FieldSep = new NonTerminal(LuaTerminalNames.FieldSeperator); NonTerminal BinOp = new NonTerminal(LuaTerminalNames.Binop); NonTerminal UnOp = new NonTerminal(LuaTerminalNames.Unop); NonTerminal LoopBlock = new NonTerminal(LuaTerminalNames.LoopBlock); NonTerminal BranchBlock = new NonTerminal(LuaTerminalNames.BranchBlock); NonTerminal Assign = new NonTerminal(LuaTerminalNames.Assign); NonTerminal LocalVar = new NonTerminal(LuaTerminalNames.LocalVar); #endregion #region Place Rules Here //Using Lua 5.1 grammar as defined in //http://www.lua.org/manual/5.1/manual.html#8 this.Root = Chunk; //chunk ::= {stat [`;´]} [laststat [`;´]] Chunk.Rule = MakeStarRule(Chunk, Statement + SEMIC.Q()) + (LastStatement + SEMIC.Q()).Q(); //block ::= chunk Block = Chunk; //stat ::= varlist `=´ explist | // functioncall | // do block end | // while exp do block end | // repeat block until exp | // if exp then block {elseif exp then block} [else block] end | // for Name `=´ exp `,´ exp [`,´ exp] do block end | // for namelist in explist do block end | // function funcname funcbody | // local function Name funcbody | // local namelist [`=´ explist] Statement.Rule = Assign | FunctionCall | DO + Block + END | LoopBlock | BranchBlock | NamedFunction | LocalVar ; Assign.Rule = VarList + EQ + ExprList; LoopBlock.Rule = WHILE + Expr + DO + Block + END | REPEAT + Block + UNTIL + Expr | FOR + Name + EQ + Expr + COMMA + Expr + (COMMA + Expr).Q() + DO + Block + END | FOR + NameList + IN + ExprList + DO + Block + END; BranchBlock.Rule = IF + Expr + THEN + Block + MakeStarRule(BranchBlock, ELSEIF + Expr + THEN + Block) + (ELSE + Block).Q() + END; LocalVar.Rule = LOCAL + NamedFunction | LOCAL + NameList + (EQ + ExprList).Q(); //laststat ::= return [explist] | break LastStatement.Rule = RETURN + ExprList.Q() | BREAK; //funcname ::= Name {`.´ Name} [`:´ Name] FuncName.Rule = Name + MakeStarRule(DOT + Name) + (COLON + Name).Q(); //NamedFunction = 'function' + FuncName + FuncBody NamedFunction.Rule = FUNCTION + FuncName + FuncBody; //varlist ::= var {`,´ var} VarList.Rule = MakePlusRule(VarList, COMMA, Var); //namelist ::= Name {`,´ Name} NameList.Rule = MakePlusRule(NameList, COMMA, Name); //explist ::= {exp `,´} exp ExprList.Rule = MakePlusRule(ExprList, COMMA, Expr); //exp ::= nil | false | true | Number | String | `...´ | function | // prefixexp | tableconstructor | exp binop exp | unop exp Expr.Rule = NIL | FALSE | TRUE | NUMBER | STRING | LONGSTRING | "..." | NamelessFunction | PrefixExpr | TableConstructor | Expr + BinOp + Expr | UnOp + Expr; //var ::= Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name Var.Rule = Name | PrefixExpr + "[" + Expr + "]" | PrefixExpr + DOT + Name; //prefixexp ::= var | functioncall | `(´ exp `)´ PrefixExpr.Rule = Var | FunctionCall | "(" + Expr + ")"; //functioncall ::= prefixexp args | prefixexp `:´ Name args FunctionCall.Rule = PrefixExpr + Args | PrefixExpr + COLON + Name + Args; //args ::= `(´ [explist] `)´ | tableconstructor | String Args.Rule = "(" + ExprList.Q() + ")" | TableConstructor | STRING | LONGSTRING; //function ::= function funcbody NamelessFunction.Rule = FUNCTION + FuncBody; //funcbody ::= `(´ [parlist] `)´ block end FuncBody.Rule = "(" + ParList.Q() + ")" + Block + END; //parlist ::= namelist [`,´ `...´] | `...´ ParList.Rule = NameList + (COMMA + "...").Q() | "..."; //tableconstructor ::= `{´ [fieldlist] `}´ TableConstructor.Rule = "{" + FieldList.Q() + "}"; //fieldlist ::= field {fieldsep field} [fieldsep] //FieldList.Rule = Field + MakeStarRule(FieldSep + Field) + FieldSep.Q(); FieldList.Rule = MakePlusRule(FieldList, Field + FieldSep.Q()); //field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp Field.Rule = "[" + Expr + "]" + EQ + Expr | Name + EQ + Expr | Expr; //fieldsep ::= `,´ | `;´ FieldSep.Rule = COMMA | SEMIC; //binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ | // `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ | // and | or BinOp.Rule = OpeAdd | OpeSub | OpeMul | OpeDiv | OpePow | OpePre | OpeLink | OpeSm | OpeSmEQ | OpeBig | OpeBigEQ | OpeEQ | OpeNEQ | AND | OR; //unop ::= `-´ | not | `#´ UnOp.Rule = NOT | OpeSub | OpeWell; #endregion #region Define Keywords and Register Symbols this.RegisterBracePair("(", ")"); this.RegisterBracePair("{", "}"); this.RegisterBracePair("[", "]"); this.MarkPunctuation(",", ";"); this.RegisterOperators(1, OR); this.RegisterOperators(2, AND); this.RegisterOperators(3, OpeBigEQ, OpeBig, OpeSm, OpeSmEQ, OpeNEQ, OpeEQ); this.RegisterOperators(4, Associativity.Right, OpeLink); this.RegisterOperators(5, OpeAdd, OpeSub); this.RegisterOperators(6, OpeMul, OpeDiv, OpePre); this.RegisterOperators(7, NOT); this.RegisterOperators(8, Associativity.Right, OpePow); #endregion }
TerminalSet _skipTokensInPreview = new TerminalSet(); //used in token preview for conflict resolution #endregion Fields #region Constructors public XLANGsGrammar() { var xlang_orchestration = new NonTerminal("orchestration"); var xlang_module = new NonTerminal("module"); var xlang_module_identifier = new NonTerminal("module_identifier"); var xlang_operators = new NonTerminal("operators"); var xlang_type_definitions = new NonTerminal("type_definitions"); var xlang_type_definition_att_opt = new NonTerminal("type_definition_att?"); var xlang_type_definition = new NonTerminal("type_definition"); var xlang_type_definition_choice = new NonTerminal("type_definition_choice"); var xlang_servicetype_definition = new NonTerminal("service_type_definition"); var xlang_servicetype_definitions = new NonTerminal("servicetype_definitions"); var xlang_accesmodifier_choice = new NonTerminal("accesmodifier_choice"); var xlang_mep_choice = new NonTerminal("mep_choice"); var xlang_body = new NonTerminal("body"); var xlang_exceptions = new NonTerminal("exceptions"); var xlang_exceptions_opt = new NonTerminal("exceptions?"); var xlang_catch_clauses = new NonTerminal("catch_clauses"); var xlang_catch_clause_att_opt = new NonTerminal("catch_clause_att?"); var xlang_compensation = new NonTerminal("compensation"); var xlang_compensation_opt = new NonTerminal("compensation?"); var xlang_transaction_declaration_opt = new NonTerminal("transaction_declaration?"); var xlang_transaction_declaration = new NonTerminal("transaction_declaration"); var xlang_transaction_type_opt = new NonTerminal("transaction_type?"); var xlang_transaction_type_choice = new NonTerminal("transaction_type_choice"); var xlang_messagetypes = new NonTerminal("messagetypes"); var xlang_messagetype_definition = new NonTerminal("messagetype_definition"); var xlang_message_parts = new NonTerminal("message_parts"); var xlang_body_part = new NonTerminal("body_part"); var xlang_messagepart_choice = new NonTerminal("messagepart_choice"); var xlang_porttype_definitions = new NonTerminal("porttype_definitions"); var xlang_porttype_definition = new NonTerminal("porttype_definition"); var xlang_porttype_operations = new NonTerminal("porttype_operations"); var xlang_porttype_operation = new NonTerminal("porttype_operation"); var xlang_operation_messagetypes = new NonTerminal("operation_messagetypes"); var xlang_operation_messagetype_choice = new NonTerminal("operation_messagetype_choice"); var xlang_operation_fault_messagetype = new NonTerminal("operation_fault_messagetype"); var xlang_correlationtypes = new NonTerminal("correlationtypes"); var xlang_correlationtype_definition = new NonTerminal("correlationtype_definition"); var xlang_servicelinktypes = new NonTerminal("servicelinktypes"); var xlang_servicelinktype_definition = new NonTerminal("servicelinktype_definition"); var xlang_type_choice = new NonTerminal("type_choice"); var xlang_porttype = new NonTerminal("porttype"); var xlang_correlationtype = new NonTerminal("correlationtype"); var xlang_messagetype = new NonTerminal("messagetype"); var xlang_servicelinktype = new NonTerminal("servicelinktype"); var xlang_port_direction = new NonTerminal("port_direction"); var xlang_scope = new NonTerminal("scope"); var xlang_correlation_properties = new NonTerminal("correlation_properties"); var xlang_nonbody_part = new NonTerminal("nonbody_part"); var xlang_operation_messagetype = new NonTerminal("operation_messagetype"); var xlang_call_statement = new NonTerminal("call_statement"); var xlang_exec_statement = new NonTerminal("exec_statement"); var xlang_statement_choice = new NonTerminal("statement"); var xlang_statement_att_opt = new NonTerminal("statement_att?"); var xlang_statement_list = new NonTerminal("statement_list"); var xlang_task = new NonTerminal("task"); var xlang_tasks = new NonTerminal("tasks"); var xlang_parallel = new NonTerminal("parallel"); var xlang_send_statement = new NonTerminal("send_statement"); var xlang_receive = new NonTerminal("receive"); var xlang_receive_statement = new NonTerminal("receive_statement"); var xlang_suspend_statement = new NonTerminal("suspend_statement"); var xlang_terminate_statement = new NonTerminal("terminate_statement"); var xlang_construct = new NonTerminal("construct"); var xlang_message_identifiers = new NonTerminal("message_identifiers"); var xlang_construct_choice = new NonTerminal("construct_choice"); var xlang_transform_statement = new NonTerminal("transform_statement"); var xlang_construct_statements = new NonTerminal("construct_statements"); var xlang_construct_choice_att_opt = new NonTerminal("construct_choice_att?"); var xlang_receive_branch = new NonTerminal("receive_branch"); var xlang_timeout_branch = new NonTerminal("timeout_branch"); var xlang_listen = new NonTerminal("listen"); var xlang_listen_choice = new NonTerminal("listen_choice"); var xlang_listen_branch_att_opt = new NonTerminal("listen_branch_att?"); var xlang_listen_branches = new NonTerminal("listen_branches"); var xlang_delay = new NonTerminal("delay"); var xlang_delay_statement = new NonTerminal("delay_statement"); var xlang_limited_object_creation_expression = new NonTerminal("limited_object_creation_expression"); var xlang_timespan_returning_expression = new NonTerminal("timespan_returning_expression"); var xlang_activate_opt = new NonTerminal("activate?"); var xlang_scope_statement_att_opt = new NonTerminal("scope_statement_att?"); var xlang_scope_statements = new NonTerminal("scope_statements"); var xlang_scope_statements_opt = new NonTerminal("scope_statements?"); var xlang_scope_implementation = new NonTerminal("scope_impl"); var xlang_module_att_opt = new NonTerminal("module_att?"); var xlang_longrunning_transaction = new NonTerminal("lr_transaction"); var xlang_atomic_transaction = new NonTerminal("atomic_transaction"); var xlang_scope_statement_choice = new NonTerminal("scope_statement_choice"); var xlang_formal_parameters_par_opt = new NonTerminal("formal_parameter_list_par?"); var xlang_roletypes = new NonTerminal("roletypes"); var xlang_roletype = new NonTerminal("roletype"); var xlang_receive_operation = new NonTerminal("receive_operation"); var xlang_follow_correlation = new NonTerminal("follow_correlation"); var xlang_initialize_correlation = new NonTerminal("initialize_correlation"); var xlang_correlation_arg_choice = new NonTerminal("correlation_args"); var xlang_correlation_args = new NonTerminal("correlation_args"); var xlang_correlation_args_opt = new NonTerminal("correlation_args?"); var xlang_receive_arguments = new NonTerminal("receive_arguments"); var xlang_send_arguments = new NonTerminal("send_arguments"); var xlang_exists_expression_short = new NonTerminal("exists_expression"); var xlang_xpath_expression_short = new NonTerminal("xpath_expression_short"); var xlang_xpath_expression_long = new NonTerminal("xpath_expression_long"); var xlang_xpath_expression_choice = new NonTerminal("xpath_expression_choice"); var xlang_property_reference = new NonTerminal("property_reference"); var xlang_exists_expression_choice = new NonTerminal("exists_expression_choice"); var xlang_exists_expression_message_reference = new NonTerminal("exists_expression_message_reference"); var xlang_exists_expression_message_part_reference = new NonTerminal("exists_expression_message_part_reference"); var xlang_intrinsic_expression = new NonTerminal("intrinsic_expression"); var xlang_message_reference = new NonTerminal("message_reference"); var xlang_message_part_reference = new NonTerminal("messagepart_reference"); var xlang_message_or_message_part_reference_choice = new NonTerminal("xlang_message_or_message_part_reference"); var xlang_message_identifier = TerminalFactory.CreateCSharpIdentifier("message_identifier"); var xlang_messagepart_identifier = TerminalFactory.CreateCSharpIdentifier("messagepart_identifier"); var xlang_messagetype_identifier = TerminalFactory.CreateCSharpIdentifier("message_type_identifier"); var xlang_porttype_identifier = TerminalFactory.CreateCSharpIdentifier("port_type_identifier"); var xlang_operation_identifier = TerminalFactory.CreateCSharpIdentifier("port_operation_identifier"); var xlang_correlationtype_identifier = TerminalFactory.CreateCSharpIdentifier("correlation_type_identifier"); var xlang_servicelinktype_identifier = TerminalFactory.CreateCSharpIdentifier("servicelink_type_identifier"); var xlang_transaction_identifier = TerminalFactory.CreateCSharpIdentifier("transaction_identifier"); var xlang_roletype_identifier = TerminalFactory.CreateCSharpIdentifier("roletype_identifier"); //Temporarily, treat preprocessor instructions like comments CommentTerminal ppInstruction = new CommentTerminal("ppInstruction", "#", "\n"); NonGrammarTerminals.Add(ppInstruction); //ignore designer data, must be below above rule for preprocessor var designer_data = new CommentTerminal("designer_data", "#if __DESIGNER_DATA", "#endif"); NonGrammarTerminals.Add(designer_data); this.MarkReservedWords("activate", "atomic", "body", "call", "catch", "checked", "compensate", "compensation", "construct", "correlation", "correlationtype", "delay", "dynamic", "else", "exceptions", "exec", "exists", "false", "if", "implements", "in", "initialize", "internal", "link", "listen", "longrunning", "message", "messagetype", "method", "module", "new", "null", "oneway", "out", "parallel", "port", "porttype", "private", "public", "receive", "ref", "request", "requestresponse", "response", "scope", "send", "service", "servicelink", "servicelinktype", "source", "suppressfailure", "suspend", "succeeded", "target", "task", "terminate", "throw", "timeout", "transaction", "transform", "true", "unchecked", "until", "uses", "using", "while", "xpath"); #region CSharp #region Comments //copy of c-sharp comments CommentTerminal single_line_comment = new CommentTerminal("single_line_comment", "//", "\r", "\n", "\u2085", "\u2028", "\u2029"); CommentTerminal delimited_comment = new CommentTerminal("delimited_comment", "/*", "*/"); NonGrammarTerminals.Add(single_line_comment); NonGrammarTerminals.Add(delimited_comment); #endregion #region Lexical structure StringLiteral StringLiteral = TerminalFactory.CreateCSharpString("StringLiteral"); StringLiteral CharLiteral = TerminalFactory.CreateCSharpChar("CharLiteral"); NumberLiteral Number = TerminalFactory.CreateCSharpNumber("Number"); IdentifierTerminal identifier = TerminalFactory.CreateCSharpIdentifier("Identifier"); CommentTerminal SingleLineComment = new CommentTerminal("SingleLineComment", "//", "\r", "\n", "\u2085", "\u2028", "\u2029"); CommentTerminal DelimitedComment = new CommentTerminal("DelimitedComment", "/*", "*/"); NonGrammarTerminals.Add(SingleLineComment); NonGrammarTerminals.Add(DelimitedComment); //Symbols KeyTerm colon = ToTerm(":", "colon"); KeyTerm semi = ToTerm(";", "semi"); NonTerminal semi_opt = new NonTerminal("semi?"); semi_opt.Rule = Empty | semi; KeyTerm dot = ToTerm(".", "dot"); KeyTerm comma = ToTerm(",", "comma"); NonTerminal comma_opt = new NonTerminal("comma_opt", Empty | comma); NonTerminal commas_opt = new NonTerminal("commas?"); commas_opt.Rule = MakeStarRule(commas_opt, null, comma); KeyTerm qmark = ToTerm("?", "qmark"); NonTerminal qmark_opt = new NonTerminal("qmark_opt", Empty | qmark); KeyTerm lbr = ToTerm("{"); KeyTerm rbr = ToTerm("}"); KeyTerm lpar = ToTerm("("); KeyTerm rpar = ToTerm(")"); KeyTerm tgoto = ToTerm("goto"); KeyTerm yld = ToTerm("yield"); KeyTerm lparx = ToTerm("(*"); #endregion #region NonTerminals //B.2.1. Basic concepts var qual_name_with_targs = new NonTerminal("qual_name_with_targs"); var base_type_list = new NonTerminal("base_type_list"); var generic_dimension_specifier = new NonTerminal("generic_dimension_specifier"); var qual_name_segment = new NonTerminal("qual_name_segment"); var qual_name_segments_opt = new NonTerminal("qual_name_segments?"); var type_or_void = new NonTerminal("type_or_void", "type or void"); var builtin_type = new NonTerminal("builtin_type", "built-in type"); var type_ref_list = new NonTerminal("type_ref_list"); var identifier_ext = new NonTerminal("identifier_ext"); var identifier_or_builtin = new NonTerminal("identifier_or_builtin"); //B.2.2. Types var type_ref = new NonTerminal("type_ref"); var new_type_ref = new NonTerminal("new_type_ref"); var type_argument_list = new NonTerminal("type_argument_list"); var type_argument_list_opt = new NonTerminal("type_argument_list?"); var integral_type = new NonTerminal("integral_type"); //B.2.4. Expressions var argument = new NonTerminal("argument"); var argument_list = new NonTerminal("argument_list"); var argument_list_opt = new NonTerminal("argument_list?"); var expression = new NonTerminal("expression", "expression"); var expression_list = new NonTerminal("expression_list"); var expression_opt = new NonTerminal("expression?"); var conditional_expression = new NonTerminal("conditional_expression"); var lambda_expression = new NonTerminal("lambda_expression"); var query_expression = new NonTerminal("query_expression"); var unary_operator = new NonTerminal("unary_operator"); var assignment_operator = new NonTerminal("assignment_operator"); var primary_expression = new NonTerminal("primary_expression"); var pre_incr_decr_expression = new NonTerminal("pre_incr_decr_expression"); var post_incr_decr_expression = new NonTerminal("post_incr_decr_expression"); var primary_no_array_creation_expression = new NonTerminal("primary_no_array_creation_expression"); var literal = new NonTerminal("literal"); var parenthesized_expression = new NonTerminal("parenthesized_expression"); var member_access = new NonTerminal("member_access"); var member_access_segment = new NonTerminal("member_access_segment"); var member_access_segments_opt = new NonTerminal("member_access_segments?"); var array_indexer = new NonTerminal("array_indexer"); var argument_list_par = new NonTerminal("argument_list_par"); var argument_list_par_opt = new NonTerminal("argument_list_par?"); var incr_or_decr = new NonTerminal("incr_or_decr"); var incr_or_decr_opt = new NonTerminal("incr_or_decr?"); var creation_args = new NonTerminal("creation_args"); var object_creation_expression = new NonTerminal("object_creation_expression"); // delegate creation is syntactically equiv to object creation //var delegate_creation_expression = new NonTerminal("delegate_creation_expression"); var anonymous_object_creation_expression = new NonTerminal("anonymous_object_creation_expression"); var typeof_expression = new NonTerminal("typeof_expression"); var checked_expression = new NonTerminal("checked_expression"); var unchecked_expression = new NonTerminal("unchecked_expression"); var default_value_expression = new NonTerminal("default_value_expression"); var anonymous_method_expression = new NonTerminal("anonymous_method_expression"); var elem_initializer = new NonTerminal("elem_initializer"); var elem_initializer_list = new NonTerminal("elem_initializer_list"); var elem_initializer_list_ext = new NonTerminal("elem_initializer_list_ext"); var initializer_value = new NonTerminal("initializer_value"); var anonymous_object_initializer = new NonTerminal("anonymous_object_initializer"); var member_declarator = new NonTerminal("member_declarator"); var member_declarator_list = new NonTerminal("member_declarator_list"); var unbound_type_name = new NonTerminal("unbound_type_name"); var generic_dimension_specifier_opt = new NonTerminal("generic_dimension_specifier?"); var anonymous_function_signature = new NonTerminal("anonymous_function_signature"); var anonymous_function_signature_opt = new NonTerminal("anonymous_function_signature?"); var anonymous_function_parameter = new NonTerminal("anonymous_function_parameter"); var anonymous_function_parameter_decl = new NonTerminal("anonymous_function_parameter_decl"); var anonymous_function_parameter_list_opt = new NonTerminal("anonymous_function_parameter_list?"); var anonymous_function_parameter_modifier_opt = new NonTerminal("anonymous_function_parameter_modifier?"); var anonymous_function_body = new NonTerminal("anonymous_function_body"); var lambda_function_signature = new NonTerminal("lambda_function_signature"); var bin_op_expression = new NonTerminal("bin_op_expression"); var typecast_expression = new NonTerminal("typecast_expression"); var bin_op = new NonTerminal("bin_op", "operator symbol"); //B.2.5. Statements var statement = new NonTerminal("statement", "statement"); var statement_list = new NonTerminal("statement_list"); var statement_list_opt = new NonTerminal("statement_list?"); var labeled_statement = new NonTerminal("labeled_statement"); var declaration_statement = new NonTerminal("declaration_statement"); var embedded_statement = new NonTerminal("embedded_statement"); var embedded_statement_attributes_opt = new NonTerminal("embedded_statement_attributes?"); var selection_statement = new NonTerminal("selection_statement"); var iteration_statement = new NonTerminal("iteration_statement"); var jump_statement = new NonTerminal("jump_statement"); var try_statement = new NonTerminal("try_statement"); var checked_statement = new NonTerminal("checked_statement"); var unchecked_statement = new NonTerminal("unchecked_statement"); var lock_statement = new NonTerminal("lock_statement"); var using_statement = new NonTerminal("using_statement"); var yield_statement = new NonTerminal("yield_statement"); var block = new NonTerminal("block"); var statement_expression = new NonTerminal("statement_expression"); var statement_expression_list = new NonTerminal("statement_expression_list"); var local_variable_declaration = new NonTerminal("local_variable_declaration"); var local_constant_declaration = new NonTerminal("local_constant_declaration"); var local_variable_type = new NonTerminal("local_variable_type"); var local_variable_declarator = new NonTerminal("local_variable_declarator"); var local_variable_declarators = new NonTerminal("local_variable_declarators"); var if_statement = new NonTerminal("if_statement"); var switch_statement = new NonTerminal("switch_statement"); var else_clause_opt = new NonTerminal("else_clause?"); var switch_section = new NonTerminal("switch_section"); var switch_sections_opt = new NonTerminal("switch_sections?"); var switch_label = new NonTerminal("switch_label"); var switch_labels = new NonTerminal("switch_labels"); var while_statement = new NonTerminal("while_statement"); var do_statement = new NonTerminal("do_statement"); var for_statement = new NonTerminal("for_statement"); var foreach_statement = new NonTerminal("foreach_statement"); var for_initializer_opt = new NonTerminal("for_initializer?"); var for_condition_opt = new NonTerminal("for_condition?"); var for_iterator_opt = new NonTerminal("for_iterator?"); var break_statement = new NonTerminal("break_statement"); var continue_statement = new NonTerminal("continue_statement"); var goto_statement = new NonTerminal("goto_statement"); var return_statement = new NonTerminal("return_statement"); var throw_statement = new NonTerminal("throw_statement"); var try_clause = new NonTerminal("try_clause"); var try_clauses = new NonTerminal("try_clauses"); var catch_clause = new NonTerminal("catch_clause"); var finally_clause = new NonTerminal("finally_clause"); var catch_specifier_opt = new NonTerminal("catch_specifier?"); var identifier_opt = new NonTerminal("identifier?"); var resource_acquisition = new NonTerminal("resource_acquisition"); //namespaces, compilation units var compilation_unit = new NonTerminal("compilation_unit"); var extern_alias_directive = new NonTerminal("extern_alias_directive"); var extern_alias_directives_opt = new NonTerminal("extern_alias_directives?"); var using_directive = new NonTerminal("using_directive"); var using_directives = new NonTerminal("using_directives"); var using_directives_opt = new NonTerminal("using_directives?"); var namespace_declaration = new NonTerminal("namespace_declaration"); var namespace_declarations_opt = new NonTerminal("namespace_declarations?"); var qualified_identifier = new NonTerminal("qualified_identifier"); var namespace_body = new NonTerminal("namespace_body"); var namespace_member_declaration = new NonTerminal("namespace_member_declaration"); var namespace_member_declarations = new NonTerminal("namespace_member_declarations"); var using_alias_directive = new NonTerminal("using_alias_directive"); var using_ns_directive = new NonTerminal("using_ns_directive"); var type_declaration = new NonTerminal("type_declaration"); var class_declaration = new NonTerminal("class_declaration"); var delegate_declaration = new NonTerminal("delegate_declaration"); var qualified_alias_member = new NonTerminal("qualified_alias_member"); var class_body = new NonTerminal("class_body"); //B.2.7 Classes //Terminal partial = ToTerm("partial"); var type_parameter_list_opt = new NonTerminal("type_parameter_list?"); var type_parameter = new NonTerminal("type_parameter"); var type_parameters = new NonTerminal("type_parameters"); var bases_opt = new NonTerminal("bases?"); var type_parameter_constraints_clause = new NonTerminal("type_parameter_constraints_clause"); var type_parameter_constraints_clauses_opt = new NonTerminal("type_parameter_constraints_clauses"); var type_parameter_constraint = new NonTerminal("type_parameter_constraint"); var type_parameter_constraints = new NonTerminal("type_parameter_constraints"); var member_declaration = new NonTerminal("member_declaration"); var member_declarations_opt = new NonTerminal("member_declarations?"); var constant_declaration = new NonTerminal("constant_declaration"); var field_declaration = new NonTerminal("field_declaration"); var method_declaration = new NonTerminal("method_declaration"); var property_declaration = new NonTerminal("property_declaration"); var event_declaration = new NonTerminal("event_declaration"); var indexer_declaration = new NonTerminal("indexer_declaration"); var constructor_declaration = new NonTerminal("constructor_declaration"); var destructor_declaration = new NonTerminal("destructor_declaration"); var constant_declarator = new NonTerminal("constant_declarator"); var constant_declarators = new NonTerminal("constant_declarators"); var modifier = new NonTerminal("modifier"); var modifiers_opt = new NonTerminal("modifiers?"); var member_header = new NonTerminal("member_header"); var accessor_name = new NonTerminal("accessor_name"); var accessor_declaration = new NonTerminal("accessor_declaration"); var accessor_declarations = new NonTerminal("accessor_declarations"); var accessor_modifier_opt = new NonTerminal("accessor_modifier?"); var event_body = new NonTerminal("event_body"); var event_accessor_declarations = new NonTerminal("event_accessor_declarations"); var add_accessor_declaration = new NonTerminal("add_accessor_declaration"); var remove_accessor_declaration = new NonTerminal("remove_accessor_declaration"); var indexer_name = new NonTerminal("indexer_name"); var operator_declaration = new NonTerminal("operator_declaration"); var conversion_operator_declaration = new NonTerminal("conversion_operator_declaration"); var overloadable_operator = new NonTerminal("overloadable_operator"); var operator_parameter = new NonTerminal("operator_parameter"); var operator_parameters = new NonTerminal("operator_parameters"); var conversion_operator_kind = new NonTerminal("conversion_operator_kind"); var constructor_initializer_opt = new NonTerminal("constructor_initializer?"); var constructor_base = new NonTerminal("constructor_base"); var variable_declarator = new NonTerminal("variable_declarator"); var variable_declarators = new NonTerminal("variable_declarators"); var method_body = new NonTerminal("method_body"); var formal_parameter_list = new NonTerminal("formal_parameter_list"); var formal_parameter_list_par = new NonTerminal("formal_parameter_list_par"); var fixed_parameter = new NonTerminal("fixed_parameter"); var fixed_parameters = new NonTerminal("fixed_parameters"); var parameter_modifier_opt = new NonTerminal("parameter_modifier?"); var parameter_array = new NonTerminal("parameter_array"); var rank_specifier = new NonTerminal("rank_specifier"); var rank_specifiers = new NonTerminal("rank_specifiers"); var rank_specifiers_opt = new NonTerminal("rank_specifiers?"); var dim_specifier = new NonTerminal("dim_specifier"); var dim_specifier_opt = new NonTerminal("dim_specifier?"); var list_initializer = new NonTerminal("array_initializer"); var list_initializer_opt = new NonTerminal("array_initializer?"); var attribute_section = new NonTerminal("attribute_section"); var attributes_opt = new NonTerminal("attributes?"); var attribute_target_specifier_opt = new NonTerminal("attribute_target_specifier?"); var attribute_target = new NonTerminal("attribute_target"); var attribute = new NonTerminal("attribute"); var attribute_list = new NonTerminal("attribute_list"); var attribute_arguments_opt = new NonTerminal("attribute_arguments"); var named_argument = new NonTerminal("named_argument"); var attr_arg = new NonTerminal("attr_arg"); var attribute_arguments_par_opt = new NonTerminal("attribute_arguments_par?"); #endregion #region operators, punctuation and delimiters RegisterOperators(1, "||"); RegisterOperators(2, "&&"); RegisterOperators(3, "|"); RegisterOperators(4, "^"); RegisterOperators(5, "&"); RegisterOperators(6, "==", "!="); RegisterOperators(7, "<", ">", "<=", ">=", "is", "as"); RegisterOperators(8, "<<", ">>"); RegisterOperators(9, "+", "-"); RegisterOperators(10, "*", "/", "%"); RegisterOperators(11, "."); //RestrictPrecedence(bin_op, unary_operator); // RegisterOperators(12, "++", "--"); #region comments //The following makes sense, if you think about "?" in context of operator precedence. // What we say here is that "?" has the lowest priority among arithm operators. // Therefore, the parser should prefer reduce over shift when input symbol is "?". // For ex., when seeing ? in expression "a + b?...", the parser will perform Reduce: // (a + b)->expr // and not shift the "?" symbol. // Same goes for ?? symbol #endregion RegisterOperators(-3, "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="); RegisterOperators(-2, "?"); RegisterOperators(-1, "??"); this.Delimiters = "{}[](),:;+-*/%&|^!~<>="; this.MarkPunctuation(";", ",", "(", ")", "{", "}", "[", "]", ":"); this.MarkTransient(namespace_member_declaration, member_declaration, type_declaration, statement, embedded_statement, expression); //Whitespace and NewLine characters //TODO: // 1. In addition to "normal" whitespace chars, the spec mentions "any char of unicode class Z" - // need to create special comment-based terminal that simply eats these category-based whitechars and produces comment token. // 2. Add support for multiple line terminators to LineComment this.LineTerminators = "\r\n\u2085\u2028\u2029"; //CR, linefeed, nextLine, LineSeparator, paragraphSeparator this.WhitespaceChars = " \t\r\n\v\u2085\u2028\u2029"; //add extra line terminators #endregion #region "<" conflict resolution var lt = new NonTerminal("_<_"); lt.Rule = ResolveInCode() + "<"; #endregion /* #region Keywords string strKeywords = "abstract as base bool break byte case catch char checked " + "class const continue decimal default delegate do double else enum event explicit extern false finally " + "fixed float for foreach goto if implicit in int interface internal is lock long namespace " + "new null object operator out override params private protected public " + "readonly ref return sbyte sealed short sizeof stackalloc static string " + "struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual void " + "volatile while"; AddKeywordList(strKeywords); #endregion */ // RULES //B.2.1. Basic concepts //qual_name_with_targs is an alias for namespace-name, namespace-or-type-name, type-name, generic_dimension_specifier.Rule = lt + commas_opt + ">"; identifier_ext.Rule = identifier_or_builtin | "this" | "base"; generic_dimension_specifier.Rule = lt + commas_opt + ">"; builtin_type.Rule = integral_type | "bool" | "decimal" | "float" | "double" | "string" | "object" ; qual_name_segments_opt.Rule = MakeStarRule(qual_name_segments_opt, null, qual_name_segment); qual_name_segment.Rule = dot + identifier | "::" + identifier | type_argument_list; qual_name_with_targs.Rule = identifier_or_builtin + qual_name_segments_opt | xlang_type_choice ; identifier_or_builtin.Rule = identifier | builtin_type ; type_argument_list.Rule = lt + type_ref_list + ">"; type_argument_list_opt.Rule = Empty | type_argument_list; //B.2.2. Types type_or_void.Rule = qual_name_with_targs | "void"; type_ref.Rule = type_or_void + qmark_opt + rank_specifiers_opt + generic_dimension_specifier_opt; type_ref_list.Rule = MakePlusRule(type_ref_list, comma, type_ref); var comma_list_opt = new NonTerminal("comma_list?"); comma_list_opt.Rule = MakeStarRule(comma_list_opt, comma); rank_specifier.Rule = "[" + comma_list_opt + "]"; rank_specifiers.Rule = MakePlusRule(rank_specifiers, null, rank_specifier); rank_specifiers_opt.Rule = rank_specifiers.Q(); integral_type.Rule = ToTerm("sbyte") | "byte" | "short" | "ushort" | "int" | "uint" | "long" | "ulong" | "char"; //B.2.4. Variables //Quite strange in specs - // variable-reference: // expression // Is that case it would be possible to do the following: // GetMyStuff(out (a+b)); // but MS c# rejects it //B.2.4. Expressions argument.Rule = expression | "ref" + identifier | "out" + identifier; argument_list.Rule = MakePlusRule(argument_list, comma, argument); argument_list_opt.Rule = Empty | argument_list; expression.Rule = conditional_expression | bin_op_expression | typecast_expression | primary_expression; expression_opt.Rule = Empty | expression; expression_list.Rule = MakePlusRule(expression_list, comma, expression); unary_operator.Rule = ToTerm("+") | "-" | "!" | "~" | "*"; assignment_operator.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>="; conditional_expression.Rule = expression + PreferShiftHere() + qmark + expression + colon + expression;// + ReduceThis(); bin_op_expression.Rule = expression + bin_op + expression; typecast_expression.Rule = parenthesized_expression + primary_expression; primary_expression.Rule = literal | unary_operator + primary_expression | parenthesized_expression | member_access| pre_incr_decr_expression | post_incr_decr_expression | object_creation_expression | anonymous_object_creation_expression | typeof_expression | checked_expression | unchecked_expression | default_value_expression | anonymous_method_expression | xlang_exists_expression_choice | xlang_intrinsic_expression | xlang_xpath_expression_choice; xlang_property_reference.Rule = member_access; var xlang_property_reference_choice = new NonTerminal("xlang_property_reference_choice"); var xlang_message_property_reference = new NonTerminal("xlang_message_property_reference"); var xlang_message_part_property_reference = new NonTerminal("xlang_message_part_property_reference"); var xlang_correlation_property_reference = new NonTerminal("xlang_correlation_property_reference"); var xlang_service_link_property_reference = new NonTerminal("xlang_service_link_property_reference"); var xlang_port_property_reference = new NonTerminal("xlang_port_property_reference"); var xlang_service_property_reference = new NonTerminal("xlang_service_property_reference"); xlang_message_reference.Rule = xlang_message_identifier; xlang_message_part_reference.Rule = xlang_message_reference + dot + xlang_messagepart_identifier; xlang_message_or_message_part_reference_choice.Rule = xlang_message_part_reference | xlang_message_reference; xlang_exists_expression_short.Rule = xlang_property_reference + "exists"; xlang_exists_expression_message_reference.Rule = xlang_property_reference + "exists" + xlang_message_reference; xlang_exists_expression_message_part_reference.Rule = xlang_property_reference + "exists" + xlang_message_part_reference; xlang_exists_expression_choice.Rule = xlang_exists_expression_short | xlang_exists_expression_message_part_reference | xlang_exists_expression_message_reference; xlang_xpath_expression_short.Rule = "xpath" + lpar + literal + rpar; xlang_xpath_expression_long.Rule = "xpath" + lpar + xlang_message_or_message_part_reference_choice + comma + literal + rpar; xlang_xpath_expression_choice.Rule = xlang_xpath_expression_short | xlang_xpath_expression_long; xlang_intrinsic_expression.Rule = "succeeded" + lpar + xlang_transaction_identifier + rpar; dim_specifier.Rule = "[" + expression_list + "]"; dim_specifier_opt.Rule = dim_specifier.Q(); literal.Rule = Number | StringLiteral | CharLiteral | "true" | "false" | "null"; parenthesized_expression.Rule = lpar + expression + rpar; pre_incr_decr_expression.Rule = incr_or_decr + member_access; post_incr_decr_expression.Rule = member_access + incr_or_decr; //joined invocation_expr and member_access; for member access left the most general variant member_access.Rule = identifier_ext + member_access_segments_opt; member_access_segments_opt.Rule = MakeStarRule(member_access_segments_opt, null, member_access_segment); member_access_segment.Rule = dot + identifier | array_indexer | argument_list_par | type_argument_list; array_indexer.Rule = "[" + expression_list + "]"; argument_list_par.Rule = lpar + argument_list_opt + rpar; argument_list_par_opt.Rule = Empty | argument_list_par; list_initializer.Rule = lbr + elem_initializer_list_ext + rbr; list_initializer_opt.Rule = list_initializer.Q(); elem_initializer.Rule = initializer_value | identifier + "=" + initializer_value; elem_initializer_list.Rule = MakePlusRule(elem_initializer_list, comma, elem_initializer); elem_initializer_list_ext.Rule = Empty | elem_initializer_list + comma_opt; initializer_value.Rule = expression | list_initializer; //delegate, anon-object, object object_creation_expression.Rule = "new" + qual_name_with_targs + qmark_opt + creation_args + list_initializer_opt; creation_args.Rule = dim_specifier | rank_specifier | argument_list_par; anonymous_object_creation_expression.Rule = "new" + anonymous_object_initializer; anonymous_object_initializer.Rule = lbr + rbr | lbr + member_declarator_list + comma_opt + rbr; member_declarator.Rule = expression | identifier + "=" + expression; member_declarator_list.Rule = MakePlusRule(member_declarator_list, comma, member_declarator); //typeof typeof_expression.Rule = "typeof" + lpar + type_ref + rpar; generic_dimension_specifier_opt.Rule = Empty | lt + commas_opt + ">"; //checked, unchecked checked_expression.Rule = "checked" + parenthesized_expression; unchecked_expression.Rule = "unchecked" + parenthesized_expression; //default-value default_value_expression.Rule = "default" + lpar + type_ref + rpar; //note: we treat ?? as bin-operation, so null-coalesce-expr used in spec as first (condition) component is replaced with expression // we resolve all this expr hierarchies of binary expressions using precedence //anonymous method and lambda - we join explicit and implicit param definitions, making 'type' element optional // TODO: add after-parse check for this anonymous_method_expression.Rule = "delegate" + anonymous_function_signature_opt + block; lambda_expression.Rule = lambda_function_signature + "=>" + anonymous_function_body; lambda_function_signature.Rule = anonymous_function_signature | identifier; anonymous_function_signature.Rule = lpar + anonymous_function_parameter_list_opt + rpar; anonymous_function_signature_opt.Rule = anonymous_function_signature.Q(); anonymous_function_parameter_modifier_opt.Rule = Empty | "ref" | "out"; anonymous_function_parameter.Rule = anonymous_function_parameter_modifier_opt + anonymous_function_parameter_decl; anonymous_function_parameter_decl.Rule = identifier | type_ref + identifier; anonymous_function_parameter_list_opt.Rule = MakeStarRule(anonymous_function_parameter_list_opt, comma, anonymous_function_parameter_decl); anonymous_function_body.Rule = expression | block; //we don't use grammar expressions to specify operator precedence, so we combine all these grammar elements together // and define just bin_op_expression. Where to put it? // In spec: non_assignment_expression.Rule = conditional_expression | lambda_expression | query_expression; //I think it's a mistake; there must be additional entry here for arithm expressions, so we put them here. // We also have to add "is" and "as" expressions here, as we don't build entire hierarchy of elements for expressing // precedence (where they appear in original spec); so we put them here bin_op.Rule = lt | "||" | "&&" | "|" | "^" | "&" | "==" | "!=" | ">" | "<=" | ">=" | "<<" | ">>" | "+" | "-" | "*" | "/" | "%" | "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "is" | "as" | "??" ; //type_check_expression.Rule = expression + "is" + type_ref | expression + "as" + type_ref; //Queries query_expression.Rule = "from"; //B.2.5. Statements statement.Rule = labeled_statement | declaration_statement | embedded_statement; statement.ErrorRule = SyntaxError + semi; //skip all until semicolon var statement_attributes_opt = new NonTerminal("statement_attributes?"); statement_attributes_opt.Rule = attributes_opt + statement; statement_list.Rule = MakePlusRule(statement_list, null, statement_attributes_opt); statement_list_opt.Rule = Empty | statement_list; //labeled_statement labeled_statement.Rule = identifier + colon + embedded_statement; //declaration_statement declaration_statement.Rule = local_variable_declaration + semi | local_constant_declaration + semi; local_variable_declaration.Rule = local_variable_type + local_variable_declarators; //!!! local_variable_type.Rule = "var" | member_access | xlang_type_choice; //to fix the conflict, changing to member-access here local_variable_declarator.Rule = identifier | identifier + "=" + initializer_value; local_variable_declarators.Rule = MakePlusRule(local_variable_declarators, comma, local_variable_declarator); local_constant_declaration.Rule = "const" + type_ref + constant_declarators; //embedded_statement embedded_statement.Rule = block | semi /*empty_statement*/ | statement_expression + semi | selection_statement | iteration_statement | jump_statement | try_statement | checked_statement | unchecked_statement | lock_statement | using_statement | yield_statement | xlang_statement_choice; embedded_statement_attributes_opt.Rule = attributes_opt + embedded_statement; block.Rule = lbr + statement_list_opt + rbr; //selection (if and switch) selection_statement.Rule = if_statement | switch_statement; if_statement.Rule = ToTerm("if") + lpar + expression + rpar + embedded_statement_attributes_opt + else_clause_opt; else_clause_opt.Rule = Empty | PreferShiftHere() + "else" + embedded_statement_attributes_opt; switch_statement.Rule = "switch" + parenthesized_expression + lbr + switch_sections_opt + rbr; switch_section.Rule = switch_labels + statement_list; switch_sections_opt.Rule = MakeStarRule(switch_sections_opt, null, switch_section); switch_label.Rule = "case" + expression + colon | "default" + colon; switch_labels.Rule = MakePlusRule(switch_labels, null, switch_label); //iteration statements iteration_statement.Rule = while_statement | do_statement | for_statement | foreach_statement; while_statement.Rule = "while" + parenthesized_expression + embedded_statement_attributes_opt; do_statement.Rule = "do" + embedded_statement_attributes_opt + "while" + parenthesized_expression + semi; for_statement.Rule = "for" + lpar + for_initializer_opt + semi + for_condition_opt + semi + for_iterator_opt + rpar + embedded_statement_attributes_opt; for_initializer_opt.Rule = Empty | local_variable_declaration | statement_expression_list; for_condition_opt.Rule = Empty | expression; for_iterator_opt.Rule = Empty | statement_expression_list; foreach_statement.Rule = "foreach" + lpar + local_variable_type + identifier + "in" + expression + rpar + embedded_statement_attributes_opt; //jump-statement jump_statement.Rule = break_statement | continue_statement | goto_statement | return_statement | throw_statement; break_statement.Rule = "break" + semi; continue_statement.Rule = "continue" + semi; goto_statement.Rule = tgoto + identifier + semi | tgoto + "case" + expression + semi | tgoto + "default" + semi; return_statement.Rule = "return" + expression_opt + semi; throw_statement.Rule = "throw" + expression_opt + semi; //try-statement //changed to avoid conflicts; need to check correct ordering of catch/finally clause in after-parse validation try_statement.Rule = "try" + block + try_clauses; try_clause.Rule = catch_clause | finally_clause; try_clauses.Rule = MakePlusRule(try_clauses, null, try_clause); catch_clause.Rule = "catch" + catch_specifier_opt + block; finally_clause.Rule = "finally" + block; catch_specifier_opt.Rule = Empty | lpar + qual_name_with_targs + identifier_opt + rpar; identifier_opt.Rule = Empty | identifier; //checked, unchecked, locked, using checked_statement.Rule = "checked" + block; unchecked_statement.Rule = "unchecked" + block; lock_statement.Rule = "lock" + parenthesized_expression + embedded_statement_attributes_opt; using_statement.Rule = "using" + lpar + resource_acquisition + rpar + embedded_statement_attributes_opt; resource_acquisition.Rule = local_variable_declaration | expression; //yield statement yield_statement.Rule = yld + "return" + expression + semi | yld + "break" + semi; //expression statement // expression_statement.Rule = statement_expression + semi; statement_expression.Rule = object_creation_expression | member_access | member_access + assignment_operator + expression | pre_incr_decr_expression | post_incr_decr_expression ; statement_expression_list.Rule = MakePlusRule(statement_expression_list, comma, statement_expression); incr_or_decr_opt.Rule = Empty | ToTerm("++") | "--"; incr_or_decr.Rule = ToTerm("++") | "--"; type_parameter.Rule = attributes_opt + identifier; type_parameters.Rule = MakePlusRule(type_parameters, comma, type_parameter); type_parameter_list_opt.Rule = Empty | lt + type_parameters + ">"; type_parameter_constraints_clause.Rule = "where" + type_parameter + colon + type_parameter_constraints; type_parameter_constraints.Rule = MakePlusRule(type_parameter_constraints, comma, type_parameter_constraint); type_parameter_constraints_clauses_opt.Rule = MakeStarRule(type_parameter_constraints_clauses_opt, null, type_parameter_constraints_clause); //Note for post-processing - make sure the order is correct: new() is always last, etc. See p.503 of the spec type_parameter_constraint.Rule = qual_name_with_targs | "class" | "struct" | ToTerm("new") + lpar + rpar; ////Class members ////Note: we split operator-declaration into two separate operator elements: bin/unary and conversion operators //// to avoid possible ambiguities and conflicts member_declaration.Rule = constant_declaration | field_declaration | method_declaration | property_declaration | event_declaration | indexer_declaration | operator_declaration | conversion_operator_declaration | constructor_declaration | destructor_declaration | type_declaration; member_declaration.ErrorRule = SyntaxError + ";" | SyntaxError + "}"; member_declarations_opt.Rule = MakeStarRule(member_declarations_opt, null, member_declaration); ////Modifiers - see note #1 in Notes.txt file modifier.Rule = ToTerm("new") | "public" | "protected" | "internal" | "private" | "static" | "virtual" | "sealed" | "override" | "abstract" | "readonly" | "volatile" | "partial" | "extern"; //!!! modifiers_opt.Rule = MakeStarRule(modifiers_opt, null, modifier); //Joined member header - see note #2 member_header.Rule = attributes_opt + modifiers_opt; constant_declaration.Rule = member_header + "const" + type_ref + constant_declarators + semi; constant_declarator.Rule = identifier + "=" + expression; constant_declarators.Rule = MakePlusRule(constant_declarators, comma, constant_declarator); field_declaration.Rule = member_header + type_ref + variable_declarators + semi; variable_declarator.Rule = identifier | identifier + "=" + elem_initializer; variable_declarators.Rule = MakePlusRule(variable_declarators, comma, variable_declarator); //See note #3 about merging type_parameter_list into type_arguments of the preceding qual_name. method_declaration.Rule = member_header + type_ref + qual_name_with_targs // + type_parameter_list.Q() + formal_parameter_list_par + type_parameter_constraints_clauses_opt + method_body; formal_parameter_list.Rule = fixed_parameters | fixed_parameters + comma + parameter_array | parameter_array; formal_parameter_list_par.Rule = lpar + rpar | lpar + formal_parameter_list + rpar; fixed_parameter.Rule = attributes_opt + parameter_modifier_opt + type_ref + identifier; fixed_parameters.Rule = MakePlusRule(fixed_parameters, comma, fixed_parameter); parameter_modifier_opt.Rule = Empty | "ref" | "out" | "this"; parameter_array.Rule = attributes_opt + "params" + type_ref + /*"[" + "]" + */ identifier; method_body.Rule = block | semi; // See note #4 about member-name //TODO: add after-parse validation that no more than one accessor of each type is there. property_declaration.Rule = member_header + type_ref + qual_name_with_targs/*member-name*/ + lbr + accessor_declarations + rbr; accessor_declaration.Rule = attributes_opt + accessor_modifier_opt + accessor_name + block; accessor_declarations.Rule = MakePlusRule(accessor_declarations, null, accessor_declaration); accessor_name.Rule = ToTerm("get") | "set"; accessor_modifier_opt.Rule = Empty | "protected" | "internal" | "private" | ToTerm("protected") + "internal" | ToTerm("internal") + "protected"; attributes_opt.Rule = MakeStarRule(attributes_opt, null, attribute_section); attribute_section.Rule = "[" + attribute_target_specifier_opt + attribute_list + comma_opt + "]"; attribute_list.Rule = MakePlusRule(attribute_list, comma, attribute); attribute.Rule = qual_name_with_targs + attribute_arguments_par_opt; attribute_target_specifier_opt.Rule = Empty | attribute_target + colon; attribute_target.Rule = ToTerm("field") | "event" | "method" | "param" | "property" | "return" | "type"; attribute_arguments_par_opt.Rule = Empty | lpar + attribute_arguments_opt + rpar; attribute_arguments_opt.Rule = MakeStarRule(attribute_arguments_opt, comma, attr_arg); attr_arg.Rule = identifier + "=" + expression | expression; #endregion //Prepare term set for conflict resolution _skipTokensInPreview.UnionWith(new Terminal[] { dot, identifier, comma, ToTerm("::"), comma, ToTerm("["), ToTerm("]") }); xlang_operators.Rule = ToTerm("exists"); RegisterOperators(7, "exists"); //attributes_opt clashes with the array indexer of member access //http://technet.microsoft.com/en-us/library/aa560334(BTS.70).aspx //support for array indexers removed from member access this.Root = xlang_orchestration; xlang_orchestration.Rule = xlang_module_att_opt; xlang_module.Rule = "module" + xlang_module_identifier + lbr + xlang_type_definitions + rbr; xlang_accesmodifier_choice.Rule = "public" | ToTerm("private") | "internal"; xlang_type_definition.Rule = xlang_accesmodifier_choice + xlang_type_definition_choice; xlang_type_definition_choice.Rule = xlang_messagetype_definition | xlang_porttype_definition | xlang_correlationtype_definition | xlang_servicelinktype_definition | xlang_servicetype_definition; xlang_messagetype_definition.Rule = "messagetype" + xlang_messagetype_identifier + lbr + xlang_message_parts + rbr + semi; xlang_messagepart_choice.Rule = xlang_body_part | xlang_nonbody_part; xlang_body_part.Rule = "body" + type_ref + identifier + semi; xlang_nonbody_part.Rule = type_ref + identifier + semi; xlang_porttype_definition.Rule = "porttype" + xlang_porttype_identifier + lbr + xlang_porttype_operations + rbr + semi; xlang_mep_choice.Rule = "oneway" | ToTerm("requestresponse") | "solicitresponse"; xlang_porttype_operation.Rule = xlang_mep_choice + xlang_operation_identifier + lbr + xlang_operation_messagetypes + rbr + semi; xlang_operation_messagetype.Rule = type_ref; xlang_operation_fault_messagetype.Rule = identifier + "=" + type_ref; xlang_operation_messagetype_choice.Rule = xlang_operation_messagetype | xlang_operation_fault_messagetype; xlang_correlationtype_definition.Rule = "correlationtype" + xlang_correlationtype_identifier + lbr + xlang_correlation_properties + rbr + semi; xlang_servicelinktype_definition.Rule = "servicelinktype" + xlang_servicelinktype_identifier + lbr + xlang_roletypes + rbr + semi; xlang_roletype.Rule = xlang_roletype_identifier + lbr + xlang_porttype_identifier + rbr + semi; xlang_longrunning_transaction.Rule = "longrunning" + ToTerm("transaction"); xlang_atomic_transaction.Rule = "atomic" + ToTerm("transaction"); xlang_transaction_type_choice.Rule = xlang_longrunning_transaction | xlang_atomic_transaction ; xlang_transaction_declaration.Rule = xlang_transaction_type_opt + xlang_transaction_identifier; xlang_servicetype_definition.Rule = "service" + xlang_transaction_declaration + lbr + xlang_scope_implementation + rbr; xlang_scope.Rule = "scope" + xlang_transaction_declaration_opt + lbr + xlang_scope_implementation + rbr; xlang_scope_statement_choice.Rule = declaration_statement | xlang_body | xlang_exceptions | xlang_compensation; xlang_scope_implementation.Rule = xlang_scope_statements; xlang_port_direction.Rule = "uses" | ToTerm("implements"); //composite types xlang_servicelinktype.Rule = "servicelink" + xlang_port_direction + identifier_or_builtin + qual_name_segments_opt; xlang_porttype.Rule = "port" + xlang_port_direction + identifier_or_builtin + qual_name_segments_opt; xlang_correlationtype.Rule = "correlation" + identifier_or_builtin + qual_name_segments_opt; xlang_messagetype.Rule = "message" + identifier_or_builtin + qual_name_segments_opt; xlang_type_choice.Rule = xlang_servicelinktype | xlang_porttype | xlang_correlationtype | xlang_messagetype; xlang_body.Rule = "body" + xlang_formal_parameters_par_opt + lbr + statement_list_opt + rbr; xlang_exceptions.Rule = "exceptions" + lbr + xlang_catch_clauses + rbr; xlang_compensation.Rule = "compensation" + lpar + rpar + lbr + statement_list_opt + rbr; xlang_parallel.Rule = "parallel" + xlang_formal_parameters_par_opt + lbr + xlang_tasks + rbr; xlang_task.Rule = "task" + xlang_formal_parameters_par_opt + lbr + statement_list_opt + rbr; xlang_construct.Rule = "construct" + xlang_message_identifiers + lbr + xlang_construct_statements + rbr; xlang_listen.Rule = "listen" + lbr + xlang_listen_branches + rbr; xlang_timeout_branch.Rule = "timeout" + xlang_timespan_returning_expression + lbr + statement_list + rbr; xlang_receive_branch.Rule = "until" + xlang_receive + lbr + statement_list + rbr; xlang_listen_choice.Rule = xlang_timeout_branch | xlang_receive_branch; xlang_statement_choice.Rule = xlang_scope | xlang_parallel | xlang_construct | xlang_listen | xlang_send_statement | xlang_receive_statement | xlang_call_statement | xlang_exec_statement | xlang_suspend_statement | xlang_terminate_statement | xlang_delay_statement; xlang_construct_choice.Rule = semi | statement_expression + semi | xlang_transform_statement | selection_statement; xlang_follow_correlation.Rule = member_access; xlang_initialize_correlation.Rule = "initialize" + member_access; xlang_correlation_arg_choice.Rule = xlang_initialize_correlation | xlang_follow_correlation; xlang_correlation_args.Rule = MakeStarRule(xlang_correlation_args, comma, xlang_correlation_arg_choice); xlang_correlation_args_opt.Rule = Empty | comma + xlang_correlation_args; xlang_send_arguments.Rule = lpar + member_access + comma + member_access + xlang_correlation_args_opt + rpar; xlang_receive_arguments.Rule = lpar + member_access + comma + member_access + xlang_correlation_args_opt + rpar; xlang_call_statement.Rule = "call" + member_access + identifier + semi; xlang_exec_statement.Rule = "exec" + member_access + semi; xlang_receive.Rule = xlang_activate_opt + "receive" + xlang_receive_arguments; xlang_receive_statement.Rule = xlang_receive + semi; xlang_send_statement.Rule = "send" + xlang_send_arguments + semi; xlang_suspend_statement.Rule = "suspend" + member_access + semi | "suspend" + StringLiteral + semi; xlang_terminate_statement.Rule = "terminate" + member_access + semi; xlang_transform_statement.Rule = "transform" + lpar + identifier + rpar + "=" + member_access + semi; xlang_delay.Rule = "delay" + xlang_timespan_returning_expression; xlang_delay_statement.Rule = xlang_delay + semi; xlang_module_identifier.Rule = MakePlusRule(xlang_module_identifier, dot, identifier); xlang_servicetype_definitions.Rule = MakePlusRule(xlang_servicetype_definitions, null, xlang_servicetype_definition); xlang_statement_list.Rule = MakeStarRule(xlang_statement_list, null, xlang_statement_att_opt); xlang_type_definitions.Rule = MakeStarRule(xlang_type_definitions, null, xlang_type_definition_att_opt); xlang_messagetypes.Rule = MakeStarRule(xlang_messagetypes, null, xlang_messagetype_definition); xlang_message_parts.Rule = MakePlusRule(xlang_message_parts, null, xlang_messagepart_choice); xlang_porttype_definitions.Rule = MakeStarRule(xlang_porttype_definitions, null, xlang_porttype_definition); xlang_porttype_operations.Rule = MakePlusRule(xlang_porttype_operations, null, xlang_porttype_operation); xlang_operation_messagetypes.Rule = MakeStarRule(xlang_operation_messagetypes, ToTerm(","), xlang_operation_messagetype_choice); xlang_correlation_properties.Rule = MakeStarRule(xlang_correlation_properties, comma, type_ref); xlang_correlationtypes.Rule = MakeStarRule(xlang_correlationtypes, null, xlang_correlationtype_definition); xlang_servicelinktypes.Rule = MakeStarRule(xlang_servicelinktypes, null, xlang_servicelinktype_definition); xlang_scope_statements.Rule = MakeStarRule(xlang_scope_statements, null, xlang_scope_statement_att_opt); xlang_listen_branches.Rule = MakePlusRule(xlang_listen_branches, null, xlang_listen_branch_att_opt); xlang_catch_clauses.Rule = MakePlusRule(xlang_catch_clauses, null, xlang_catch_clause_att_opt); xlang_tasks.Rule = MakePlusRule(xlang_tasks, null, xlang_task); xlang_message_identifiers.Rule = MakePlusRule(xlang_message_identifiers, comma, identifier); xlang_construct_statements.Rule = MakePlusRule(xlang_construct_statements, null, xlang_construct_choice_att_opt); xlang_roletypes.Rule = MakePlusRule(xlang_roletypes, null, xlang_roletype); xlang_module_att_opt.Rule = attributes_opt + xlang_module; xlang_catch_clause_att_opt.Rule = attributes_opt + catch_clause; xlang_construct_choice_att_opt.Rule = attributes_opt + xlang_construct_choice; xlang_listen_branch_att_opt.Rule = attributes_opt + xlang_listen_choice; xlang_type_definition_att_opt.Rule = attributes_opt + xlang_type_definition; xlang_scope_statement_att_opt.Rule = attributes_opt + xlang_scope_statement_choice; xlang_statement_att_opt.Rule = attributes_opt + xlang_statement_choice; xlang_transaction_declaration_opt.Rule = Empty | xlang_transaction_declaration; xlang_transaction_type_opt.Rule = Empty | xlang_transaction_type_choice; xlang_scope_statements_opt.Rule = Empty | xlang_scope_statements; xlang_compensation_opt.Rule = Empty | xlang_compensation; xlang_exceptions_opt.Rule = Empty | xlang_exceptions; xlang_formal_parameters_par_opt.Rule = Empty | formal_parameter_list_par; xlang_activate_opt.Rule = Empty | "activate"; xlang_limited_object_creation_expression.Rule = "new" + qual_name_with_targs + qmark_opt + creation_args; //removed array inits xlang_timespan_returning_expression.Rule = xlang_limited_object_creation_expression | member_access; this.MarkTransient(xlang_statement_att_opt); this.MarkTransient(xlang_transaction_declaration_opt); this.MarkTransient(xlang_transaction_type_opt); this.MarkTransient(xlang_scope_statements_opt); this.MarkTransient(xlang_compensation_opt); this.MarkTransient(xlang_exceptions_opt); this.MarkTransient(xlang_formal_parameters_par_opt); this.MarkTransient(xlang_accesmodifier_choice); this.MarkTransient(xlang_mep_choice); this.MarkTransient(xlang_port_direction); this.MarkTransient(xlang_messagepart_choice); this.MarkTransient(xlang_construct_choice); this.MarkTransient(xlang_statement_choice); this.MarkTransient(xlang_type_definition_choice); this.MarkTransient(xlang_operation_messagetype_choice); this.MarkTransient(xlang_type_choice); this.MarkTransient(xlang_listen_choice); this.MarkTransient(xlang_transaction_type_choice); }
public Grammar() { #region 1. Terminals NumberLiteral n = TerminalFactory.CreateCSharpNumber("number"); StringLiteral stringLiteral = TerminalFactory.CreateCSharpString("String"); IdentifierTerminal ident = new IdentifierTerminal("Identifier"); this.MarkReservedWords( "assert", "assume", "axiom", "bool", "break", "bv0", "bv1", "bv2", "bv3", "bv4", "bv5", "bv6", "bv7", "bv8", "bv9", "bv10", "bv11", "bv12", "bv13", "bv14", "bv15", "bv16", "bv17", "bv18", "bv19", "bv20", "bv21", "bv22", "bv23", "bv24", "bv25", "bv26", "bv27", "bv28", "bv29", "bv30", "bv31", "bv32", "bv64", "call", "complete", "const", "div", "else", "ensures", "exists", "extends", "false", "forall", "free", "function", "goto", "havoc", "if", "implementation", "int", "invariant", "lambda", "mod", "modifies", "old", "procedure", "real", "requires", "return", "returns", "then", "true", "type", "unique", "var", "where", "while" ); StringLiteral s = new StringLiteral("String", "'", StringFlags.AllowsDoubledQuote); Terminal dot = ToTerm(".", "dot"); Terminal less = ToTerm("<"); Terminal greater = ToTerm(">"); Terminal iff = ToTerm("<==>"); Terminal implication = ToTerm("==>"); Terminal explication = ToTerm("<=="); Terminal LBracket = ToTerm("["); Terminal RBracket = ToTerm("]"); Terminal LParen = ToTerm("("); Terminal RParen = ToTerm(")"); Terminal RCurly = ToTerm("}"); Terminal LCurly = ToTerm("{"); Terminal LDoubleCurly = ToTerm("{{"); Terminal RDoubleCurly = ToTerm("}}"); Terminal comma = ToTerm(","); Terminal semicolon = ToTerm(";"); Terminal colon = ToTerm(":"); Terminal doubleColon = ToTerm("::"); #endregion #region 2. Non-terminals #region 2.1 Expressions NonTerminal expression = new NonTerminal("Expr"); NonTerminal BinOp = new NonTerminal("BinOp"); NonTerminal LUnOp = new NonTerminal("LUnOp"); NonTerminal RUnOp = new NonTerminal("RUnOp"); NonTerminal ArrayConstructor = new NonTerminal("ArrayConstructor"); #endregion #region 2.2 QualifiedName //Expression List: expr1, expr2, expr3, .. NonTerminal expressionList = new NonTerminal("ExprList"); NonTerminal identList = new NonTerminal("identList"); //A name in form: a.b.c().d[1,2].e .... NonTerminal NewStmt = new NonTerminal("NewStmt"); NonTerminal NewArrStmt = new NonTerminal("NewArrStmt"); NonTerminal QualifiedName = new NonTerminal("QualifiedName"); NonTerminal GenericsPostfix = new NonTerminal("GenericsPostfix"); NonTerminal ArrayExpression = new NonTerminal("ArrayExpression"); NonTerminal FunctionExpression = new NonTerminal("FunctionExpression"); NonTerminal selectExpr = new NonTerminal("selectExpr"); #endregion #region 2.3 Statement NonTerminal Condition = new NonTerminal("Condition"); NonTerminal Statement = new NonTerminal("Statement"); NonTerminal Statements = new NonTerminal("Statements"); //Block NonTerminal blockStatement = new NonTerminal("CompoundStatement"); #endregion #region 2.4 Program and Functions NonTerminal Prog = new NonTerminal("Prog"); NonTerminal anything = new NonTerminal("anything"); // temporary hack NonTerminal declaration = new NonTerminal("declaration"); NonTerminal classDecl = new NonTerminal("class decl"); NonTerminal memberDecl = new NonTerminal("member decl"); NonTerminal fieldDecl = new NonTerminal("field declaration"); NonTerminal idType = new NonTerminal("identifier type"); NonTerminal typeDecl = new NonTerminal("type reference"); NonTerminal methodDecl = new NonTerminal("method declaration"); NonTerminal formalParameters = new NonTerminal("formals"); NonTerminal methodSpec = new NonTerminal("method spec"); NonTerminal formalsList = new NonTerminal("ParamaterListOpt"); NonTerminal functionDecl = new NonTerminal("function declaration"); NonTerminal predicateDecl = new NonTerminal("predicate declaration"); NonTerminal invariantDecl = new NonTerminal("invariant declaration"); NonTerminal Semi = new NonTerminal("semi"); NonTerminal Rhs = new NonTerminal("right-hand side"); NonTerminal FieldInit = new NonTerminal("field init"); NonTerminal FieldInits = new NonTerminal("field inits"); NonTerminal installBounds = new NonTerminal("installBounds"); NonTerminal localVarStmt = new NonTerminal("localVarStmt"); NonTerminal evalstate = new NonTerminal("evalstate"); NonTerminal channelDecl = new NonTerminal("channel declaration"); NonTerminal loopSpec = new NonTerminal("loop specification"); NonTerminal rdPermArg = new NonTerminal("rdPermArg"); #endregion #endregion #region 3. BNF rules Semi.Rule = semicolon; #region 3.1 Expressions selectExpr.Rule = (ToTerm("this") + ".").Q() + QualifiedName; evalstate.Rule = ident + ToTerm(".") + (ToTerm("acquire") | "release" | "fork" + FunctionExpression ) ; rdPermArg.Rule = ToTerm("*") | expression; expression.Rule = ToTerm("true") | "false" | "null" | "maxlock" | "lockbottom" | "this" | "result" | s | n | QualifiedName // The following is needed: to parse "A<B ..." either as comparison or as beginning of GenericsPostfix | QualifiedName + less + expression //| QualifiedName + less + QualifiedName + greater //| NewStmt | NewArrStmt | ArrayExpression | FunctionExpression | ArrayConstructor | expression + BinOp + expression | LUnOp + expression | expression + RUnOp | LParen + expression + RParen | ToTerm("unfolding") + expression + "in" + expression | ToTerm("acc") + "(" + selectExpr + (("," + expression) | Empty) + ")" | ToTerm("old") + "(" + expression + ")" | ToTerm("eval") + "(" + evalstate + "," + expression + ")" | ToTerm("credit") + "(" + expression + "," + expression + ")" | ToTerm("credit") + "(" + expression + ")" | expression + PreferShiftHere() + "?" + expression + ":" + expression | ToTerm("rd") + (ToTerm("holds") + "(" + expression + ")" | "(" + selectExpr + rdPermArg.Q() + ")" ) ; expressionList.Rule = MakePlusRule(expressionList, comma, expression); identList.Rule = MakePlusRule(identList, comma, ident); NewStmt.Rule = "new" + QualifiedName + GenericsPostfix.Q() + LParen + expressionList.Q() + RParen; NewArrStmt.Rule = "new" + QualifiedName + GenericsPostfix.Q() + LBracket + expressionList.Q() + RBracket; BinOp.Rule = ToTerm("+") | "-" | "*" | "div" | "mod" | "^" | "&" | "|" | "&&" | "||" | "==" | "!=" | greater | less | ">=" | "<=" | "is" | "=" | "+=" | "-=" | "." | "==>" | "<==>" | "<<" ; LUnOp.Rule = ToTerm("-") | "~" | "!"; RUnOp.Rule = ToTerm("++") | "--"; ArrayConstructor.Rule = LBracket + expressionList + RBracket; #endregion #region 3.2 QualifiedName ArrayExpression.Rule = QualifiedName + LBracket + expressionList + RBracket; FunctionExpression.Rule = QualifiedName + LParen + expressionList.Q() + RParen; QualifiedName.Rule = ident | QualifiedName + dot + ident; GenericsPostfix.Rule = less + QualifiedName + greater; //ExprList.Rule = Expr.Plus(comma); #endregion #region 3.3 Statement Condition.Rule = LParen + expression + RParen; installBounds.Rule = "installBounds" //= ToTerm("between") + expressionList + "and" + expressionList //| "below" + expressionList //| "below" + expressionList + "above" + expressionList //| "above" + expressionList //| "above" + expressionList + "below" + expressionList ; FieldInit.Rule = ident + ":=" + expression ; FieldInits.Rule = MakeStarRule(FieldInits, ToTerm(","), FieldInit); Rhs.Rule = ToTerm("new") + ident | ToTerm("new") + ident + "{" + FieldInits + "}" | ToTerm("new") + ident + installBounds | ToTerm("new") + ident + "{" + FieldInits + "}" + installBounds | expression ; localVarStmt.Rule = idType + ":=" + Rhs + Semi | idType + Semi ; loopSpec.Rule = ToTerm("invariant") + expression + Semi | "lockchange" + expressionList + Semi ; Statement.Rule = Semi | "if" + Condition + Statement ; Statements.Rule = MakeStarRule(Statements, null, Statement); blockStatement.Rule = LCurly + Statements + RCurly; #endregion #region 3.4 Prog Prog.Rule = anything.Star() + Eof; anything.Rule = ToTerm("assert") | "assume" | "axiom" | "bool" | "break" | "bv0" | "bv1" | "bv2" | "bv3" | "bv4" | "bv5" | "bv6" | "bv7" | "bv8" | "bv9" | "bv10" | "bv11" | "bv12" | "bv13" | "bv14" | "bv15" | "bv16" | "bv17" | "bv18" | "bv19" | "bv20" | "bv21" | "bv22" | "bv23" | "bv24" | "bv25" | "bv26" | "bv27" | "bv28" | "bv29" | "bv30" | "bv31" | "bv32" | "bv64" | "call" | "complete" | "const" | "else" | "ensures" | "exists" | "extends" | "false" | "forall" | "free" | "function" | "goto" | "havoc" | "if" | "implementation" | "int" | "invariant" | "lambda" | "modifies" | "old" | "procedure" | "real" | "requires" | "return" | "returns" | "then" | "true" | "type" | "unique" | "var" | "where" | "while" | ident | "}" | "{" | "(" | ")" | "[" | "]" | "," | ":" | ";" | "." | "`" | "==" | "=" | "!=" | "<" | "<=" | ">=" | ">" | "=>" | ":=" | "+" | "-" | "*" | "/" | "%" | "!!" | "|" | "!" | "&&" | "||" | "==>" | "<==>" | "#" | "$" | "^" | n | stringLiteral ; idType.Rule = ident + ":" + typeDecl | ident ; typeDecl.Rule = (ToTerm("int") | "bool" | "real" | ident) ; fieldDecl.Rule = ToTerm("var") + idType + Semi | ToTerm("ghost") + "var" + idType + Semi ; methodSpec.Rule = (ToTerm("requires") | "ensures" | "lockchange") + expression + Semi; formalsList.Rule = MakeStarRule(formalsList, comma, idType); formalParameters.Rule = LParen + formalsList + RParen; methodDecl.Rule = "method" + ident + formalParameters + (("returns" + formalParameters) | Empty) + methodSpec.Star() + blockStatement; functionDecl.Rule = ToTerm("function") + ident + formalParameters + ":" + typeDecl + methodSpec.Star() + "{" + expression + "}"; predicateDecl.Rule = ToTerm("predicate") + ident + "{" + expression + "}"; invariantDecl.Rule = ToTerm("invariant") + expression + Semi; memberDecl.Rule = fieldDecl | invariantDecl | methodDecl //| conditionDecl | predicateDecl | functionDecl ; classDecl.Rule = (ToTerm("external") | Empty) + "class" + ident + ("module" + ident | Empty) + "{" + memberDecl.Star() + "}"; channelDecl.Rule = ToTerm("channel") + ident + formalParameters + "where" + expression + Semi | ToTerm("channel") + ident + formalParameters + Semi; declaration.Rule = classDecl | channelDecl ; Terminal Comment = new CommentTerminal("Comment", "/*", "*/"); NonGrammarTerminals.Add(Comment); Terminal LineComment = new CommentTerminal("LineComment", "//", "\n"); NonGrammarTerminals.Add(LineComment); #endregion #endregion #region 4. Set starting symbol this.Root = Prog; // Set grammar root #endregion #region 5. Operators precedence RegisterOperators(1, "<==>"); RegisterOperators(2, "+", "-"); RegisterOperators(3, "*", "div", "mod", "!!"); RegisterOperators(4, Associativity.Right, "^"); RegisterOperators(5, "||"); RegisterOperators(6, "&&"); RegisterOperators(7, "==", "=", "!=", ">", "<", ">=", "<="); RegisterOperators(8, "in"); RegisterOperators(9, "-", "!", "++", "--"); RegisterOperators(10, "==>"); RegisterOperators(11, "."); //RegisterOperators(10, Associativity.Right, ".",",", ")", "(", "]", "[", "{", "}"); //RegisterOperators(11, Associativity.Right, "else"); #endregion #region 6. Punctuation symbols RegisterPunctuation("(", ")", "[", "]", "{", "}", ",", ";"); #endregion }