Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ParserData.cs
Go to the documentation of this file.
1 #region License
2 /* **********************************************************************************
3  * Copyright (c) Roman Ivantsov
4  * This source code is subject to terms and conditions of the MIT License
5  * for Irony. A copy of the license can be found in the License.txt file
6  * at the root of this distribution.
7  * By using this source code in any fashion, you are agreeing to be bound by the terms of the
8  * MIT License.
9  * You must not remove this notice from this software.
10  * **********************************************************************************/
11 #endregion
12 
13 using System;
14 using System.Collections.Generic;
15 using System.Linq;
16 using System.Text;
17 
18 
19 namespace Irony.Parsing {
20  // ParserData is a container for all information used by CoreParser in input processing.
21  // ParserData is a field in LanguageData structure and is used by CoreParser when parsing intput.
22  // The state graph entry is InitialState state; the state graph encodes information usually contained
23  // in what is known in literature as transiton/goto tables.
24  // The graph is built from the language grammar by ParserBuilder.
25  // See "Parsing Techniques", 2nd edition for introduction to non-canonical parsing algorithms
26  using Irony.Parsing.Construction;
27  public class ParserData {
28  public readonly LanguageData Language;
30  public ParserStateTable InitialStates = new ParserStateTable(); //extra entries into automaton
32  public readonly ParserStateList States = new ParserStateList();
33  public ParserData(LanguageData language) {
34  Language = language;
35  }
36  }
37 
38  public class ParserState {
39  public readonly string Name;
40  public readonly ParserActionTable Actions = new ParserActionTable();
41  //Defined for states with a single reduce item; Parser.GetAction returns this action if it is not null.
43  //Expected terms contains terminals is to be used in
44  //Parser-advise-to-Scanner facility would use it to filter current terminals when Scanner has more than one terminal for current char,
45  // it can ask Parser to filter the list using the ExpectedTerminals in current Parser state.
46  public readonly TerminalSet ExpectedTerminals = new TerminalSet();
47  //Used for error reporting, we would use it to include list of expected terms in error message
48  // It is reduced compared to ExpectedTerms - some terms are "merged" into other non-terminals (with non-empty DisplayName)
49  // to make message shorter and cleaner. It is computed on-demand in CoreParser
51  internal ParserStateData BuilderData; //transient, used only during automaton construction and may be cleared after that
52 
53  public ParserState(string name) {
54  Name = name;
55  }
56  public void ClearData() {
57  BuilderData = null;
58  }
59  public override string ToString() {
60  return Name;
61  }
62  public override int GetHashCode() {
63  return Name.GetHashCode();
64  }
65 
66  }//class
67 
68  public class ParserStateList : List<ParserState> { }
69  public class ParserStateSet : HashSet<ParserState> { }
70  public class ParserStateHash : Dictionary<string, ParserState> { }
71  public class ParserStateTable : Dictionary<NonTerminal, ParserState> { }
72 
73  public enum ParserActionType {
74  Shift,
75  Reduce,
76  Operator, //shift or reduce depending on operator associativity and precedence
77  Code, //conflict resolution made in resolution method in grammar or in custom grammar hint;
78  Accept,
79  }
80 
81  public class ParserAction {
82  public ParserActionType ActionType {get;private set;}
83  public ParserState NewState {get;private set;} // for Shift action
84  public Production ReduceProduction {get;private set;} // for Reduce action
85  private Action<ConflictResolutionArgs> ConflictResolver {get;set;}
86 
87  internal ParserAction(ParserActionType actionType, ParserState newState, Production reduceProduction) {
88  this.ActionType = actionType;
89  this.NewState = newState;
90  this.ReduceProduction = reduceProduction;
91  this.ConflictResolver = null;
92  }
93 
94  internal ParserAction(ParserState newState, Production reduceProduction, Action<ConflictResolutionArgs> conflictResolver)
95  : this(ParserActionType.Code, newState, reduceProduction) {
96  ConflictResolver = conflictResolver;
97  }
98 
99  internal void ChangeToOperatorAction(Production reduceProduction) {
100  ActionType = ParserActionType.Operator;
101  ReduceProduction = reduceProduction;
102  }
103 
105  var args = new ConflictResolutionArgs(context, this);
106  // custom conflict resolver such as custom grammar hint has a higher priority than OnResolvingConflict handler
107  var resolver = ConflictResolver ?? grammar.OnResolvingConflict;
108  resolver(args);
109  return args;
110  }
111 
112  public override string ToString() {
113  switch (this.ActionType) {
114  case ParserActionType.Shift: return string.Format(Resources.LabelActionShift, NewState.Name);
115  case ParserActionType.Reduce: return string.Format(Resources.LabelActionReduce, ReduceProduction.ToStringQuoted());
116  case ParserActionType.Operator: return string.Format(Resources.LabelActionOp, NewState.Name, ReduceProduction.ToStringQuoted());
117  case ParserActionType.Accept: return Resources.LabelActionAccept;
118  }
119  return Resources.LabelActionUnknown; //should never happen
120  }
121  }//class ParserAction
122 
123  public class ParserActionTable : Dictionary<BnfTerm, ParserAction> { }
124 
125  [Flags]
126  public enum ProductionFlags {
127  None = 0,
128  HasTerminals = 0x02, //contains terminal
129  IsError = 0x04, //contains Error terminal
130  IsEmpty = 0x08,
131  //Indicates that it is a main production for list formation, in the form: "list->list+delim?+elem"
132  IsListBuilder = 0x10,
133  }
134 
135  public class Production {
137  public readonly NonTerminal LValue; // left-side element
138  public readonly BnfTermList RValues = new BnfTermList(); //the right-side elements sequence
139  internal readonly Construction.LR0ItemList LR0Items = new Construction.LR0ItemList(); //LR0 items based on this production
140 
141  public Production(NonTerminal lvalue) {
142  LValue = lvalue;
143  }//constructor
144 
145  public bool IsSet(ProductionFlags flag) {
146  return (Flags & flag) != ProductionFlags.None;
147  }
148 
149  public string ToStringQuoted() {
150  return "'" + ToString() + "'";
151  }
152  public override string ToString() {
153  return ProductionToString(this, -1); //no dot
154  }
155  public static string ProductionToString(Production production, int dotPosition) {
156  char dotChar = '\u00B7'; //dot in the middle of the line
157  StringBuilder bld = new StringBuilder();
158  bld.Append(production.LValue.Name);
159  bld.Append(" -> ");
160  for (int i = 0; i < production.RValues.Count; i++) {
161  if (i == dotPosition)
162  bld.Append(dotChar);
163  bld.Append(production.RValues[i].Name);
164  bld.Append(" ");
165  }//for i
166  if (dotPosition == production.RValues.Count)
167  bld.Append(dotChar);
168  return bld.ToString();
169  }
170 
171  }//Production class
172 
173  public class ProductionList : List<Production> { }
174 
175  /// <summary>
176  /// The class provides arguments for custom conflict resolution grammar method.
177  /// </summary>
179  public readonly ParsingContext Context;
180  public readonly Scanner Scanner;
181  public readonly ParserState NewShiftState;
182  //Results
183  public ParserActionType Result; //shift, reduce or operator
184  public Production ReduceProduction; //defaulted to
185  //constructor
186  internal ConflictResolutionArgs(ParsingContext context, ParserAction conflictAction) {
187  Context = context;
188  Scanner = Context.Parser.Scanner;
189  NewShiftState = conflictAction.NewState;
190  ReduceProduction = conflictAction.ReduceProduction;
191  Result = ParserActionType.Shift; //make shift by default
192  }
193  }//class
194 
195 
196 }//namespace
static string LabelActionShift
Looks up a localized string similar to Shift to {0}.
ParserState FinalState
Definition: ParserData.cs:31
readonly NonTerminal LValue
Definition: ParserData.cs:137
Production(NonTerminal lvalue)
Definition: ParserData.cs:141
override string ToString()
Definition: ParserData.cs:112
Scanner base class. The Scanner's function is to transform a stream of characters into aggregates/wor...
Definition: Scanner.cs:22
readonly string Name
Definition: ParserData.cs:39
Flags
Enumeration of the new Assimp's flags.
The class provides arguments for custom conflict resolution grammar method.
Definition: ParserData.cs:178
virtual ConflictResolutionArgs ResolveConflict(Grammar grammar, ParsingContext context)
Definition: ParserData.cs:104
readonly ParsingContext Context
Definition: ParserData.cs:179
ParserAction DefaultAction
Definition: ParserData.cs:42
StringSet ReportedExpectedSet
Definition: ParserData.cs:50
ParserData(LanguageData language)
Definition: ParserData.cs:33
static string LabelActionUnknown
Looks up a localized string similar to (Unknown action type).
readonly ParserState NewShiftState
Definition: ParserData.cs:181
Describes a language.
Definition: LanguageData.cs:23
ParserState InitialState
Definition: ParserData.cs:29
bool IsSet(ProductionFlags flag)
Definition: ParserData.cs:145
static string LabelActionOp
Looks up a localized string similar to Operator, shift to {0}/reduce on {1}..
static string LabelActionAccept
Looks up a localized string similar to Accept.
readonly BnfTermList RValues
Definition: ParserData.cs:138
ParserState(string name)
Definition: ParserData.cs:53
override int GetHashCode()
Definition: ParserData.cs:62
static string LabelActionReduce
Looks up a localized string similar to Reduce on {0}.
ProductionFlags Flags
Definition: ParserData.cs:136
override string ToString()
Definition: ParserData.cs:152
readonly LanguageData Language
Definition: ParserData.cs:28
static string ProductionToString(Production production, int dotPosition)
Definition: ParserData.cs:155
override string ToString()
Definition: ParserData.cs:59