protected override void DoAction(int action) { #pragma warning disable 162, 1522 switch (action) { case 2: // lp_description -> structure, PROC, options_section { ConstructedGrammar.PostProcessing(); Log.AddRange(ConstructedGrammar.CheckValidity()); } break; case 8: // terminal -> ENTITY_NAME, COLON, opt_linestart, REGEX { SafeGrammarAction(() => { ConstructedGrammar.DeclareTerminal(ValueStack[ValueStack.Depth - 4].strVal, ValueStack[ValueStack.Depth - 1].strVal, ValueStack[ValueStack.Depth - 2].boolVal); ConstructedGrammar.AddLocation(ValueStack[ValueStack.Depth - 4].strVal, LocationStack[LocationStack.Depth - 4].Start); }, LocationStack[LocationStack.Depth - 4].Start); } break; case 9: // opt_linestart -> LINESTART { CurrentSemanticValue.boolVal = true; } break; case 10: // opt_linestart -> /* empty */ { CurrentSemanticValue.boolVal = false; } break; case 11: // pair -> ENTITY_NAME, COLON, LEFT, pair_border, RIGHT, pair_border { SafeGrammarAction(() => { ConstructedGrammar.DeclarePair(ValueStack[ValueStack.Depth - 6].strVal, ValueStack[ValueStack.Depth - 3].strSet, ValueStack[ValueStack.Depth - 1].strSet); ConstructedGrammar.AddLocation(ValueStack[ValueStack.Depth - 6].strVal, LocationStack[LocationStack.Depth - 6].Start); }, LocationStack[LocationStack.Depth - 6].Start); } break; case 12: // pair_border -> ID { CurrentSemanticValue.strSet = new HashSet <string>() { ValueStack[ValueStack.Depth - 1].strVal }; } break; case 13: // pair_border -> REGEX { var generated = ConstructedGrammar.GenerateTerminal(ValueStack[ValueStack.Depth - 1].strVal); ConstructedGrammar.AddLocation(generated, LocationStack[LocationStack.Depth - 1].Start); CurrentSemanticValue.strSet = new HashSet <string>() { generated }; } break; case 14: // pair_border -> LROUND_BRACKET, pair_border_group_content, RROUND_BRACKET { CurrentSemanticValue.strSet = ValueStack[ValueStack.Depth - 2].strSet; } break; case 15: // pair_border_group_content -> pair_border { CurrentSemanticValue.strSet = ValueStack[ValueStack.Depth - 1].strSet; } break; case 16: // pair_border_group_content -> pair_border_group_content, OR, pair_border { ValueStack[ValueStack.Depth - 3].strSet.UnionWith(ValueStack[ValueStack.Depth - 1].strSet); CurrentSemanticValue.strSet = ValueStack[ValueStack.Depth - 3].strSet; } break; case 17: // nonterminal -> ENTITY_NAME, EQUALS, body { var aliases = this.Aliases; this.Aliases = new HashSet <string>(); SafeGrammarAction(() => { ConstructedGrammar.DeclareNonterminal(ValueStack[ValueStack.Depth - 3].strVal, ValueStack[ValueStack.Depth - 1].altList); ConstructedGrammar.AddLocation(ValueStack[ValueStack.Depth - 3].strVal, LocationStack[LocationStack.Depth - 3].Start); if (aliases.Count > 0) { ConstructedGrammar.AddAliases(ValueStack[ValueStack.Depth - 3].strVal, aliases); } }, LocationStack[LocationStack.Depth - 3].Start); } break; case 18: // body -> body, OR, alternative, optional_alias { CurrentSemanticValue.altList = ValueStack[ValueStack.Depth - 4].altList; ValueStack[ValueStack.Depth - 2].altVal.Alias = ValueStack[ValueStack.Depth - 1].strVal; CurrentSemanticValue.altList.Add(ValueStack[ValueStack.Depth - 2].altVal); } break; case 19: // body -> alternative, optional_alias { CurrentSemanticValue.altList = new List <Alternative>(); ValueStack[ValueStack.Depth - 2].altVal.Alias = ValueStack[ValueStack.Depth - 1].strVal; CurrentSemanticValue.altList.Add(ValueStack[ValueStack.Depth - 2].altVal); } break; case 20: // alternative -> alternative, entry { CurrentSemanticValue.altVal = ValueStack[ValueStack.Depth - 2].altVal; CurrentSemanticValue.altVal.Add(ValueStack[ValueStack.Depth - 1].entryVal); } break; case 21: // alternative -> /* empty */ { CurrentSemanticValue.altVal = new Alternative(); } break; case 22: // optional_alias -> ARROW, ID { CurrentSemanticValue.strVal = ValueStack[ValueStack.Depth - 1].strVal; this.Aliases.Add(ValueStack[ValueStack.Depth - 1].strVal); } break; case 23: // optional_alias -> /* empty */ { CurrentSemanticValue.strVal = null; } break; case 24: // entry -> context_options, entry_core, entry_args, quantifier, prec_nonempty { var opts = new LocalOptions(); foreach (var opt in ValueStack[ValueStack.Depth - 5].optionParamsList) { NodeOption nodeOpt; if (!Enum.TryParse <NodeOption>(opt.Item1.ToUpper(), out nodeOpt)) { MappingOption mapOpt; if (!Enum.TryParse <MappingOption>(opt.Item1.ToUpper(), out mapOpt)) { Log.Add(Message.Error( "Неизвестная опция '" + opt.Item1 + "'", LocationStack[LocationStack.Depth - 5].Start, "LanD" )); } else { opts.Set(mapOpt, opt.Item2.ToArray()); } } else { opts.Set(nodeOpt); } } if (ValueStack[ValueStack.Depth - 2].optQuantVal.HasValue) { if (ValueStack[ValueStack.Depth - 4].strVal.StartsWith(Grammar.ANY_TOKEN_NAME)) { Log.Add(Message.Warning( "Использование квантификаторов с символом '" + Grammar.ANY_TOKEN_NAME + "' избыточно и не влияет на процесс разбора", LocationStack[LocationStack.Depth - 5].Start, "LanD" )); } else { var generated = ConstructedGrammar.GenerateNonterminal(ValueStack[ValueStack.Depth - 4].strVal, ValueStack[ValueStack.Depth - 2].optQuantVal.Value, ValueStack[ValueStack.Depth - 1].boolVal); ConstructedGrammar.AddLocation(generated, CurrentLocationSpan.Start); CurrentSemanticValue.entryVal = new Entry(generated, opts); } } if (CurrentSemanticValue.entryVal == null) { if (ValueStack[ValueStack.Depth - 4].strVal.StartsWith(Grammar.ANY_TOKEN_NAME)) { AnyOption sugarOption; if (Enum.TryParse(ValueStack[ValueStack.Depth - 4].strVal.Substring(Grammar.ANY_TOKEN_NAME.Length), out sugarOption)) { opts.AnyOptions[sugarOption] = new HashSet <string>(ValueStack[ValueStack.Depth - 3].dynamicList.Select(e => (string)e)); } else { foreach (var opt in ValueStack[ValueStack.Depth - 3].dynamicList) { var errorGroupName = String.Empty; if (opt is ArgumentGroup) { var group = (ArgumentGroup)opt; if (Enum.TryParse(group.Name, out sugarOption)) { opts.AnyOptions[sugarOption] = new HashSet <string>(group.Arguments.Select(e => (string)e)); } else { errorGroupName = group.Name; } } else if (opt is String) { if (Enum.TryParse((string)opt, out sugarOption)) { opts.AnyOptions[sugarOption] = new HashSet <string>(); } else { errorGroupName = (string)opt; } } if (!String.IsNullOrEmpty(errorGroupName)) { Log.Add(Message.Error( "При описании '" + Grammar.ANY_TOKEN_NAME + "' использовано неизвестное имя группы '" + errorGroupName + "', группа проигнорирована", LocationStack[LocationStack.Depth - 5].Start, "LanD" )); } } } CurrentSemanticValue.entryVal = new Entry(Grammar.ANY_TOKEN_NAME, opts); } else { CurrentSemanticValue.entryVal = new Entry(ValueStack[ValueStack.Depth - 4].strVal, opts); } } } break; case 25: // entry_args -> ELEM_LROUND_BRACKET, args, RROUND_BRACKET { CurrentSemanticValue.dynamicList = ValueStack[ValueStack.Depth - 2].dynamicList; } break; case 26: // entry_args -> /* empty */ { CurrentSemanticValue.dynamicList = new List <dynamic>(); } break; case 27: // context_options -> context_options, OPTION_NAME, context_opt_args { CurrentSemanticValue.optionParamsList = ValueStack[ValueStack.Depth - 3].optionParamsList; CurrentSemanticValue.optionParamsList.Add(new Tuple <string, List <dynamic> >(ValueStack[ValueStack.Depth - 2].strVal, ValueStack[ValueStack.Depth - 1].dynamicList)); } break; case 28: // context_options -> /* empty */ { CurrentSemanticValue.optionParamsList = new List <Tuple <string, List <dynamic> > >(); } break; case 29: // context_opt_args -> OPT_LROUND_BRACKET, args, RROUND_BRACKET { CurrentSemanticValue.dynamicList = ValueStack[ValueStack.Depth - 2].dynamicList; } break; case 30: // context_opt_args -> /* empty */ { CurrentSemanticValue.dynamicList = new List <dynamic>(); } break; case 31: // prec_nonempty -> PREC_NONEMPTY { CurrentSemanticValue.boolVal = true; } break; case 32: // prec_nonempty -> /* empty */ { CurrentSemanticValue.boolVal = false; } break; case 33: // quantifier -> OPTIONAL { CurrentSemanticValue.optQuantVal = ValueStack[ValueStack.Depth - 1].quantVal; } break; case 34: // quantifier -> ZERO_OR_MORE { CurrentSemanticValue.optQuantVal = ValueStack[ValueStack.Depth - 1].quantVal; } break; case 35: // quantifier -> ONE_OR_MORE { CurrentSemanticValue.optQuantVal = ValueStack[ValueStack.Depth - 1].quantVal; } break; case 36: // quantifier -> /* empty */ { CurrentSemanticValue.optQuantVal = null; } break; case 37: // entry_core -> REGEX { CurrentSemanticValue.strVal = ConstructedGrammar.GenerateTerminal(ValueStack[ValueStack.Depth - 1].strVal); ConstructedGrammar.AddLocation(CurrentSemanticValue.strVal, CurrentLocationSpan.Start); } break; case 38: // entry_core -> ID { CurrentSemanticValue.strVal = ValueStack[ValueStack.Depth - 1].strVal; } break; case 39: // entry_core -> group { CurrentSemanticValue.strVal = ValueStack[ValueStack.Depth - 1].strVal; } break; case 40: // group -> LROUND_BRACKET, body, RROUND_BRACKET { CurrentSemanticValue.strVal = ConstructedGrammar.GenerateNonterminal(ValueStack[ValueStack.Depth - 2].altList); ConstructedGrammar.AddLocation(CurrentSemanticValue.strVal, CurrentLocationSpan.Start); } break; case 43: // category_block -> CATEGORY_NAME, option_or_block { OptionCategory optCategory; if (!Enum.TryParse(ValueStack[ValueStack.Depth - 2].strVal.ToUpper(), out optCategory)) { Log.Add(Message.Error( "Неизвестная категория опций '" + ValueStack[ValueStack.Depth - 2].strVal + "'", LocationStack[LocationStack.Depth - 2].Start, "LanD" )); } foreach (var option in ValueStack[ValueStack.Depth - 1].optionsList) { bool goodOption = true; switch (optCategory) { case OptionCategory.PARSING: ParsingOption parsingOpt; goodOption = Enum.TryParse(option.Name.ToUpper(), out parsingOpt); if (goodOption) { SafeGrammarAction(() => { ConstructedGrammar.SetOption(parsingOpt, option.Symbols.ToArray()); }, LocationStack[LocationStack.Depth - 2].Start); } break; case OptionCategory.NODES: NodeOption nodeOpt; goodOption = Enum.TryParse(option.Name.ToUpper(), out nodeOpt); if (goodOption) { SafeGrammarAction(() => { ConstructedGrammar.SetOption(nodeOpt, option.Symbols.ToArray()); }, LocationStack[LocationStack.Depth - 2].Start); } break; case OptionCategory.MAPPING: MappingOption mappingOpt; goodOption = Enum.TryParse(option.Name.ToUpper(), out mappingOpt); if (goodOption) { SafeGrammarAction(() => { ConstructedGrammar.SetOption(mappingOpt, option.Symbols.ToArray(), option.Arguments.ToArray()); }, LocationStack[LocationStack.Depth - 2].Start); } break; case OptionCategory.CUSTOMBLOCK: CustomBlockOption customBlockOption; goodOption = Enum.TryParse(option.Name.ToUpper(), out customBlockOption); if (goodOption) { SafeGrammarAction(() => { ConstructedGrammar.SetOption(customBlockOption, option.Symbols.ToArray(), option.Arguments.ToArray()); }, LocationStack[LocationStack.Depth - 2].Start); } break; default: break; } if (!goodOption) { Log.Add(Message.Error( "Опция '" + option.Name + "' не определена для категории '" + ValueStack[ValueStack.Depth - 2].strVal + "'", LocationStack[LocationStack.Depth - 1].Start, "LanD" )); } } } break; case 44: // option_or_block -> option { CurrentSemanticValue.optionsList = new List <OptionDeclaration>() { ValueStack[ValueStack.Depth - 1].optDeclVal }; } break; case 45: // option_or_block -> LCURVE_BRACKET, options, RCURVE_BRACKET { CurrentSemanticValue.optionsList = ValueStack[ValueStack.Depth - 2].optionsList; } break; case 46: // options -> /* empty */ { CurrentSemanticValue.optionsList = new List <OptionDeclaration>(); } break; case 47: // options -> options, option { CurrentSemanticValue.optionsList = ValueStack[ValueStack.Depth - 2].optionsList; ValueStack[ValueStack.Depth - 2].optionsList.Add(ValueStack[ValueStack.Depth - 1].optDeclVal); } break; case 48: // option -> OPTION_NAME, opt_args, identifiers { CurrentSemanticValue.optDeclVal = new OptionDeclaration() { Name = ValueStack[ValueStack.Depth - 3].strVal, Arguments = ValueStack[ValueStack.Depth - 2].dynamicList, Symbols = ValueStack[ValueStack.Depth - 1].strList }; } break; case 49: // opt_args -> LROUND_BRACKET, args, RROUND_BRACKET { CurrentSemanticValue.dynamicList = ValueStack[ValueStack.Depth - 2].dynamicList; } break; case 50: // opt_args -> /* empty */ { CurrentSemanticValue.dynamicList = new List <dynamic>(); } break; case 51: // args -> args, COMMA, argument { CurrentSemanticValue.dynamicList = ValueStack[ValueStack.Depth - 3].dynamicList; CurrentSemanticValue.dynamicList.Add(ValueStack[ValueStack.Depth - 1].dynamicVal); } break; case 52: // args -> argument { CurrentSemanticValue.dynamicList = new List <dynamic>() { ValueStack[ValueStack.Depth - 1].dynamicVal }; } break; case 53: // argument -> RNUM { CurrentSemanticValue.dynamicVal = ValueStack[ValueStack.Depth - 1].doubleVal; } break; case 54: // argument -> REGEX { var generated = ConstructedGrammar.GenerateTerminal((string)ValueStack[ValueStack.Depth - 1].strVal); ConstructedGrammar.AddLocation(generated, LocationStack[LocationStack.Depth - 1].Start); CurrentSemanticValue.dynamicVal = generated; } break; case 55: // argument -> STRING { CurrentSemanticValue.dynamicVal = ValueStack[ValueStack.Depth - 1].strVal.Substring(1, ValueStack[ValueStack.Depth - 1].strVal.Length - 2); } break; case 56: // argument -> ID { CurrentSemanticValue.dynamicVal = ValueStack[ValueStack.Depth - 1].strVal; } break; case 57: // argument -> argument_group { CurrentSemanticValue.dynamicVal = ValueStack[ValueStack.Depth - 1].argGroupVal; } break; case 58: // argument_group -> ID, ELEM_LROUND_BRACKET, args, RROUND_BRACKET { CurrentSemanticValue.argGroupVal = new ArgumentGroup() { Name = ValueStack[ValueStack.Depth - 4].strVal, Arguments = ValueStack[ValueStack.Depth - 2].dynamicList }; } break; case 59: // identifiers -> identifiers, ID { CurrentSemanticValue.strList = ValueStack[ValueStack.Depth - 2].strList; CurrentSemanticValue.strList.Add(ValueStack[ValueStack.Depth - 1].strVal); } break; case 60: // identifiers -> /* empty */ { CurrentSemanticValue.strList = new List <string>(); } break; } #pragma warning restore 162, 1522 }