public SyntaxNode(GrammarElement <T> value, SyntaxNode <T> parent) { Value = value; Parent = parent; ParentTree = parent.ParentTree; children = new List <SyntaxNode <T> >(); }
public InvalidParseTableException(ParseTableExceptionType exceptions, IParseTable <T> invalidTable, int state = -1, GrammarElement <T> nextInput = null) : base(createExceptionMsg(exceptions)) { ParseTable = invalidTable; State = state; NextInput = nextInput; }
public void ElementClick(GameObject elementButton) { GrammarElement currentElement = elements[elementButton]; if (currentProduction == null) { currentProduction = new GrammarProduction(null, new List <GrammarElement>()); } if (currentProduction.GetLeftSide() == null) { if (currentElement.IsNonTerminal()) { currentProduction.SetLeftSide(currentElement); } } else { currentProduction.GetRightSide().Add(currentElement); } if (!newProduction) { currentProductionButton.transform.parent.GetChild(1).GetComponentInChildren <Text>().text = GetProductionString(currentProduction); } currentProductionText.text = GetProductionString(currentProduction); }
private void FindNextOfEachNT(GrammarElement nonTerminal, GrammarElement guideNT, List <GrammarElement> seekedNt) { if (guideNT == productions[0].GetLeftSide()) { if (!nextOfEachNT[nonTerminal].Contains(endOfSequenceElemment)) { nextOfEachNT[nonTerminal].Add(endOfSequenceElemment); } } foreach (var production in productions) { for (var indexElement = 0; indexElement < production.GetRightSide().Count; indexElement++) { var elementGuide = production.GetRightSide()[indexElement]; if (elementGuide != guideNT) { continue; } for (var index = indexElement; index < production.GetRightSide().Count; index++) { var element = production.GetRightSide()[index]; if (index == production.GetRightSide().Count - 1) { if (!seekedNt.Contains(production.GetLeftSide())) { seekedNt.Add(production.GetLeftSide()); FindNextOfEachNT(nonTerminal, production.GetLeftSide(), seekedNt); } } if (index == indexElement) { continue; } if (element.IsNonTerminal()) { foreach (var tempVar in firstOfEachNT[element].Where(tempVar => !nextOfEachNT[nonTerminal].Contains(tempVar))) { nextOfEachNT[nonTerminal].Add(tempVar); } if (!voidableNT[element]) { break; } } else { if (!nextOfEachNT[nonTerminal].Contains(element)) { nextOfEachNT[nonTerminal].Add(element); } break; } } } } }
public void NewTerminal(Text text) { string symbol = text.text.ToLower(); if (!VerifyExistence(symbol)) { GrammarElement newNT = new GrammarElement(false, symbol); GameObject newNTButton = Instantiate(elementButton, TContainer.transform); newNTButton.transform.GetChild(0).GetComponent <Text>().text = symbol; elements.Add(newNTButton, newNT); } }
public void Lista_NaoPodeSerVazia() { var list = new GrammarElement[] { }; var ex = Assert.Throws <ArgumentException>( () => new OrListGrammarElement(list) ); Assert.Equal("list", ex.ParamName); Assert.Equal( "Argument list can not be empty", ex.Message.Split(new char[] { '\r', '\n' })[0] ); }
private void treeView2_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { TreeNode sel = treeView2.SelectedNode; if (!sel.Text.Equals("Grammar")) { try { textBox1.Text = "GrammarElement " + textBox1.Text + " = "; GrammarElement ge = grammar.Terminals[sel.Text]; propertyGrid2.SelectedObject = ge; } catch (Exception) { } } }
/// <summary> /// Constructor de la Clase Grammar /// </summary> /// <param name="productions"></param> /// <param name="nonTerminals"></param> public Grammar(List <GrammarProduction> productions, List <GrammarElement> nonTerminals) { endOfSequenceElemment = new GrammarElement(false, endOfSequence); this.productions = productions; this.nonTerminals = nonTerminals; GenerateNonTerminals(); Voidables(); GenerateFirstOfEachNT(); GenerateFirstOfEachProduction(); GenerateNextOfEachNT(); GenerateSelectionOfEachProduction(); IsSGrammar(); IsQGrammar(); IsSFGrammar(); IsLRGrammar(); IsLL1Grammar(); }
public void Evaluate() { if (this.productions.Count < 1) { ErrorMessage("Ninguna Producción"); return; } List <GrammarElement> nonTerminals = new List <GrammarElement>(); foreach (KeyValuePair <GameObject, GrammarProduction> production in this.productions) { GrammarElement currentElement = production.Value.GetLeftSide(); if (!nonTerminals.Contains(currentElement)) { nonTerminals.Add(currentElement); } } List <GrammarElement> currentList; foreach (KeyValuePair <GameObject, GrammarProduction> production in this.productions) { currentList = production.Value.GetRightSide(); foreach (GrammarElement element in currentList) { if (element.IsNonTerminal() && !nonTerminals.Contains(element)) { ErrorMessage("No existe una producción que defina a <" + element.GetSymbol() + ">"); return; } } } List <GrammarProduction> productions = new List <GrammarProduction>(); foreach (KeyValuePair <GameObject, GrammarProduction> production in this.productions) { productions.Add(production.Value); } SendGrammar(nonTerminals, productions); }
public ParserTransition(IntermediateParserState source, GrammarElement element, IntermediateParserState destination) { Source = source; Element = element; Destination = destination; }
public void SetLeftSide(GrammarElement leftSide) { this.leftSide = leftSide; }
/// <summary> /// Gets the action(s) given the current state and the next input. /// </summary> /// <param name="state"></param> /// <param name="nextInput"></param> /// <exception cref="System.ArgumentNullException" /> /// <returns> /// A array of ShiftActions if the operation is to move, ReduceActions if the operation is to Reduce, or AcceptActions /// if the parse is valid. /// Returns null if the action does not exist. /// </returns> public ParserAction <T>[] this[int currentState, GrammarElement <T> nextInput] { get { if (nextInput == null) { throw new ArgumentNullException("nextInput"); } if (nextInput is Terminal <T> ) { //if the given state is in the table if (ActionTable.ContainsKey(currentState)) { var actions = new List <ParserAction <T> >(); //if the next input is in the table if (ActionTable[currentState].ContainsKey((Terminal <T>)nextInput)) { Terminal <T> key = ActionTable[currentState].GetKey((Terminal <T>)nextInput); //if the stored column is not negated if (!key.Negated) { //return the action actions.AddRange(ActionTable[currentState][key].ToArray()); } } //Negated values will never match the end of input element if (!((Terminal <T>)nextInput).EndOfInput) { //Negated values act as an 'and' clause instead of an 'or' clause //input is not 'a' and input is not 'b', instead of input is not 'a' or input is not 'b' //If all of the negated keys do not equal the next input. if (ActionTable[currentState].All(a => (a.Key.Negated && !a.Key.Equals(nextInput)) || !a.Key.Negated)) { //if the state is contained in the table, and if there is a negated input element that does not match the given input //A Terminal with a null value that is negated will match anything except END_OF_INPUT. KeyValuePair <Terminal <T>, List <ParserAction <T> > > result = ActionTable[currentState].FirstOrDefault(a => a.Key.Negated && !a.Key.Equals(nextInput)); if (!result.Equals(default(KeyValuePair <Terminal <T>, List <ParserAction <T> > >))) { actions.AddRange(result.Value.ToArray()); } } } return(actions.ToArray()); } } else { //if the given state and next input are in the table if (GotoTable.ContainsKey(currentState) && GotoTable[currentState].ContainsKey((NonTerminal <T>)nextInput)) { //return a new shift action representing the goto movement. return(new[] { new ShiftAction <T>(this, GotoTable[currentState, (NonTerminal <T>)nextInput].Value) }); } } //the item does not exist in the table, return null. return(null); } }
public WhileGrammarElement(GrammarElement element) { _element = element ?? throw new ArgumentNullException(nameof(element)); }
public AnnotatedGrammarElement GetOrCreateAnnotatedElement(GrammarElement element, ParserTransition transition) { // Compute a hashcode for quick look up. int elementHash = element.GetHashCode(); int transitionHash = transition?.GetHashCode() ?? 0; AnnotatedGrammarElement annotatedElement = null; IDictionary<int, AnnotatedGrammarElement> annotatedElements; if (!_elementMapping.TryGetValue(elementHash, out annotatedElements) || !annotatedElements.TryGetValue(transitionHash, out annotatedElement)) { if (annotatedElements == null) _elementMapping.Add(elementHash, annotatedElements = new Dictionary<int, AnnotatedGrammarElement>()); annotatedElements.Add(transitionHash, annotatedElement = new AnnotatedGrammarElement(element, transition)); } return annotatedElement; }
protected static void ParseGrammarElement(ref Grammar.Grammar grammar, string line) { string backup = line; LiteralGrammarElement SymbolKeyword = new LiteralGrammarElement("GrammarElement "); if (SymbolKeyword.Validate(ref line, true).Result) { line = line.Trim(); string templine = line; SymbolSet AlphabetWithSpace = SymbolSet.FromType(SymbolSetPredefinedType.AlphaNumeric); AlphabetWithSpace.Add(new Symbol('_')); AlphabetWithSpace.Add(new Symbol('$')); AlphabetWithSpace.Add(new Symbol('/')); VariableLengthGrammarElement SymbolName = new VariableLengthGrammarElement(VariableLengthGrammarElementType.Plus, AlphabetWithSpace); if (SymbolName.Validate(ref line, true).Result) { string name = templine.Substring(0, templine.IndexOf(line)).Trim(); line = line.Trim(); LiteralGrammarElement EqualsSign = new LiteralGrammarElement("="); if (EqualsSign.Validate(ref line, true).Result) { line = line.Trim(); if (line.Contains(" or ") || line.Contains(" | ") || (line.Contains("precedence") && (line.Contains("Ascending") || line.Contains("Descending")))) { MultiParsePrecedenceType precedence = MultiParsePrecedenceType.Normal; if (line.IndexOf(',') >= 0) { string precedenceString = line.Substring(line.IndexOf(',') + 1).Trim(); line = line.Substring(0, line.IndexOf(',')).Trim(); LiteralGrammarElement precKey = new LiteralGrammarElement("precedence"); LiteralGrammarElement colon = new LiteralGrammarElement(":"); if (precKey.Validate(ref precedenceString, true).Result) { precedenceString = precedenceString.Trim(); if (colon.Validate(ref precedenceString, true).Result) { string[] precedenceList = Enum.GetNames(typeof(MultiParsePrecedenceType)); LiteralGrammarElement type = new LiteralGrammarElement(precedenceList); precedenceString = precedenceString.Trim(); if (type.Validate(ref precedenceString, false).Result) { precedence = (MultiParsePrecedenceType)Enum.Parse(typeof(MultiParsePrecedenceType), precedenceString); } } } } string[] terminals = line.Split(new string[] { " or ", " | " }, StringSplitOptions.RemoveEmptyEntries); MultiParseGrammarElement mpge = new MultiParseGrammarElement(); mpge.Precedence = precedence; int count = 0; foreach (string ss in terminals) { try { GrammarElement cge = ParseCGE(grammar, ss); if (cge.Name == null || cge.Name == "") { cge.Name = name + ":" + count++; } mpge.AddTerminal(cge); } catch (KeyNotFoundException k) { _temp.Add(backup); throw new InfinityGrammarScriptParseError("No such terminal to add to. " + k.Message, backup); } } grammar.AddTerminal(name, mpge); } else { string delimiters = " \n\r\t"; int idx = line.LastIndexOf(','); if (line.Substring(idx + 1).Trim().StartsWith("delimiters")) { delimiters = line.Substring(idx + 1).Trim(); line = line.Substring(0, idx); LiteralGrammarElement lge = new LiteralGrammarElement("delimiters"); if (lge.Validate(ref delimiters, true).Result) { delimiters = delimiters.Trim(); if (delimiters.StartsWith("[") && delimiters.EndsWith("]")) { delimiters = delimiters.Substring(1, delimiters.Length - 2); if (delimiters.Length == 0) { delimiters = "@None"; } } } else { throw new InfinityGrammarScriptParseError("Delimiters not declared properly - " + delimiters, backup); } } try { GrammarElement cge = ParseCGE(grammar, line, delimiters); grammar.AddTerminal(name, cge); } catch (KeyNotFoundException) { _temp.Add(backup); throw new InfinityGrammarScriptParseError("No such terminal to add to.", backup); } } } } } }
public ParserTransition GetOrCreateTransition(IntermediateParserState source, GrammarElement element, IntermediateParserState destination) { var transition = source.OutgoingTransitions.Values.FirstOrDefault(x => x.Destination == destination); if (transition == null) { transition = new ParserTransition(source, element, destination); source.OutgoingTransitions.Add(element, transition); destination.IncomingTransitions.Add(transition); } return transition; }
protected static void ParseMPGE(Grammar.Grammar grammar, string line) { string backup = line; LiteralGrammarElement SymbolKeyword = new LiteralGrammarElement("MultiGrammarElement "); if (SymbolKeyword.Validate(ref line, true).Result) { line = line.Trim(); string templine = line; SymbolSet AlphabetWithSpace = SymbolSet.FromType(SymbolSetPredefinedType.AlphaNumeric); AlphabetWithSpace.Add(new Symbol('_')); AlphabetWithSpace.Add(new Symbol('$')); AlphabetWithSpace.Add(new Symbol('/')); VariableLengthGrammarElement SymbolName = new VariableLengthGrammarElement(VariableLengthGrammarElementType.Plus, AlphabetWithSpace); if (SymbolName.Validate(ref line, true).Result) { string name = templine.Substring(0, templine.IndexOf(line)).Trim(); line = line.Trim(); LiteralGrammarElement EqualsSign = new LiteralGrammarElement("="); if (EqualsSign.Validate(ref line, true).Result) { line = line.Trim(); MultiParsePrecedenceType precedence = MultiParsePrecedenceType.Normal; if (line.LastIndexOf(',') >= 0) { string precedenceString = line.Substring(line.IndexOf(',') + 1).Trim(); line = line.Substring(0, line.IndexOf(',')).Trim(); LiteralGrammarElement precKey = new LiteralGrammarElement("precedence"); LiteralGrammarElement colon = new LiteralGrammarElement(":"); if (precKey.Validate(ref precedenceString, true).Result) { precedenceString = precedenceString.Trim(); if (colon.Validate(ref precedenceString, true).Result) { string[] precedenceList = Enum.GetNames(typeof(MultiParsePrecedenceType)); LiteralGrammarElement type = new LiteralGrammarElement(precedenceList); precedenceString = precedenceString.Trim(); if (type.Validate(ref precedenceString, false).Result) { precedence = (MultiParsePrecedenceType)Enum.Parse(typeof(MultiParsePrecedenceType), precedenceString); } else { throw new InfinityGrammarScriptParseError("Error", backup); } } else { throw new InfinityGrammarScriptParseError("Precedence is always followed by a Colon \":\"", backup); } } else { throw new InfinityGrammarScriptParseError("Invalid syntax. Only 'precedence' keyword allowed here", backup); } } string[] terminals = line.Split(new string[] { " or ", " | " }, StringSplitOptions.RemoveEmptyEntries); MultiParseGrammarElement mpge = new MultiParseGrammarElement(); mpge.Precedence = precedence; int count = 0; foreach (string ss in terminals) { try { GrammarElement cge = ParseCGE(grammar, ss); if (cge.Name == null || cge.Name == "") { cge.Name = name + ":" + count++; } mpge.AddTerminal(cge); } catch (KeyNotFoundException) { _temp.Add(backup); throw new InfinityGrammarScriptParseError("No such terminal to add to.", backup); } } grammar.AddTerminal(name, mpge); } else { throw new InfinityGrammarScriptParseError("MultiGrammarElement requires assignment after the name, missing '=' sign", backup); } } else { throw new InfinityGrammarScriptParseError("Check name", backup); } } else { throw new InfinityGrammarScriptParseError("Undetected error", backup); } }
public GrammarExpression(GrammarElement element) : this() { if (element != null) Switch[0].Add(element); }
public AnnotatedGrammarElement(GrammarElement element, ParserTransition transition) { Element = element; Transition = transition; Parents = new HashSet<AugmentedGrammarReduction>(); }
void Start() { elements = new Dictionary <GameObject, GrammarElement>(); this.productions = new Dictionary <GameObject, GrammarProduction>(); currentProduction = new GrammarProduction(null, new List <GrammarElement>()); GrammarElement A = new GrammarElement(true, "A"); GrammarElement B = new GrammarElement(true, "B"); GrammarElement C = new GrammarElement(true, "C"); GrammarElement D = new GrammarElement(true, "D"); GrammarElement E = new GrammarElement(true, "E"); GrammarElement a = new GrammarElement(false, "a"); GrammarElement b = new GrammarElement(false, "b"); GrammarElement c = new GrammarElement(false, "c"); GrammarElement d = new GrammarElement(false, "d"); GrammarElement e = new GrammarElement(false, "e"); GrammarElement f = new GrammarElement(false, "f"); GrammarProduction one = new GrammarProduction(A, new List <GrammarElement>() { a, B, C }); GrammarProduction two = new GrammarProduction(A, new List <GrammarElement>() { D, b, A }); GrammarProduction three = new GrammarProduction(B, new List <GrammarElement>() { }); GrammarProduction four = new GrammarProduction(B, new List <GrammarElement>() { b, A, B }); GrammarProduction five = new GrammarProduction(C, new List <GrammarElement>() { c, C }); GrammarProduction six = new GrammarProduction(C, new List <GrammarElement>() { D, d, B }); GrammarProduction seven = new GrammarProduction(D, new List <GrammarElement>() { }); GrammarProduction eight = new GrammarProduction(D, new List <GrammarElement>() { e, E }); GrammarProduction nine = new GrammarProduction(E, new List <GrammarElement>() { B, D }); GrammarProduction ten = new GrammarProduction(E, new List <GrammarElement>() { f }); List <GrammarProduction> productions = new List <GrammarProduction>() { one, two, three, four, five, six, seven, eight, nine, ten }; grammar = new Grammar(productions, new List <GrammarElement>() { A, B, C, D, E }); }
/// <summary> /// Busqueda recursiva de Primeros de cada Produccion de la Clase Grammar /// </summary> /// <param name="nonterminal"></param> /// <param name="production"></param> /// <param name="seekedNt"></param> /// <param name="index"></param> private void FindFirstOfEachNT(GrammarElement actualNt, int indexProduction, List <GrammarElement> seekedNt, int indexElement) { if (productions[indexProduction].GetRightSide().Count == 0) { return; } var firstOfRightSide = productions[indexProduction].GetRightSide()[indexElement]; if (!firstOfRightSide.IsNonTerminal()) { if (!firstOfEachNT[actualNt].Contains(firstOfRightSide)) { firstOfEachNT[actualNt].Add(firstOfRightSide); } } else { if (seekedNt.Contains(firstOfRightSide)) { return; } seekedNt.Add(firstOfRightSide); for (var index = 0; index < productions.Count; index++) { var production = productions[index]; if (production.GetLeftSide() == firstOfRightSide) { FindFirstOfEachNT(actualNt, index, seekedNt, 0); } } if (!voidableNT[firstOfRightSide]) { return; } var indexNextElement = indexElement + 1; if (indexNextElement < productions[indexProduction].GetRightSide().Count) { if (productions[indexProduction].GetRightSide()[indexNextElement].IsNonTerminal()) { if (seekedNt.Contains(productions[indexProduction].GetRightSide()[indexNextElement])) { return; } seekedNt.Add(productions[indexProduction].GetRightSide()[indexNextElement]); for (var index = 0; index < productions.Count; index++) { var production = productions[index]; if (production.GetLeftSide() == productions[indexProduction].GetRightSide()[indexNextElement]) { FindFirstOfEachNT(actualNt, index, seekedNt, 0); } } } else { if (!firstOfEachNT[actualNt].Contains(firstOfRightSide)) { firstOfEachNT[actualNt].Add(productions[indexProduction].GetRightSide()[indexElement + 1]); } } } else { for (var index = 0; index < productions.Count; index++) { var production = productions[index]; if (production.GetLeftSide() == productions[indexProduction].GetLeftSide()) { FindFirstOfEachNT(actualNt, index, seekedNt, indexElement + 1); } } } } }
public GrammarProduction(GrammarElement leftSide, List <GrammarElement> rightSide) { this.leftSide = leftSide; this.rightSide = rightSide; }
public GrammarRule(string name, GrammarElement element) { Name = name; Grammar = new [] { element }; Cardinality = 1; }
/// <summary> /// Sets the parse table that the parser uses with the given state graph used to help resolve parse table conflicts. /// </summary> /// <exception cref="Parser.Parsers.InvalidParseTableException"> /// Thrown when the given parse table contains either a 'Shift /// Reduce' conflict or a 'Reduce Reduce' conflict. /// </exception> /// <param name="value">The parse table to use for parsing</param> /// <param name="graph">The graph to use to return informative exceptions regarding conflicts.</param> public virtual void SetParseTable(ParseTable <T> value, StateGraph <GrammarElement <T>, LRItem <T>[]> graph) { if (value == null) { throw new ArgumentNullException("value"); } if (graph == null) { throw new ArgumentNullException("graph"); } foreach (var colRow in value.ActionTable.Select(a => { foreach (Terminal <T> b in a.Value.Keys) { return(new { Row = a, Column = b, Value = a.Value[b] }); } return(null); })) { //if we have a conflict if (colRow.Value.Count > 1) { var conflicts = new List <ParseTableConflict <T> >(); StateNode <GrammarElement <T>, LRItem <T>[]> node = graph.GetBreadthFirstTraversal().ElementAt(colRow.Row.Key); //ParseTableExceptionType exType; ////if we have a shift-reduce conflict if (colRow.Value.Any(a => a is ShiftAction <T>) && colRow.Value.Any(a => a is ReduceAction <T>)) { LRItem <T>[] items = node.Value.Where(a => { GrammarElement <T> e = a.GetNextElement(); if (e != null) { return(e.Equals(colRow.Column)); } return(false); }).Concat(colRow.Value.OfType <ReduceAction <T> >().Select(a => a.ReduceItem)).ToArray(); conflicts.Add(new ParseTableConflict <T>(ParseTableExceptionType.SHIFT_REDUCE, new ColumnRowPair <int, Terminal <T> >(colRow.Row.Key, colRow.Column), node, items)); //then check for a reduce-reduce conflict if (colRow.Value.Count(a => a is ReduceAction <T>) > 1) { items = colRow.Value.OfType <ReduceAction <T> >().Select(a => a.ReduceItem).ToArray(); conflicts.Add(new ParseTableConflict <T>(ParseTableExceptionType.REDUCE_REDUCE, new ColumnRowPair <int, Terminal <T> >(colRow.Row.Key, colRow.Column), node, items)); } } //otherwise we have a reduce-reduce conflict else { //get all of the reduce items LRItem <T>[] items = colRow.Value.OfType <ReduceAction <T> >().Select(a => a.ReduceItem).ToArray(); conflicts.Add(new ParseTableConflict <T>(ParseTableExceptionType.REDUCE_REDUCE, new ColumnRowPair <int, Terminal <T> >(colRow.Row.Key, colRow.Column), node, items)); } //throw invalid parse table exception throw new InvalidParseTableException <T>(value, node, conflicts.ToArray()); } } parseTable = value; SetEndOfInputFromTable(); }