public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) { if (delimiter == null) { listNonTerminal.Rule = listMember | listNonTerminal + listMember; } else { listNonTerminal.Rule = listMember | listNonTerminal + delimiter + listMember; } listNonTerminal.SetFlag(TermFlags.IsList); return(listNonTerminal.Rule); }
private void CollectTermsRecursive(BnfTerm term) { if (_grammarData.AllTerms.Contains(term)) { return; } _grammarData.AllTerms.Add(term); var nt = term as NonTerminal; if (nt == null) { return; } if (string.IsNullOrEmpty(nt.Name)) { if (!string.IsNullOrEmpty(nt.Rule?.Name)) { nt.Name = nt.Rule.Name; } else { nt.Name = "Unnamed" + _unnamedCount++; } } if (nt.Rule == null) { _language.Errors.AddAndThrow(GrammarErrorLevel.Error, null, Resources.ErrNtRuleIsNull, nt.Name); } //check all child elements foreach (var elemList in nt.Rule.Data) { for (var i = 0; i < elemList.Count; i++) { var child = elemList[i]; if (child == null) { _language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrRuleContainsNull, nt.Name, i); continue; } //Check for nested expression - convert to non-terminal if (child is BnfExpression expr) { child = new NonTerminal(null, expr); elemList[i] = child; } CollectTermsRecursive(child); } } }
public LRItemSet SelectByCurrent(BnfTerm current) { var result = new LRItemSet(); foreach (var item in this) { if (item.Core.Current == current) { result.Add(item); } } return(result); }
public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember, TermListOptions options) { bool allowTrailingDelimiter = (options & TermListOptions.AllowTrailingDelimiter) != 0; if (delimiter == null || !allowTrailingDelimiter) { return(MakePlusRule(listNonTerminal, delimiter, listMember)); } //create plus list var plusList = new NonTerminal(listMember.Name + "+"); plusList.Rule = MakePlusRule(listNonTerminal, delimiter, listMember); listNonTerminal.Rule = plusList | plusList + delimiter; listNonTerminal.SetFlag(TermFlags.IsListContainer); return(listNonTerminal.Rule); }
//Pipe/Alternative //New version proposed by the codeplex user bdaugherty internal static BnfExpression Op_Pipe(BnfTerm term1, BnfTerm term2) { BnfExpression expr1 = term1 as BnfExpression; if (expr1 == null) { expr1 = new BnfExpression(term1); } BnfExpression expr2 = term2 as BnfExpression; if (expr2 == null) { expr2 = new BnfExpression(term2); } expr1.Data.AddRange(expr2.Data); return(expr1); }
private ParserAction FindErrorShiftActionInStack(BnfTerm exitTerm) { while (Context.ParserStack.Count >= 1) { ParserAction errorShiftAction; if (Context.CurrentParserState.Actions.TryGetValue(exitTerm, out errorShiftAction)) { return(errorShiftAction); } //pop next state from stack if (Context.ParserStack.Count == 1) { return(null); //don't pop the initial state } Context.ParserStack.Pop(); Context.CurrentParserState = Context.ParserStack.Top.State; } return(null); }
protected BnfExpression MakeListRule(NonTerminal list, BnfTerm delimiter, BnfTerm listMember, TermListOptions options = TermListOptions.PlusList) { //If it is a star-list (allows empty), then we first build plus-list var isPlusList = !options.IsSet(TermListOptions.AllowEmpty); var allowTrailingDelim = options.IsSet(TermListOptions.AllowTrailingDelimiter) && delimiter != null; //"plusList" is the list for which we will construct expression - it is either extra plus-list or original list. // In the former case (extra plus-list) we will use it later to construct expression for list NonTerminal plusList = isPlusList ? list : new NonTerminal(listMember.Name + "+"); plusList.SetFlag(TermFlags.IsList); plusList.Rule = plusList; // rule => list if (delimiter != null) { plusList.Rule += delimiter; // rule => list + delim } if (options.IsSet(TermListOptions.AddPreferShiftHint)) { plusList.Rule += PreferShiftHere(); // rule => list + delim + PreferShiftHere() } plusList.Rule += listMember; // rule => list + delim + PreferShiftHere() + elem plusList.Rule |= listMember; // rule => list + delim + PreferShiftHere() + elem | elem if (isPlusList) { // if we build plus list - we're almost done; plusList == list // add trailing delimiter if necessary; for star list we'll add it to final expression if (allowTrailingDelim) { plusList.Rule |= list + delimiter; // rule => list + delim + PreferShiftHere() + elem | elem | list + delim } } else { // Setup list.Rule using plus-list we just created list.Rule = Empty | plusList; if (allowTrailingDelim) { list.Rule |= plusList + delimiter | delimiter; } plusList.SetFlag(TermFlags.NoAstNode); list.SetFlag(TermFlags.IsListContainer); //indicates that real list is one level lower } return(list.Rule); }//method
//Find an LR item without hints compatible with term (either shift on term or reduce with term as lookahead); // this item without hints would become our default. We assume that other items have hints, and when conditions // on all these hints fail, we chose this remaining item without hints. private ParserAction FindDefaultAction(ParserState state, BnfTerm term) { //First check reduce items var reduceItems = state.BuilderData.ReduceItems.SelectByLookahead(term as Terminal); foreach (var item in reduceItems) { if (item.Core.Hints.Count == 0) { return(ReduceParserAction.Create(item.Core.Production)); } } var shiftItem = state.BuilderData.ShiftItems.SelectByCurrent(term).FirstOrDefault(); if (shiftItem != null) { return(new ShiftParserAction(shiftItem)); } //if everything failed, returned first reduce item return(null); }
protected BnfExpression MakeListRule(NonTerminal list, BnfTerm delimiter, BnfTerm listMember, TermListOptions options = TermListOptions.PlusList) { //If it is a star-list (allows empty), then we first build plus-list var isStarList = options.IsSet(TermListOptions.AllowEmpty); NonTerminal plusList = isStarList ? new NonTerminal(listMember.Name + "+") : list; //"list" is the real list for which we will construct expression - it is either extra plus-list or original listNonTerminal. // In the latter case we will use it later to construct expression for listNonTerminal plusList.Rule = plusList; // rule => list if (delimiter != null) { plusList.Rule += delimiter; // rule => list + delim } if (options.IsSet(TermListOptions.AddPreferShiftHint)) { plusList.Rule += PreferShiftHere(); // rule => list + delim + PreferShiftHere() } plusList.Rule += listMember; // rule => list + delim + PreferShiftHere() + elem plusList.Rule |= listMember; // rule => list + delim + PreferShiftHere() + elem | elem //trailing delimiter if (options.IsSet(TermListOptions.AllowTrailingDelimiter) & delimiter != null) { plusList.Rule |= list + delimiter; // => list + delim + PreferShiftHere() + elem | elem | list + delim } // set Rule value plusList.SetFlag(TermFlags.IsList); //If we do not use exra list - we're done, return list.Rule if (plusList == list) { return(list.Rule); } // Let's setup listNonTerminal.Rule using plus-list we just created //If we are here, TermListOptions.AllowEmpty is set, so we have star-list list.Rule = Empty | plusList; plusList.SetFlag(TermFlags.NoAstNode); list.SetFlag(TermFlags.IsListContainer); //indicates that real list is one level lower return(list.Rule); }//method
public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember, TermListOptions options) { bool allowTrailingDelimiter = (options & TermListOptions.AllowTrailingDelimiter) != 0; if (delimiter == null) { //it is much simpler case listNonTerminal.SetFlag(TermFlags.IsList); listNonTerminal.Rule = _currentGrammar.Empty | listNonTerminal + listMember; return listNonTerminal.Rule; } //Note that deceptively simple version of the star-rule // Elem* -> Empty | Elem | Elem* + delim + Elem // does not work when you have delimiters. This simple version allows lists starting with delimiters - // which is wrong. The correct formula is to first define "Elem+"-list, and then define "Elem*" list // as "Elem* -> Empty|Elem+" NonTerminal plusList = new NonTerminal(listMember.Name + "+"); plusList.Rule = MakePlusRule(plusList, delimiter, listMember); plusList.SetFlag(TermFlags.NoAstNode); //to allow it to have AstNodeType not assigned if (allowTrailingDelimiter) listNonTerminal.Rule = _currentGrammar.Empty | plusList | plusList + delimiter; else listNonTerminal.Rule = _currentGrammar.Empty | plusList; listNonTerminal.SetFlag(TermFlags.IsListContainer); return listNonTerminal.Rule; }
public BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) { return(MakeListRule(listNonTerminal, delimiter, listMember)); }
public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm listMember) { return(MakePlusRule(listNonTerminal, null, listMember)); }
}//method private void ExecuteShiftTemp(BnfTerm term, ParserAction action) { Context.ParserStack.Push(new ParseTreeNode(term), action.NewState); Context.CurrentParserState = action.NewState; }
public BnfExpression(BnfTerm element) : this() { Data[0].Add(element); }
public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm listMember) { return MakeStarRule(listNonTerminal, null, listMember, TermListOptions.None); }
internal ParserState State; //used by parser to store current state when node is pushed into the parser stack public ParseTreeNode(BnfTerm term) { Term = term; }
public BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm listMember) { return(MakeListRule(listNonTerminal, null, listMember, TermListOptions.StarList)); }
public ShiftParserAction(BnfTerm term, ParserState newState) { Term = term; NewState = newState; }
public BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember, TermListOptions options) { return(MakeListRule(listNonTerminal, delimiter, listMember, options | TermListOptions.StarList)); }
public ParseTreeNode(NonTerminal term, SourceSpan span) : this() { Term = term; Span = span; }
public ParserState GetNextState(BnfTerm shiftTerm) { var shift = ShiftItems.FirstOrDefault(item => item.Core.Current == shiftTerm); return(shift?.ShiftedItem.State); }
public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) { return(MakeStarRule(listNonTerminal, delimiter, listMember, TermListOptions.None)); }
public ParseTreeNode(ParseTreeNode clone) : this(clone.State) { Term = clone.Term; Tokens = clone.Tokens; }