//public abstract IDerivation Visit(QuantifiedPhrase aQuantifiedPhrase, DerivationContext aContext); public virtual IDerivation Visit(QuantifiedPhrase aQuantifiedPhrase, DerivationContext aContext) { if (aQuantifiedPhrase.IsConfigurable) { //читаем из xml List <string> lXmlPathList = aContext.DerivPath; NonTerminal lInnerSym = aQuantifiedPhrase.Phrase as NonTerminal; if (lInnerSym != null) { lXmlPathList.Add(lInnerSym.Text); } string[] lXmlPath = lXmlPathList.ToArray(); int lMin = Generator.ConfigXml.SearchInt(lXmlPath, "min"); int lMax = Generator.ConfigXml.SearchInt(lXmlPath, "max"); int lCount = Generator.ConfigXml.SearchInt(lXmlPath, "cnt"); if (lCount != -1) { return(ExpandInternal(aQuantifiedPhrase, lCount, lCount, aContext)); } if (lMin == -1) { lMin = (int)aQuantifiedPhrase.Min; } if (lMax == -1) { lMax = (int)aQuantifiedPhrase.Max; } return(ExpandInternal(aQuantifiedPhrase, lMin, lMax, aContext)); } return(ExpandInternal(aQuantifiedPhrase, (int)aQuantifiedPhrase.Min.Value, (int)aQuantifiedPhrase.Max.Value, aContext)); }
public override IDerivation Visit(QuantifiedPhrase aQuantifiedPhrase, DerivationContext aContext) { CyclesDetectContext context = aContext as CyclesDetectContext; aQuantifiedPhrase.Parent = context.Parent; CyclesDetectContext newContext = new CyclesDetectContext(aContext as CyclesDetectContext); newContext.Parent = aQuantifiedPhrase; return(base.Visit(aQuantifiedPhrase, newContext)); }
private static void ExpandPhrase(QuantifiedPhrase aQuantifiedPhrase, DerivationContext aContext, ListDerivation aList, int aRepeatCount) { if (aQuantifiedPhrase.Phrase is NonTerminal) { NonTerminal lThisSym = (NonTerminal)aQuantifiedPhrase.Phrase; NonTerminal lNewSymbol = new NonTerminal(lThisSym); //to del but i feel it will be neeeded lNewSymbol.OccurenceInSeq = aRepeatCount; aList.Add(lNewSymbol.Accept(aContext)); } else { aList.Add(aQuantifiedPhrase.Phrase.Accept(aContext)); } }
private IDerivation ExpandInternal(QuantifiedPhrase aQuantifiedPhrase, int aMin, int aMax, DerivationContext aContext) { //Квантификатор (QuantifiedPhrase) раскрывается так: // Phrase (это то, что под квантификатором, дублируемое выражение, например, "(a|b){2..5}" - phrase = (a|b)) // Phrase раскрывается n раз и добавляется в список ListDerivation (каждый раз результат может быть разнрый) // // {2..*} * => aMax == int.MaxValue // Если заданы минимум и максимум, напр. a{3..5}, то определяем рндэшно // добаку к минимуму (rest), в данном случае от 0 до 2 //А если максимум не задан (*), то 50% выход, 50% продолжение ListDerivation lList = new ListDerivation(true, aContext); int rest = 0; if (aMax != int.MaxValue) { rest = mRnd.Next(aMax - aMin + 1); } int i; for (i = 0; i < aMin + rest; i++) { ExpandPhrase(aQuantifiedPhrase, aContext, lList, i); } //есил phrase{5..*} генерим, пока не выпадет орел :) if (aMax == int.MaxValue) { while (mRnd.Next(2) >= 1) { ExpandPhrase(aQuantifiedPhrase, aContext, lList, i); i++; } } return(lList); }
public QuantifierControl(QuantifiedPhrase aQuantifiedPhrase, List <string> aOuterSymbols) : this() { _quantifiedPhrase = aQuantifiedPhrase; UIElement control = ControlFactory.CreateControl(_quantifiedPhrase.Phrase, aOuterSymbols); quantPanel.Children.Add(control); quantLabel.Content = _quantifiedPhrase.QuantSign; //if (_quantifiedPhrase.Min == _quantifiedPhrase.Max) //{ // quantLabel.Content = "{" + _quantifiedPhrase.Max + "}"; //} ////else if (_quantifiedPhrase.Max == Int32.MaxValue) ////{ //// quantLabel.Content = (_quantifiedPhrase.Min == 1) ? "+" : "*"; ////} //else //{ // string max = (_quantifiedPhrase.Max == Int32.MaxValue) ? "*" : _quantifiedPhrase.Max.ToString(); // quantLabel.Content = "{" + _quantifiedPhrase.Min + ".." + max + "}"; //} }
public virtual IDerivation Visit(Seqence aSeqence, DerivationContext aContext) { DictionaryDerivation lList = new DictionaryDerivation(aSeqence.InsertSpace, aContext); int lExprCnt = 1; for (int i = 0; i < aSeqence.Count; i++) { IPhrase lPhr = aSeqence.Phrases[i]; IDerivation lRes = lPhr.Accept(aContext); string lKeyName; NonTerminal lCurrentSymbol = lPhr as NonTerminal; QuantifiedPhrase lCurQuantPhr = lPhr as QuantifiedPhrase; if (null != lCurQuantPhr) { lCurrentSymbol = lCurQuantPhr.Phrase as NonTerminal; } if (lCurrentSymbol != null) { //to del lCurrentSymbol.OccurenceInSeq = i; lKeyName = lCurrentSymbol.Text; //взять протокол вывода этого правила //TODO: aContext.RuleSeqProtocol.Add(lCurrentSymbol.Text, lRes); //добавить в его протокол вывода последовательности имя lCurrentSymbol.Text и результат lRes } else { lKeyName = string.Format("Expr{0}", lExprCnt++); } if (!string.IsNullOrEmpty(lPhr.Alias)) { lKeyName = lPhr.Alias; } lList.Add(lKeyName, lRes, aContext); } return(lList); }
public virtual IDerivation Visit(QuantifiedPhrase aQuantifiedPhrase, DerivationContext aContext) { aQuantifiedPhrase.Phrase.Accept(NewContext(aQuantifiedPhrase, aContext)); return(null); }
/// Частное преобразование. Проверяет только правила состоящие из двух альтернатив. /// Находит правила вида /// S := A | A, S => A+ //шаблон (*1) /// S := A | S, A => A+ //шаблон (*1') /// B := A | A, S => A, [S] //шаблон (*2) /// B := A | S, A [S], A //шаблон (*2') /// и заменяет их на /// S := A+ // {1..*} /// B := A, [S] //{0..1} /// /// /// stats := stat | stat, Stats //Пример (*1) /// Exprs := Add | Add, Adds //Пример (*2) /// struct_declaration_list := struct_declaration\ //Пример (*1') /// | struct_declaration_list, struct_declaration private void StatStatsTransform() { foreach (Rule rule in mGrammar.Rules.Values) { AlternativeSet alt = rule.RightSide as AlternativeSet; if (alt != null) { if (alt.Phrases.Count == 2) { NonTerminal first_symbol_A = alt.Phrases[0] as NonTerminal; Seqence sequence = alt.Phrases[1] as Seqence; if (first_symbol_A != null && sequence != null && sequence.Phrases.Count == 2) { NonTerminal seq_symbol1 = sequence.Phrases[0] as NonTerminal; NonTerminal seq_symbol2 = sequence.Phrases[1] as NonTerminal; if (seq_symbol1 != null && seq_symbol2 != null) { NonTerminal seq_symbol_A = null; NonTerminal seq_symbol_S = null; int repl_i = 0; // Структура как нужно, теперь анализируем какие символы одинаковы? if (first_symbol_A.Text == seq_symbol1.Text) { seq_symbol_A = seq_symbol1; seq_symbol_S = seq_symbol2; repl_i = 1; } else if (first_symbol_A.Text == seq_symbol2.Text) { seq_symbol_A = seq_symbol2; seq_symbol_S = seq_symbol1; repl_i = 0; } if (seq_symbol_A != null) { string rule_before = rule.ToString(); if (rule.Name == seq_symbol_S.Text) { //Совпадение с шаблоном (*1) или (*1') найдено // создаем квантификатор вида {stat} QuantifiedPhrase quant = new QuantifiedPhrase(mGrammar, first_symbol_A, 1, Int32.MaxValue); // подменяем им правую часть rule.RightSide = quant; } else { //Совпадение с шаблоном (*2) или (*2') найдено // создаем квантификатор вида A? QuantifiedPhrase quant = new QuantifiedPhrase(mGrammar, seq_symbol_S, 0, 1); // подменяем альтернативу в правой части последовательностью rule.RightSide = sequence; // подменяем второй элемент последовательности квантификатором sequence.Phrases[repl_i] = quant; } mStatistics.AffectedRules.Add(rule.Name); mStatistics.Log(rule_before, rule.ToString()); } } } } //GeneralizedNonMandatryInclusion(alt); } } //foreach }
/// <summary> /// 1) Ищет совпадения в начале и в конце последовательностей. /// Если ничего не совпало выходим /// 2) Удаляем последовательность которая короче. Если Aj короче swap = true /// 3) Берем подпоследовательности Cp,Dq /// 4) Мастрячим замену - если D нету, квантификатор, иначе альтернативу /// </summary> /// <param name="Ai">B1,...,Bn,[D1,...,Dq],E1,...,Ek</param> /// <param name="Aj">B1,...,Bn, C1,...,Cp, E1,...,Ek</param> /// <param name="swap">true если удаляем Aj, а не Ai</param> /// <returns>B1,...,Bn, (C1,...,Cn)?, D1,...,Dn</returns> private Seqence FindNonMandatryInclusion(Seqence Ai, Seqence Aj, out bool swap) { // 1) Ищет совпадения в начале и в конце последовательностей. int start_len = 0; //FindEqualSeq(A1, A2, 1); int Ci = Ai.Phrases.Count - 1; int Cj = Aj.Phrases.Count - 1; while (start_len <= Ci && start_len <= Cj && Ai.Phrases[start_len] is NonTerminal && Aj.Phrases[start_len] is NonTerminal && Ai.Phrases[start_len].ToString() == Aj.Phrases[start_len].ToString() ) { start_len++; } int end_len = 0; //FindEqualSeq(A1, A2, -1); while (Ci >= start_len && Cj >= start_len && Ai.Phrases[Ci] is NonTerminal && Aj.Phrases[Cj] is NonTerminal && Ai.Phrases[Ci].ToString() == Aj.Phrases[Cj].ToString() ) { Ci--; Cj--; end_len++; } //Теперь у нас //start_len=n end_len=k // B1,...,Bn, D1,...,Dq, E1,...,Ek // B1,...,Bn, C1,...,Cp, E1,...,Ek // 2) Анализируем варианты swap = (Aj.Phrases.Count < Ai.Phrases.Count); //true Aj короче - ее и удалим if (start_len > 0 || end_len > 0) { if (swap) { Seqence At = Ai; Ai = Aj; Aj = At; } int sub_d_len = Ai.Phrases.Count - start_len - end_len; int sub_c_len = Aj.Phrases.Count - start_len - end_len; //Выделим D1,...,Dq из Ai Seqence sub_d = Ai.SubSequence(start_len, sub_d_len); //Выделим C1,...,Cp Seqence sub_c = Aj.SubSequence(start_len, sub_c_len); if (sub_c != null) { IPhrase replacement; if (sub_d != null) { // Альтернатива (D|C) if (sub_c.Count == 1 && sub_c.Phrases[0] is AlternativeSet) { (sub_c.Phrases[0] as AlternativeSet).Add(sub_d); return(Aj); } else if (sub_d.Count == 1 && sub_d.Phrases[0] is AlternativeSet) { (sub_d.Phrases[0] as AlternativeSet).Add(sub_c); swap = true; return(Ai); } else { replacement = new AlternativeSet(mGrammar, sub_d); (replacement as AlternativeSet).Phrases.Add(sub_c); } } else { // Необязательная C? replacement = new QuantifiedPhrase(mGrammar, sub_c, 0, 1); } return(ReplaceSubSequence(Aj, start_len, sub_c_len, replacement)); } else { throw new Exception( "FindNonMandatryInclusion. Подпоследовательность С нулевая. Такое может быть только если среди альтернатив две одинаковые последовательности, например S = A,B | A,B "); } } //иначе вообще нет совпадений return(null); }