/// <summary> /// Генерирует множество FIRST для элемента подправила (имя терминала/нетерминала/скобка[...]) /// </summary> /// <param name="sr"></param> /// <param name="flag">True, если элемент подправила допускает пустую продукцию</param> /// <returns></returns> private HashSet <string> GetFIRST(SubRulePart sr, ref bool flag) { HashSet <string> res; if (sr is SubRuleComplexPart) { res = symbolTable.GetFIRSTforComplexSubRulePart(sr as SubRuleComplexPart); } else { res = symbolTable.GetFIRST(sr.Name); } flag = res.Contains(StringConstants.EmptyProduction); return(res); }
/// <summary> /// генерируем предопределенные правила progrm, programnodelist, programnode /// </summary> private void GeneratePredefinedRules() { if (symbolTable._rules.ContainsKey(StringConstants.ProgramRuleName)) { return; } StringBuilder sb = new StringBuilder(); List <string> MainRules = GetMainRules(); string PNListName = symbolTable.GetNewName(StringConstants.YPreDefProgNodeListName); string PNName = symbolTable.GetNewName(StringConstants.YPreDefProgNodeName); RuleDeclaration rd = new RuleDeclaration(); rd.Name = PNListName; List <SubRulePart> SR = new List <SubRulePart>(); SR.Add(new SubRulePart(StringConstants.YPreDefProgNodeListA1)); rd.SubRules.Add(SR); SR = new List <SubRulePart>(); SR.Add(new SubRulePart(PNListName)); SR.Add(new SubRulePart(PNName)); SR.Add(new SubRulePart(StringConstants.YPreDefProgNodeListA2)); rd.SubRules.Add(SR); symbolTable.AddRule(rd); rd = new RuleDeclaration(); rd.Name = PNName; SubRulePart Action = new SubRulePart(StringConstants.YPreDefProgNodeSubRule); foreach (string str in MainRules) { SR = new List <SubRulePart>(); SR.Add(new SubRulePart(str)); SR.Add(Action); rd.SubRules.Add(SR); } symbolTable.AddRule(rd); rd = new RuleDeclaration(); rd.Name = StringConstants.ProgramRuleName; SR = new List <SubRulePart>(); SR.Add(new SubRulePart(PNListName)); SR.Add(new SubRulePart(StringConstants.YPreDefProgramAction)); rd.SubRules.Add(SR); rd.isGeneratedRule = false; symbolTable.AddRule(rd); }
private string GetRepetitionSymbol(SubRulePart srp) { if (srp.Repetition == SubRuleRepetition.OneOrMore) { return(StringConstants.RuleOneOrMoreSymbol); } else if (srp.Repetition == SubRuleRepetition.ZeroOrMore) { return(StringConstants.RuleZeroOrMoreSymbol); } else if (srp.Repetition == SubRuleRepetition.ZeroOrOne) { return(StringConstants.RuleOptSymbol); } else { return(""); } }
/// <summary> /// Генерирует множество FIRST /// </summary> /// <returns></returns> private HashSet <string> GetFIRST(List <Pair> trace, int level) { if (level < 0) { return(new HashSet <string>()); } HashSet <string> FIRST = new HashSet <string>(); //флаг для остановки цикла. Становится False если очередное вхождение не может быть пустым bool flag = true; int i = trace[level].Index + 1; List <SubRulePart> list = trace[level].List; while (flag && i < list.Count) { if (!(list[i] is SubRuleAction)) { FIRST.UnionWith(GetFIRST(list[i], ref flag)); if (list[i].Repetition == SubRuleRepetition.ZeroOrMore || list[i].Repetition == SubRuleRepetition.ZeroOrOne) { flag = true; } } i += 1; } if (flag) { FIRST.UnionWith(GetFIRST(trace, level - 1)); } if (level > 0) { SubRulePart s = trace[level - 1].List[trace[level - 1].Index]; if (s.Repetition == SubRuleRepetition.OneOrMore || s.Repetition == SubRuleRepetition.ZeroOrMore) { bool f = false; FIRST.UnionWith(GetFIRST(s, ref f)); } } return(FIRST); }
/// <summary> /// Преобразуем квадратные скобки в новое правило /// </summary> /// <param name="part"></param> /// <returns></returns> private SubRulePart ConvertComplexSubrulePart(SubRuleComplexPart part) { for (int i = 0; i < part.Items.Count; ++i) { for (int j = 0; j < part.Items[i].Count; ++j) { if (part.Items[i][j] is SubRuleComplexPart) { part.Items[i][j] = ConvertComplexSubrulePart(part.Items[i][j] as SubRuleComplexPart); if (part.Items[i][j] == null) { part.Items[i].RemoveAt(j); } --j; } } } part.InitUses(); //тут можно сгенерировать имя так, чтобы одинаковые конструкции не дублировались SubRulePart result = new SubRulePart(); result.UseName = part.UseName; result.UseValue = part.UseValue; result.Name = symbolTable.GetNewName(""); result.Repetition = SubRuleRepetition.Once; RuleDeclaration rd = new RuleDeclaration(); rd.Name = result.Name; rd.Location = part.Location; SubRulePart thisRule = new SubRulePart(result.Name); thisRule.UseName = result.UseName; thisRule.UseValue = result.UseValue; if (part.Repetition == SubRuleRepetition.ZeroOrOne) { rd.SubRules.Add(new List <SubRulePart>()); rd.SubRules.AddRange(part.Items); } else if (part.Repetition == SubRuleRepetition.ZeroOrMore) { rd.SubRules.Add(new List <SubRulePart>()); rd.SubRules.AddRange(part.Items); for (int i = 1; i < rd.SubRules.Count; ++i) { rd.SubRules[i].Insert(0, thisRule); } } else if (part.Repetition == SubRuleRepetition.OneOrMore) { rd.SubRules.AddRange(part.Items); foreach (List <SubRulePart> L in part.Items) { List <SubRulePart> L2 = new List <SubRulePart>(); L2.Add(thisRule); L2.AddRange(L); rd.SubRules.Add(L2); } } else if (part.Repetition == SubRuleRepetition.Once) { if (part.Items.Count == 0) { return(null); } if (part.Items.Count == 1 && part.Items[0].Count == 1) { return(part.Items[0][0]); } rd.SubRules.AddRange(part.Items); } symbolTable.AddRuleDeferred(rd); return(result); }
/// <summary> /// генерируем предопределенные правила progrm, programnodelist, programnode /// </summary> private void GeneratePredefinedRules() { if (symbolTable._rules.ContainsKey(StringConstants.ProgramRuleName)) return; StringBuilder sb = new StringBuilder(); List<string> MainRules = GetMainRules(); string PNListName = symbolTable.GetNewName(StringConstants.YPreDefProgNodeListName); string PNName = symbolTable.GetNewName(StringConstants.YPreDefProgNodeName); RuleDeclaration rd = new RuleDeclaration(); rd.Name = PNListName; List<SubRulePart> SR = new List<SubRulePart>(); SR.Add(new SubRulePart(StringConstants.YPreDefProgNodeListA1)); rd.SubRules.Add(SR); SR = new List<SubRulePart>(); SR.Add(new SubRulePart(PNListName)); SR.Add(new SubRulePart(PNName)); SR.Add(new SubRulePart(StringConstants.YPreDefProgNodeListA2)); rd.SubRules.Add(SR); symbolTable.AddRule(rd); rd = new RuleDeclaration(); rd.Name = PNName; SubRulePart Action = new SubRulePart(StringConstants.YPreDefProgNodeSubRule); foreach (string str in MainRules) { SR = new List<SubRulePart>(); SR.Add(new SubRulePart(str)); SR.Add(Action); rd.SubRules.Add(SR); } symbolTable.AddRule(rd); rd = new RuleDeclaration(); rd.Name = StringConstants.ProgramRuleName; SR = new List<SubRulePart>(); SR.Add(new SubRulePart(PNListName)); SR.Add(new SubRulePart(StringConstants.YPreDefProgramAction)); rd.SubRules.Add(SR); rd.isGeneratedRule = false; symbolTable.AddRule(rd); }
private string GetRepetitionSymbol(SubRulePart srp) { if (srp.Repetition == SubRuleRepetition.OneOrMore) return StringConstants.RuleOneOrMoreSymbol; else if (srp.Repetition == SubRuleRepetition.ZeroOrMore) return StringConstants.RuleZeroOrMoreSymbol; else if (srp.Repetition == SubRuleRepetition.ZeroOrOne) return StringConstants.RuleOptSymbol; else return ""; }
/// <summary> /// Преобразуем квадратные скобки в новое правило /// </summary> /// <param name="part"></param> /// <returns></returns> private SubRulePart ConvertComplexSubrulePart(SubRuleComplexPart part) { for (int i = 0; i < part.Items.Count; ++i) for (int j = 0; j < part.Items[i].Count; ++j) if (part.Items[i][j] is SubRuleComplexPart) { part.Items[i][j] = ConvertComplexSubrulePart(part.Items[i][j] as SubRuleComplexPart); if (part.Items[i][j] == null) part.Items[i].RemoveAt(j); --j; } part.InitUses(); //тут можно сгенерировать имя так, чтобы одинаковые конструкции не дублировались SubRulePart result = new SubRulePart(); result.UseName = part.UseName; result.UseValue = part.UseValue; result.Name = symbolTable.GetNewName(""); result.Repetition = SubRuleRepetition.Once; RuleDeclaration rd = new RuleDeclaration(); rd.Name = result.Name; rd.Location = part.Location; SubRulePart thisRule = new SubRulePart(result.Name); thisRule.UseName = result.UseName; thisRule.UseValue = result.UseValue; if (part.Repetition == SubRuleRepetition.ZeroOrOne) { rd.SubRules.Add(new List<SubRulePart>()); rd.SubRules.AddRange(part.Items); } else if (part.Repetition == SubRuleRepetition.ZeroOrMore) { rd.SubRules.Add(new List<SubRulePart>()); rd.SubRules.AddRange(part.Items); for (int i = 1; i < rd.SubRules.Count; ++i) rd.SubRules[i].Insert(0, thisRule); } else if (part.Repetition == SubRuleRepetition.OneOrMore) { rd.SubRules.AddRange(part.Items); foreach (List<SubRulePart> L in part.Items) { List<SubRulePart> L2 = new List<SubRulePart>(); L2.Add(thisRule); L2.AddRange(L); rd.SubRules.Add(L2); } } else if (part.Repetition == SubRuleRepetition.Once) { if (part.Items.Count == 0) return null; if (part.Items.Count == 1 && part.Items[0].Count == 1) return part.Items[0][0]; rd.SubRules.AddRange(part.Items); } symbolTable.AddRuleDeferred(rd); return result; }
/// <summary> /// Генерирует множество FIRST для элемента подправила (имя терминала/нетерминала/скобка[...]) /// </summary> /// <param name="sr"></param> /// <param name="flag">True, если элемент подправила допускает пустую продукцию</param> /// <returns></returns> private HashSet<string> GetFIRST(SubRulePart sr, ref bool flag) { HashSet<string> res; if (sr is SubRuleComplexPart) res = symbolTable.GetFIRSTforComplexSubRulePart(sr as SubRuleComplexPart); else res = symbolTable.GetFIRST(sr.Name); flag = res.Contains(StringConstants.EmptyProduction); return res; }
protected override void DoAction(int action) { CurrentSemanticValue = new ValueType(); #pragma warning disable 162, 1522 switch (action) { case 2: // Program -> /* empty */ { CurrentSemanticValue.sf = new SourceFile(); root = CurrentSemanticValue.sf; } break; case 3: // Program -> Program, Declaration { CurrentSemanticValue.sf = ValueStack[ValueStack.Depth - 2].sf; if (ValueStack[ValueStack.Depth - 1].Decl != null) { ValueStack[ValueStack.Depth - 1].Decl.Location = LocationStack[LocationStack.Depth - 1]; CurrentSemanticValue.sf.Declarations.Add(ValueStack[ValueStack.Depth - 1].Decl); } } break; case 4: // Declaration -> error { } break; case 5: // Declaration -> tkSkip, SkipParameters { CurrentSemanticValue.Decl = new SkipDeclaration(); (CurrentSemanticValue.Decl as SkipDeclaration).Merge(ValueStack[ValueStack.Depth - 1].skipDs); } break; case 6: // Declaration -> tkRule, UseRuleName, Token, tkColon, SubRules { RuleDeclaration rd = new RuleDeclaration(); rd.UseRuleName = ValueStack[ValueStack.Depth - 4].flag; rd.Name = ValueStack[ValueStack.Depth - 3].sVal; rd.Merge(ValueStack[ValueStack.Depth - 1].ruleDs); CurrentSemanticValue.Decl = rd; } break; case 8: // Anon@1 -> /* empty */ { (Scanner as Scanner).BeginRegexp(); } break; case 9: // Declaration -> tkRegExToken, Token, Anon@1, RegExp { CurrentSemanticValue.Decl = new RegExTokenDeclaration(ValueStack[ValueStack.Depth - 3].sVal, ValueStack[ValueStack.Depth - 1].sVal); } break; case 10: // SkipParameters -> /* empty */ { CurrentSemanticValue.skipDs = new SkipDeclaration(); } break; case 11: // SkipParameters -> SkipParameters, SkipParam { CurrentSemanticValue.skipDs = ValueStack[ValueStack.Depth - 2].skipDs; CurrentSemanticValue.skipDs.Merge(ValueStack[ValueStack.Depth - 1].skipDs); } break; case 12: // SkipParam -> tkNested { CurrentSemanticValue.skipDs = new SkipDeclaration(); CurrentSemanticValue.skipDs.Nested = true; } break; case 13: // SkipParam -> tkBegin, TokenList { CurrentSemanticValue.skipDs = new SkipDeclaration(); CurrentSemanticValue.skipDs.Begin.AddRange(ValueStack[ValueStack.Depth - 1].sList.ToArray()); } break; case 14: // SkipParam -> tkEnd, TokenList { CurrentSemanticValue.skipDs = new SkipDeclaration(); CurrentSemanticValue.skipDs.End.AddRange(ValueStack[ValueStack.Depth - 1].sList.ToArray()); } break; case 15: // SkipParam -> tkBeginEnd, TokenList { CurrentSemanticValue.skipDs = new SkipDeclaration(); CurrentSemanticValue.skipDs.Begin.AddRange(ValueStack[ValueStack.Depth - 1].sList.ToArray()); CurrentSemanticValue.skipDs.End.AddRange(ValueStack[ValueStack.Depth - 1].sList.ToArray()); } break; case 16: // SkipParam -> tkEscapeSymbol, TokenList { CurrentSemanticValue.skipDs = new SkipDeclaration(); CurrentSemanticValue.skipDs.EscapeSymbol.AddRange(ValueStack[ValueStack.Depth - 1].sList.ToArray()); } break; case 17: // SkipParam -> tkPreprocessor { CurrentSemanticValue.skipDs = new SkipDeclaration(); CurrentSemanticValue.skipDs.Preprocessor = true; } break; case 18: // TokenList -> /* empty */ { CurrentSemanticValue.sList = new List <string>(); } break; case 19: // TokenList -> TokenList, Token { CurrentSemanticValue.sList = ValueStack[ValueStack.Depth - 2].sList; CurrentSemanticValue.sList.Add(ValueStack[ValueStack.Depth - 1].sVal); } break; case 20: // TokenCommaList -> /* empty */ { CurrentSemanticValue.sList = new List <string>(); } break; case 21: // TokenCommaList -> Token { CurrentSemanticValue.sList = new List <string>(); CurrentSemanticValue.sList.Add(ValueStack[ValueStack.Depth - 1].sVal); } break; case 22: // TokenCommaList -> TokenCommaList, tkComma, Token { CurrentSemanticValue.sList = ValueStack[ValueStack.Depth - 3].sList; CurrentSemanticValue.sList.Add(ValueStack[ValueStack.Depth - 1].sVal); } break; case 23: // UseNameValue -> /* empty */ { CurrentSemanticValue.sVal = ""; } break; case 24: // UseNameValue -> tkAt { CurrentSemanticValue.sVal = "@"; } break; case 25: // UseNameValue -> tkSharp { CurrentSemanticValue.sVal = "#"; } break; case 26: // UseNameValue -> tkAt, tkSharp { CurrentSemanticValue.sVal = "@#"; } break; case 27: // UseNameValue -> tkSharp, tkAt { CurrentSemanticValue.sVal = "@#"; } break; case 28: // UseRuleName -> /* empty */ { CurrentSemanticValue.flag = false; } break; case 29: // UseRuleName -> tkAt { CurrentSemanticValue.flag = true; } break; case 30: // Repetition -> /* empty */ { CurrentSemanticValue.srRep = SubRuleRepetition.Once; } break; case 31: // Repetition -> tkQuest { CurrentSemanticValue.srRep = SubRuleRepetition.ZeroOrOne; } break; case 32: // Repetition -> tkPlus { CurrentSemanticValue.srRep = SubRuleRepetition.OneOrMore; } break; case 33: // Repetition -> tkStar { CurrentSemanticValue.srRep = SubRuleRepetition.ZeroOrMore; } break; case 34: // SubRuleToken -> UseNameValue, Token, Repetition { SubRulePart srp = new SubRulePart(ValueStack[ValueStack.Depth - 2].sVal); srp.UseName = ValueStack[ValueStack.Depth - 3].sVal == "@" || ValueStack[ValueStack.Depth - 3].sVal == "@#"; srp.UseValue = ValueStack[ValueStack.Depth - 3].sVal == "#" || ValueStack[ValueStack.Depth - 3].sVal == "@#"; srp.Repetition = ValueStack[ValueStack.Depth - 1].srRep; CurrentSemanticValue.srp = srp; } break; case 35: // SubRuleToken -> UseNameValue, tkAny, Repetition { SubRuleAny sr = new SubRuleAny(); sr.UseName = ValueStack[ValueStack.Depth - 3].sVal == "@" || ValueStack[ValueStack.Depth - 3].sVal == "@#"; sr.UseValue = ValueStack[ValueStack.Depth - 3].sVal == "#" || ValueStack[ValueStack.Depth - 3].sVal == "@#"; sr.Repetition = ValueStack[ValueStack.Depth - 1].srRep; CurrentSemanticValue.srp = sr; } break; case 36: // SubRuleToken -> UseNameValue, tkAnyExcept, tkRoundOpen, ExceptList, // tkRoundClose, Repetition { SubRuleAny sr = new SubRuleAny(); sr.UseName = ValueStack[ValueStack.Depth - 6].sVal == "@" || ValueStack[ValueStack.Depth - 6].sVal == "@#"; sr.UseValue = ValueStack[ValueStack.Depth - 6].sVal == "#" || ValueStack[ValueStack.Depth - 6].sVal == "@#"; sr.Repetition = ValueStack[ValueStack.Depth - 1].srRep; sr.Except = ValueStack[ValueStack.Depth - 3].sHS; CurrentSemanticValue.srp = sr; } break; case 37: // SubRuleToken -> UseNameValue, tkList, tkRoundOpen, TokenCommaList, tkRoundClose, // Repetition { if (ValueStack[ValueStack.Depth - 3].sList.Count == 0 || ValueStack[ValueStack.Depth - 3].sList.Count > 2) { ErrorReporter.WriteError(ErrorMessages.WrongListParameters, LocationStack[LocationStack.Depth - 5]); } else { string NT = ValueStack[ValueStack.Depth - 3].sList[0]; string Sep = ""; if (ValueStack[ValueStack.Depth - 3].sList.Count > 1) { Sep = ValueStack[ValueStack.Depth - 3].sList[1]; } SubRuleNonTermList sr = new SubRuleNonTermList(NT, Sep); sr.UseName = ValueStack[ValueStack.Depth - 6].sVal == "@" || ValueStack[ValueStack.Depth - 6].sVal == "@#"; sr.CanBeEmpty = ValueStack[ValueStack.Depth - 5].sVal == StringConstants.tkList0; sr.Repetition = ValueStack[ValueStack.Depth - 1].srRep; CurrentSemanticValue.srp = sr; } } break; case 38: // SubRuleToken -> tkSquareOpen, SubRules, tkSquareClose, Repetition { CurrentSemanticValue.srp = new SubRuleComplexPart(ValueStack[ValueStack.Depth - 3].ruleDs.SubRules); CurrentSemanticValue.srp.Repetition = ValueStack[ValueStack.Depth - 1].srRep; } break; case 39: // SubRule -> /* empty */ { CurrentSemanticValue.srpL = new List <SubRulePart>(); } break; case 40: // SubRule -> SubRule, SubRuleToken { CurrentSemanticValue.srpL = ValueStack[ValueStack.Depth - 2].srpL; CurrentSemanticValue.srpL.Add(ValueStack[ValueStack.Depth - 1].srp); ValueStack[ValueStack.Depth - 1].srp.Location = LocationStack[LocationStack.Depth - 1]; } break; case 41: // SubRules -> SubRule { CurrentSemanticValue.ruleDs = new RuleDeclaration(); CurrentSemanticValue.ruleDs.SubRules.Add(ValueStack[ValueStack.Depth - 1].srpL); } break; case 42: // SubRules -> SubRules, tkPipe, SubRule { CurrentSemanticValue.ruleDs = ValueStack[ValueStack.Depth - 3].ruleDs; CurrentSemanticValue.ruleDs.SubRules.Add(ValueStack[ValueStack.Depth - 1].srpL); CurrentSemanticValue.ruleDs.Location = LocationStack[LocationStack.Depth - 3].Merge(LocationStack[LocationStack.Depth - 1]); } break; case 43: // ExceptList -> Token { CurrentSemanticValue.sHS = new HashSet <string>(); CurrentSemanticValue.sHS.Add(ValueStack[ValueStack.Depth - 1].sVal); } break; case 44: // ExceptList -> ExceptList, tkComma, Token { CurrentSemanticValue.sHS = ValueStack[ValueStack.Depth - 3].sHS; CurrentSemanticValue.sHS.Add(ValueStack[ValueStack.Depth - 1].sVal); } break; case 45: // Directive -> tkCaseSensitive { Options.CaseInsensitive = false; } break; case 46: // Directive -> tkCaseInsensitive { Options.CaseInsensitive = true; } break; case 47: // Directive -> tkExtension, TokenList { Options.ExtensionList = ValueStack[ValueStack.Depth - 1].sList; } break; case 48: // Directive -> tkRegion, tkBegin, tkEq, Token, tkEnd, tkEq, Token { Options.RegionBegin = ValueStack[ValueStack.Depth - 4].sVal; Options.RegionEnd = ValueStack[ValueStack.Depth - 1].sVal; } break; case 49: // Directive -> tkPreprocessor, PreProcDirective {} break; case 50: // Directive -> tkNamespace, Token { Options.Namespace = ValueStack[ValueStack.Depth - 1].sVal; } break; case 51: // PreProcDirective -> PreProcDirectivePart {} break; case 52: // PreProcDirective -> PreProcDirective, PreProcDirectivePart {} break; case 53: // PreProcDirectivePart -> tkDefine, tkEq, Token { Options.DirectiveDefine = ValueStack[ValueStack.Depth - 1].sVal; } break; case 54: // PreProcDirectivePart -> tkUndef, tkEq, Token { Options.DirectiveUndef = ValueStack[ValueStack.Depth - 1].sVal; } break; case 55: // PreProcDirectivePart -> tkIfdef, tkEq, Token { Options.DirectiveIfdef = ValueStack[ValueStack.Depth - 1].sVal; } break; case 56: // PreProcDirectivePart -> tkIfndef, tkEq, Token { Options.DirectiveIfndef = ValueStack[ValueStack.Depth - 1].sVal; } break; case 57: // PreProcDirectivePart -> tkElse, tkEq, Token { Options.DirectiveElse = ValueStack[ValueStack.Depth - 1].sVal; } break; case 58: // PreProcDirectivePart -> tkElif, tkEq, Token { Options.DirectiveElif = ValueStack[ValueStack.Depth - 1].sVal; } break; case 59: // PreProcDirectivePart -> tkEnd, tkEq, Token { Options.DirectiveEnd = ValueStack[ValueStack.Depth - 1].sVal; } break; } #pragma warning restore 162, 1522 }