private void SimplifyTokenOnlyRules() { List <string> RemoveRules = new List <string>(); foreach (RuleDeclaration rd in symbolTable._rules.Values) { bool flag = true; foreach (List <SubRulePart> branch in rd.SubRules) { if (branch.Count != 1) { flag = false; } else if (branch[0].GetType() != typeof(SubRulePart)) { flag = false; } else if (!branch[0].Name.StartsWith("\"")) { flag = false; } else if (branch[0].Repetition != SubRuleRepetition.Once) { flag = false; } } if (flag) { RemoveRules.Add(rd.Name); } } Dictionary <string, int> Literals = GetLiteralUsesCount(); foreach (string str in RemoveRules) { bool flag = true; RuleDeclaration rd = symbolTable._rules[str]; foreach (List <SubRulePart> branch in rd.SubRules) { if (Literals[branch[0].Name] != 1) { flag = false; } } if (!flag) { continue; } TokenDeclaration td = new TokenDeclaration(); td.Name = rd.Name; td.Location = rd.Location; foreach (List <SubRulePart> branch in rd.SubRules) { td.Values.Add(branch[0].Name); } symbolTable._rules.Remove(str); symbolTable._allNames.Remove(str); symbolTable.AddToken(td); } }
/// <summary> /// Поиск строковых лексем для начала и конца именованных директив пропуска /// </summary> /// <param name="tl"></param> /// <returns></returns> private List <string> FindTokensForNamedSkipBeginEnd(List <string> tl) { List <string> result = new List <string>(); foreach (string str in tl) { if (str.StartsWith("\"")) { result.Add(str); } else { if (symbolTable._tokens.ContainsKey(str)) { result.AddRange(symbolTable._tokens[str].Values); } else if (symbolTable._rules.ContainsKey(str)) { RuleDeclaration rd = symbolTable._rules[str]; foreach (List <SubRulePart> tl2 in rd.SubRules) { result.Add(symbolTable._tokens[tl2[0].Name].Values[0]); } } } } return(result); }
private void CreateRuleForANY(List <Pair> trace, SubRuleAny ANY, RuleDeclaration rdec) { foreach (string str in ANY.Except) { if (str.StartsWith(StringConstants.tkANY) && str != ANY.Name) { ErrorReporter.WriteError(ErrorMessages.ANYCollision, rdec.Location); } } HashSet <string> Except = GetFIRST(trace, trace.Count - 1); foreach (string str in ANY.Except) { Except.UnionWith(symbolTable.GetFIRST(str)); } ANY.Except = Except; RuleDeclaration rd = new RuleDeclaration(); rd.Name = symbolTable.GetNewName("ANY"); ANY.Name = rd.Name; foreach (string str in symbolTable._tokens.Keys) { if (!ANY.Except.Contains(str)) { List <SubRulePart> branch = new List <SubRulePart>(); branch.Add(new SubRulePart(str, true)); rd.SubRules.Add(branch); } } symbolTable.AddRuleDeferred(rd); }
/// <summary> /// Поиск нетерминала ANY и генерация правила для него. /// </summary> /// <param name="trace"></param> private void findNonTermANY(List <Pair> trace, RuleDeclaration rd) { List <SubRulePart> list = trace[trace.Count - 1].List; for (int i = 0; i < list.Count; ++i) { trace[trace.Count - 1].Index = i; //главная проверка if list[i] is subruleany if (list[i] is SubRuleAny) { CreateRuleForANY(trace, list[i] as SubRuleAny, rd); } if (list[i] is SubRuleComplexPart) { SubRuleComplexPart sc = list[i] as SubRuleComplexPart; for (int j = 0; j < sc.Items.Count; ++j) { trace.Add(new Pair(sc.Items[j], 0)); findNonTermANY(trace, rd); trace.RemoveAt(trace.Count - 1); } } } }
/// <summary> /// Избавляемся в ветке правила от *+?, генерируя по необходимости новые правила /// </summary> /// <param name="tl"></param> private void ExpandSubrule(List <SubRulePart> subRule) { if (subRule.Count == 0) { return; } for (int i = 0; i < subRule.Count;) { if (subRule[i].Repetition != SubRuleRepetition.Once) { string ruleName = symbolTable.FindGeneratedRuleName(subRule[i].Name + GetRepetitionSymbol(subRule[i])); if (ruleName == "") { RuleDeclaration newRule = new RuleDeclaration(); if (subRule[i].Repetition == SubRuleRepetition.ZeroOrOne) { ruleName = symbolTable.GetNewName(subRule[i].Name + StringConstants.tkOptionalSuffix); newRule.SubRules.Add(new List <SubRulePart>()); List <SubRulePart> sr2 = new List <SubRulePart>(); sr2.Add(new SubRulePart(subRule[i].Name, true)); newRule.SubRules.Add(sr2); } else if (subRule[i].Repetition == SubRuleRepetition.ZeroOrMore) { ruleName = symbolTable.GetNewName(subRule[i].Name + StringConstants.tkZeroOrMoreSuffix); newRule.SubRules.Add(new List <SubRulePart>()); List <SubRulePart> sr2 = new List <SubRulePart>(); sr2.Add(new SubRulePart(ruleName, true)); sr2.Add(new SubRulePart(subRule[i].Name, true)); newRule.SubRules.Add(sr2); } else if (subRule[i].Repetition == SubRuleRepetition.OneOrMore) { ruleName = symbolTable.GetNewName(subRule[i].Name + StringConstants.tkOneOrMoreSuffix); List <SubRulePart> sr1 = new List <SubRulePart>(); sr1.Add(new SubRulePart(subRule[i].Name, true)); newRule.SubRules.Add(sr1); List <SubRulePart> sr2 = new List <SubRulePart>(); sr2.Add(new SubRulePart(ruleName, true)); sr2.Add(new SubRulePart(subRule[i].Name, true)); newRule.SubRules.Add(sr2); } newRule.Name = ruleName; symbolTable.AddRule(newRule); symbolTable._ruleNames.Add(subRule[i].Name + GetRepetitionSymbol(subRule[i]), ruleName); } subRule[i].Name = ruleName; subRule[i].Repetition = SubRuleRepetition.Once; } else { ++i; } } }
public void AddRule(RuleDeclaration ruleDescriptor) { if (_allNames.Contains(ruleDescriptor.Name)) { ErrorReporter.WriteError(ErrorMessages.NameAlreadyDefined, ruleDescriptor.Location, ruleDescriptor.Name); return; } else { _rules.Add(ruleDescriptor.Name, ruleDescriptor); _allNames.Add(ruleDescriptor.Name); } }
public void AddRuleDeferred(RuleDeclaration rule) { if (_allNames.Contains(rule.Name)) { ErrorReporter.WriteError(ErrorMessages.NameAlreadyDefined, rule.Location, rule.Name); return; } else { _deferredRules.Add(rule); _allNames.Add(rule.Name); } }
public void Merge(RuleDeclaration rule) { if (rule == null) { return; } if (rule.Location != null) { Location = Location.Merge(rule.Location); } if (rule.SubRules != null) { SubRules.AddRange(rule.SubRules.ToArray()); } }
/// <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); }
/// <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 void ReplaceUniformListsWithRules(List <SubRulePart> branch, string RuleName, LexLocation Location) { //перебираем все символы ветки, на скобках запускаем рекурсию for (int i = 0; i < branch.Count; ++i) { if (branch[i] is SubRuleComplexPart) { foreach (List <SubRulePart> subBranch in (branch[i] as SubRuleComplexPart).Items) { ReplaceUniformListsWithRules(subBranch, RuleName, Location); } } else if (branch[i] is SubRuleNonTermList) { SubRuleNonTermList NTList = branch[i] as SubRuleNonTermList; // Проверяем, первое ли это вхождение List в ветке правила if (!isFirstTimeListEntity) { ErrorReporter.WriteError(ErrorMessages.MultipleListsNotAllowed, Location, RuleName); return; } isFirstTimeListEntity = false; //проверяем отсутствие после него знаков повторения if (branch[i].Repetition != SubRuleRepetition.Once) { ErrorReporter.WriteError(ErrorMessages.RepetitionAfterListNotAllowed, Location, RuleName); return; } //проверяем первый параметр - должно быть имя правила if (symbolTable.FindRuleDescriptor(NTList.Name) == null) { ErrorReporter.WriteError(ErrorMessages.WrongFirstParamInList, Location, RuleName); return; } bool SeparatorEmpty = NTList.Separator == null || NTList.Separator == ""; //проверяем второй параметр - должен быть разделитель - строка или имя лексемы if (!SeparatorEmpty && !NTList.Separator.StartsWith("\"")) { if (symbolTable.FindTokenList(NTList.Separator) == null) { ErrorReporter.WriteError(ErrorMessages.WrongFirstParamInList, Location, RuleName); return; } else { NTList.Separator = symbolTable.FindTokenList(NTList.Separator).Values[0]; } } //строим новое правило RuleDeclaration newRule = new RuleDeclaration(); newRule.Name = symbolTable.GetNewName(RuleName + StringConstants.tkUniformSetSuffix); newRule.Location = Location; newRule.isActionGenerated = true; newRule.isGeneratedRule = true; newRule.UseRuleName = false; newRule.Type = StringConstants.SourceEntityUniformSetClassName; List <SubRulePart> Branch1 = new List <SubRulePart>(); List <SubRulePart> Branch2 = new List <SubRulePart>(); string action; string Sep1 = SeparatorEmpty ? "\"\"" : NTList.Separator; string ActionAddValPart = symbolTable.FindRuleDescriptor(NTList.Name).isGeneratedRule ? StringConstants.YActionAddValueAsList : StringConstants.YActionAddValue; if (NTList.CanBeEmpty) { action = string.Format(StringConstants.YActionForSet1, StringConstants.SourceEntityUniformSetClassName, Sep1, Environment.NewLine, "true"); } else { Branch1.Add(new SubRulePart(NTList.Name, true)); string act = string.Format(ActionAddValPart, "1") + string.Format(StringConstants.YActionAddName, "1"); action = string.Format(StringConstants.YActionForSet1, StringConstants.SourceEntityUniformSetClassName, Sep1, act + Environment.NewLine, "false"); } Branch1.Add(new SubRuleAction(action)); Branch2.Add(new SubRulePart(newRule.Name)); if (SeparatorEmpty) { action = string.Format(StringConstants.YActionForSet2, "2", string.Format(ActionAddValPart, "2")); } else { Branch2.Add(new SubRulePart(NTList.Separator)); action = string.Format(StringConstants.YActionForSet2, "3", string.Format(ActionAddValPart, "3")); } Branch2.Add(new SubRulePart(NTList.Name, true)); Branch2.Add(new SubRuleAction(action)); newRule.SubRules.Add(Branch1); newRule.SubRules.Add(Branch2); symbolTable.AddRuleDeferred(newRule); branch.RemoveAt(i); branch.Insert(i, new SubRulePart(newRule.Name)); branch[i].UseValue = true; branch[i].UseName = NTList.UseName; } } }
/// <summary> /// Дописываем к правилам действия /// </summary> private void AddActionsToRules() { foreach (KeyValuePair <string, RuleDeclaration> rd in symbolTable._rules) { if (rd.Value.isActionGenerated) { continue; } foreach (List <SubRulePart> tl in rd.Value.SubRules) { string str; bool isError = false; foreach (SubRulePart srp in tl) { if (srp.Name == StringConstants.ErrorRuleName) { isError = true; } } if (isError) { str = string.Format(StringConstants.YErrorAction, Options.BaseClassName, tl.Count); } else { List <int> Names = new List <int>(); List <int> Values = new List <int>(); for (int i = 0; i < tl.Count; ++i) { if (tl[i].UseName) { Names.Add(i + 1); } if (tl[i].UseValue) { Values.Add(i + 1); } } StringBuilder sb = new StringBuilder(); if (rd.Value.UseRuleName) { sb.AppendFormat(StringConstants.YActionAddName, rd.Value.Name); } foreach (int i in Names) { sb.AppendFormat(StringConstants.YActionAddNameList, i); } foreach (int i in Values) { RuleDeclaration frd = symbolTable.FindRuleDescriptor(tl[i - 1].Name); if ((frd != null && frd.isGeneratedRule) || tl[i - 1].Name == StringConstants.ProgramRuleName) { sb.AppendFormat(StringConstants.YActionAddValueAsList, i); } else { sb.AppendFormat(StringConstants.YActionAddValue, i); } } if (rd.Key == StringConstants.ProgramRuleName) { sb.Append(StringConstants.YActionPartForProgram); } string strErr = ""; if (rd.Value.HasError()) { strErr = StringConstants.YErrorAltBranchAction; sb.Append(strErr); } string type = rd.Value.isGeneratedRule ? Options.BaseClassName : rd.Value.Name; if (Names.Count == 0 && Values.Count == 0 && !rd.Value.UseRuleName) { str = string.Format(StringConstants.YActionEmpty, type, strErr); } else { int last = tl.Count; while (last > 1 && tl[last - 1].Name.TrimStart().StartsWith(StringConstants.ActionStartSymbol)) { last -= 1; } str = string.Format(StringConstants.YAction, last, sb.ToString(), type); } } tl.Add(new SubRuleAction(str)); } rd.Value.isActionGenerated = true; } }
public void Merge(RuleDeclaration rule) { if (rule == null) return; if (rule.Location != null) Location = Location.Merge(rule.Location); if (rule.SubRules != null) SubRules.AddRange(rule.SubRules.ToArray()); }
/// <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> /// Избавляемся в ветке правила от *+?, генерируя по необходимости новые правила /// </summary> /// <param name="tl"></param> private void ExpandSubrule(List<SubRulePart> subRule) { if (subRule.Count == 0) return; for (int i = 0; i < subRule.Count; ) { if (subRule[i].Repetition != SubRuleRepetition.Once) { string ruleName = symbolTable.FindGeneratedRuleName(subRule[i].Name + GetRepetitionSymbol(subRule[i])); if (ruleName == "") { RuleDeclaration newRule = new RuleDeclaration(); if (subRule[i].Repetition == SubRuleRepetition.ZeroOrOne) { ruleName = symbolTable.GetNewName(subRule[i].Name + StringConstants.tkOptionalSuffix); newRule.SubRules.Add(new List<SubRulePart>()); List<SubRulePart> sr2 = new List<SubRulePart>(); sr2.Add(new SubRulePart(subRule[i].Name, true)); newRule.SubRules.Add(sr2); } else if (subRule[i].Repetition == SubRuleRepetition.ZeroOrMore) { ruleName = symbolTable.GetNewName(subRule[i].Name + StringConstants.tkZeroOrMoreSuffix); newRule.SubRules.Add(new List<SubRulePart>()); List<SubRulePart> sr2 = new List<SubRulePart>(); sr2.Add(new SubRulePart(ruleName, true)); sr2.Add(new SubRulePart(subRule[i].Name, true)); newRule.SubRules.Add(sr2); } else if (subRule[i].Repetition == SubRuleRepetition.OneOrMore) { ruleName = symbolTable.GetNewName(subRule[i].Name + StringConstants.tkOneOrMoreSuffix); List<SubRulePart> sr1 = new List<SubRulePart>(); sr1.Add(new SubRulePart(subRule[i].Name, true)); newRule.SubRules.Add(sr1); List<SubRulePart> sr2 = new List<SubRulePart>(); sr2.Add(new SubRulePart(ruleName, true)); sr2.Add(new SubRulePart(subRule[i].Name, true)); newRule.SubRules.Add(sr2); } newRule.Name = ruleName; symbolTable.AddRule(newRule); symbolTable._ruleNames.Add(subRule[i].Name + GetRepetitionSymbol(subRule[i]), ruleName); } subRule[i].Name = ruleName; subRule[i].Repetition = SubRuleRepetition.Once; } else ++i; } }
/// <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> /// Поиск нетерминала ANY и генерация правила для него. /// </summary> /// <param name="trace"></param> private void findNonTermANY(List<Pair> trace, RuleDeclaration rd) { List<SubRulePart> list = trace[trace.Count-1].List; for (int i = 0; i < list.Count; ++i) { trace[trace.Count - 1].Index = i; //главная проверка if list[i] is subruleany if (list[i] is SubRuleAny) CreateRuleForANY(trace, list[i] as SubRuleAny, rd); if (list[i] is SubRuleComplexPart) { SubRuleComplexPart sc = list[i] as SubRuleComplexPart; for (int j = 0; j< sc.Items.Count; ++j) { trace.Add(new Pair(sc.Items[j], 0)); findNonTermANY(trace, rd); trace.RemoveAt(trace.Count - 1); } } } }
private void CreateRuleForANY(List<Pair> trace, SubRuleAny ANY, RuleDeclaration rdec) { foreach (string str in ANY.Except) if (str.StartsWith(StringConstants.tkANY) && str != ANY.Name) ErrorReporter.WriteError(ErrorMessages.ANYCollision, rdec.Location); HashSet<string> Except = GetFIRST(trace, trace.Count - 1); foreach (string str in ANY.Except) Except.UnionWith(symbolTable.GetFIRST(str)); ANY.Except = Except; RuleDeclaration rd = new RuleDeclaration(); rd.Name = symbolTable.GetNewName("ANY"); ANY.Name = rd.Name; foreach (string str in symbolTable._tokens.Keys) if (!ANY.Except.Contains(str)) { List<SubRulePart> branch = new List<SubRulePart>(); branch.Add(new SubRulePart(str, true)); rd.SubRules.Add(branch); } symbolTable.AddRuleDeferred(rd); }
private void ReplaceUniformListsWithRules(List<SubRulePart> branch, string RuleName, LexLocation Location) { //перебираем все символы ветки, на скобках запускаем рекурсию for (int i = 0; i < branch.Count; ++i ) if (branch[i] is SubRuleComplexPart) foreach (List<SubRulePart> subBranch in (branch[i] as SubRuleComplexPart).Items) ReplaceUniformListsWithRules(subBranch, RuleName, Location); else if (branch[i] is SubRuleNonTermList) { SubRuleNonTermList NTList = branch[i] as SubRuleNonTermList; // Проверяем, первое ли это вхождение List в ветке правила if (!isFirstTimeListEntity) { ErrorReporter.WriteError(ErrorMessages.MultipleListsNotAllowed, Location, RuleName); return; } isFirstTimeListEntity = false; //проверяем отсутствие после него знаков повторения if (branch[i].Repetition != SubRuleRepetition.Once) { ErrorReporter.WriteError(ErrorMessages.RepetitionAfterListNotAllowed, Location, RuleName); return; } //проверяем первый параметр - должно быть имя правила if (symbolTable.FindRuleDescriptor(NTList.Name) == null) { ErrorReporter.WriteError(ErrorMessages.WrongFirstParamInList, Location, RuleName); return; } bool SeparatorEmpty = NTList.Separator == null || NTList.Separator == ""; //проверяем второй параметр - должен быть разделитель - строка или имя лексемы if (!SeparatorEmpty && !NTList.Separator.StartsWith("\"")) if (symbolTable.FindTokenList(NTList.Separator) == null) { ErrorReporter.WriteError(ErrorMessages.WrongFirstParamInList, Location, RuleName); return; } else NTList.Separator = symbolTable.FindTokenList(NTList.Separator).Values[0]; //строим новое правило RuleDeclaration newRule = new RuleDeclaration(); newRule.Name = symbolTable.GetNewName(RuleName + StringConstants.tkUniformSetSuffix); newRule.Location = Location; newRule.isActionGenerated = true; newRule.isGeneratedRule = true; newRule.UseRuleName = false; newRule.Type = StringConstants.SourceEntityUniformSetClassName; List<SubRulePart> Branch1 = new List<SubRulePart>(); List<SubRulePart> Branch2 = new List<SubRulePart>(); string action; string Sep1 = SeparatorEmpty ? "\"\"" : NTList.Separator; string ActionAddValPart = symbolTable.FindRuleDescriptor(NTList.Name).isGeneratedRule ? StringConstants.YActionAddValueAsList : StringConstants.YActionAddValue; if (NTList.CanBeEmpty) action = string.Format(StringConstants.YActionForSet1, StringConstants.SourceEntityUniformSetClassName, Sep1, Environment.NewLine, "true"); else { Branch1.Add(new SubRulePart(NTList.Name, true)); string act = string.Format(ActionAddValPart, "1") + string.Format(StringConstants.YActionAddName, "1"); action = string.Format(StringConstants.YActionForSet1, StringConstants.SourceEntityUniformSetClassName, Sep1, act + Environment.NewLine, "false"); } Branch1.Add(new SubRuleAction(action)); Branch2.Add(new SubRulePart(newRule.Name)); if (SeparatorEmpty) { action = string.Format(StringConstants.YActionForSet2, "2", string.Format(ActionAddValPart, "2")); } else { Branch2.Add(new SubRulePart(NTList.Separator)); action = string.Format(StringConstants.YActionForSet2, "3", string.Format(ActionAddValPart, "3")); } Branch2.Add(new SubRulePart(NTList.Name, true)); Branch2.Add(new SubRuleAction(action)); newRule.SubRules.Add(Branch1); newRule.SubRules.Add(Branch2); symbolTable.AddRuleDeferred(newRule); branch.RemoveAt(i); branch.Insert(i, new SubRulePart(newRule.Name)); branch[i].UseValue = true; branch[i].UseName = NTList.UseName; } }
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 }