예제 #1
0
        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
        }