// Computes set of expected terms in a parser state. While there may be extended list of symbols expected at some point, // we want to reorganize and reduce it. For example, if the current state expects all arithmetic operators as an input, // it would be better to not list all operators (+, -, *, /, etc) but simply put "operator" covering them all. // To achieve this grammar writer can group operators (or any other terminals) into named groups using Grammar's methods // AddTermReportGroup, AddNoReportGroup etc. Then instead of reporting each operator separately, Irony would include // a single "group name" to represent them all. // The "expected report set" is not computed during parser construction (it would bite considerable time), but on demand during parsing, // when error is detected and the expected set is actually needed for error message. // Multi-threading concerns. When used in multi-threaded environment (web server), the LanguageData would be shared in // application-wide cache to avoid rebuilding the parser data on every request. The LanguageData is immutable, except // this one case - the expected sets are constructed late by CoreParser on the when-needed basis. // We don't do any locking here, just compute the set and on return from this function the state field is assigned. // We assume that this field assignment is an atomic, concurrency-safe operation. The worst thing that might happen // is "double-effort" when two threads start computing the same set around the same time, and the last one to finish would // leave its result in the state field. #endregion internal static StringSet ComputeGroupedExpectedSetForState(Grammar grammar, ParserState state) { var terms = new TerminalSet(); terms.UnionWith(state.ExpectedTerminals); var result = new StringSet(); //Eliminate no-report terminals foreach (var group in grammar.TermReportGroups) { if (group.GroupType == TermReportGroupType.Exclude) { terms.ExceptWith(group.Terminals); } } //Add normal and operator groups foreach (var group in grammar.TermReportGroups) { if (group.GroupType == TermReportGroupType.Normal || group.GroupType == TermReportGroupType.Operator && terms.Overlaps(group.Terminals)) { result.Add(group.Alias); terms.ExceptWith(group.Terminals); } } //Add remaining terminals "as is" foreach (var terminal in terms) { result.Add(terminal.ErrorAlias); } return(result); }
public TerminalSet GetReduceReduceConflicts() { var result = new TerminalSet(); result.UnionWith(Conflicts); result.ExceptWith(ShiftTerminals); return(result); }
public TerminalSet GetShiftReduceConflicts() { var result = new TerminalSet(); result.UnionWith(Conflicts); result.IntersectWith(ShiftTerminals); return(result); }
public TermReportGroup(string alias, TermReportGroupType groupType, IEnumerable <Terminal> terminals) { Alias = alias; GroupType = groupType; if (terminals != null) { Terminals.UnionWith(terminals); } }
public CustomParserAction(LanguageData language, ParserState state, ExecuteActionMethod executeRef) { Language = language; State = state; ExecuteRef = executeRef; Conflicts.UnionWith(state.BuilderData.Conflicts); // Create default shift and reduce actions foreach (var shiftItem in state.BuilderData.ShiftItems) { ShiftActions.Add(new ShiftParserAction(shiftItem)); } foreach (var item in state.BuilderData.ReduceItems) { ReduceActions.Add(ReduceParserAction.Create(item.Core.Production)); } }
public TokenPreviewHint(PreferredActionType actionType, Terminal thisTerm, params Terminal[] comesBefore) { _actionType = actionType; _firstTerminal = thisTerm; _beforeTerminals.UnionWith(comesBefore); }