Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
BnfTerm.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;
15 using System.Collections.Generic;
16 using System.Text;
17 using System.Reflection;
18 
19 namespace Irony.Parsing {
20  [Flags]
21  public enum TermFlags {
22  None = 0,
23  IsOperator = 0x01,
24  IsOpenBrace = 0x02,
25  IsCloseBrace = 0x04,
27  IsLiteral = 0x08,
28 
29  IsConstant = 0x10,
30  IsPunctuation = 0x20,
31  IsDelimiter = 0x40,
32  IsReservedWord = 0x080,
33  IsMemberSelect = 0x100,
34 
35  IsNonScanner = 0x01000, // indicates that tokens for this terminal are NOT produced by scanner
36  IsNonGrammar = 0x02000, // if set, parser would eliminate the token from the input stream; terms in Grammar.NonGrammarTerminals have this flag set
37  IsTransient = 0x04000, // Transient non-terminal - should be replaced by it's child in the AST tree.
38  IsNotReported = 0x08000, // Exclude from expected terminals list on syntax error
39 
40  //calculated flags
41  IsNullable = 0x010000,
42  IsVisible = 0x020000,
43  IsKeyword = 0x040000,
44  IsMultiline = 0x100000,
45  //internal flags
46  IsList = 0x200000,
47  IsListContainer = 0x400000,
48  //Indicates not to create AST node; mainly to suppress warning message on some special nodes that AST node type is not specified
49  //Automatically set by MarkTransient method
50  NoAstNode = 0x800000,
51  }
52 
53  public delegate void AstNodeCreator(ParsingContext context, ParseTreeNode parseNode);
54 
55  //Basic Backus-Naur Form element. Base class for Terminal, NonTerminal, BnfExpression, GrammarHint
56  public abstract class BnfTerm {
57  #region consructors
58  public BnfTerm(string name) : this(name, name) { }
59  public BnfTerm(string name, string errorAlias) {
60  Name = name;
61  ErrorAlias = errorAlias;
62  }
63  public BnfTerm(string name, string errorAlias, Type nodeType) : this(name, errorAlias) {
64  AstNodeType = nodeType;
65  }
66  public BnfTerm(string name, string errorAlias, AstNodeCreator nodeCreator) : this(name, errorAlias) {
67  AstNodeCreator = nodeCreator;
68  }
69  #endregion
70 
71 
72  #region virtuals and overrides
73  public virtual void Init(GrammarData grammarData) {
74  GrammarData = grammarData;
75  }
76 
77  public virtual string GetParseNodeCaption(ParseTreeNode node) {
78  if (GrammarData != null)
79  return GrammarData.Grammar.GetParseNodeCaption(node);
80  else
81  return Name;
82  }
83 
84  public override string ToString() {
85  return Name;
86  }
87 
88  public override int GetHashCode() {
89  if (Name == null) return 0;
90  return Name.GetHashCode();
91  }
92  #endregion
93 
94  public const int NoPrecedence = 0;
95 
96  #region properties: Name, DisplayName, Key, Options
97  public string Name;
98 
99  //ErrorAlias is used in error reporting, e.g. "Syntax error, expected <list-of-display-names>".
100  public string ErrorAlias;
101  public TermFlags Flags;
103  public int Precedence = NoPrecedence;
104  public Associativity Associativity = Associativity.Neutral;
105 
106  public Grammar Grammar {
107  get { return GrammarData.Grammar; }
108  }
109  public bool FlagIsSet(TermFlags flag) {
110  return (Flags & flag) != 0;
111  }
112  public void SetFlag(TermFlags flag) {
113  SetFlag(flag, true);
114  }
115  public void SetFlag(TermFlags flag, bool value) {
116  if (value)
117  Flags |= flag;
118  else
119  Flags &= ~flag;
120  }
121 
122  #endregion
123 
124  #region AST node creations: AstNodeType, AstNodeCreator, AstNodeCreated
125  public Type AstNodeType;
126  public object AstNodeConfig; //config data passed to AstNode
128  public event EventHandler<AstNodeEventArgs> AstNodeCreated;
129 
130  public virtual void CreateAstNode(ParsingContext context, ParseTreeNode nodeInfo) {
131  if (AstNodeCreator != null) {
132  AstNodeCreator(context, nodeInfo);
133  //We assume that Node creator method creates node and initializes it, so parser does not need to call
134  // IAstNodeInit.InitNode() method on node object.
135  return;
136  }
137  Type nodeType = GetAstNodeType(context, nodeInfo);
138  if (nodeType == null)
139  return; //we give a warning on grammar validation about this situation
140  nodeInfo.AstNode = Activator.CreateInstance(nodeType);
141  //Initialize node
142  var iInit = nodeInfo.AstNode as IAstNodeInit;
143  if (iInit != null)
144  iInit.Init(context, nodeInfo);
145  }
146 
147  //method may be overriden to provide node type different from this.AstNodeType. StringLiteral is overriding this method
148  // to use different node type for template strings
149  protected virtual Type GetAstNodeType(ParsingContext context, ParseTreeNode nodeInfo) {
150  return AstNodeType ?? Grammar.DefaultNodeType;
151  }
152 
153  protected internal void OnAstNodeCreated(ParseTreeNode parseNode) {
154  if (this.AstNodeCreated == null || parseNode.AstNode == null) return;
155  AstNodeEventArgs args = new AstNodeEventArgs(parseNode);
156  AstNodeCreated(this, args);
157  }
158  #endregion
159 
160 
161  #region Kleene operators: Q(), Plus(), Star()
162  NonTerminal _q, _plus, _star; //cash them
163  public NonTerminal Q()
164  {
165  if (_q != null)
166  return _q;
167  _q = new NonTerminal(this.Name + "?");
168  _q.Rule = this | Grammar.CurrentGrammar.Empty;
169  return _q;
170  }
171 
172  public NonTerminal Plus() {
173  if (_plus != null)
174  return _plus;
175  _plus = new NonTerminal(this.Name + "+");
176  _plus.Rule = Grammar.MakePlusRule(_plus, this);
177  return _plus;
178  }
179 
180  public NonTerminal Star()
181  {
182  if (_star != null) return _star;
183  _star = new NonTerminal(this.Name + "*");
184  _star.Rule = Grammar.MakeStarRule(_star, this);
185  return _star;
186  }
187  #endregion
188 
189  #region Operators: +, |, implicit
190  public static BnfExpression operator +(BnfTerm term1, BnfTerm term2) {
191  return Op_Plus(term1, term2);
192  }
193  public static BnfExpression operator +(BnfTerm term1, string symbol2) {
194  return Op_Plus(term1, Grammar.CurrentGrammar.ToTerm(symbol2));
195  }
196  public static BnfExpression operator +( string symbol1, BnfTerm term2) {
197  return Op_Plus(Grammar.CurrentGrammar.ToTerm(symbol1), term2);
198  }
199 
200  //Alternative
201  public static BnfExpression operator |(BnfTerm term1, BnfTerm term2) {
202  return Op_Pipe(term1, term2);
203  }
204  public static BnfExpression operator |(BnfTerm term1, string symbol2) {
205  return Op_Pipe(term1, Grammar.CurrentGrammar.ToTerm(symbol2));
206  }
207  public static BnfExpression operator |(string symbol1, BnfTerm term2) {
208  return Op_Pipe(Grammar.CurrentGrammar.ToTerm(symbol1), term2);
209  }
210 
211  //BNF operations implementation -----------------------
212  // Plus/sequence
213  internal static BnfExpression Op_Plus(BnfTerm term1, BnfTerm term2) {
214  //Check term1 and see if we can use it as result, simply adding term2 as operand
215  BnfExpression expr1 = term1 as BnfExpression;
216  if (expr1 == null || expr1.Data.Count > 1) //either not expression at all, or Pipe-type expression (count > 1)
217  expr1 = new BnfExpression(term1);
218  expr1.Data[expr1.Data.Count - 1].Add(term2);
219  return expr1;
220  }
221 
222  //Pipe/Alternative
223  //New version proposed by the codeplex user bdaugherty
224  internal static BnfExpression Op_Pipe(BnfTerm term1, BnfTerm term2) {
225  BnfExpression expr1 = term1 as BnfExpression;
226  if (expr1 == null)
227  expr1 = new BnfExpression(term1);
228  BnfExpression expr2 = term2 as BnfExpression;
229  if (expr2 == null)
230  expr2 = new BnfExpression(term2);
231  expr1.Data.AddRange(expr2.Data);
232  return expr1;
233  }
234 
235 
236  #endregion
237 
238  }//class
239 
240  public class BnfTermList : List<BnfTerm> { }
241  public class BnfTermSet : HashSet<BnfTerm> { }
242 
243  public class AstNodeEventArgs : EventArgs {
244  public AstNodeEventArgs(ParseTreeNode parseTreeNode) {
245  ParseTreeNode = parseTreeNode;
246  }
247  public readonly ParseTreeNode ParseTreeNode;
248  public object AstNode {
249  get { return ParseTreeNode.AstNode; }
250  }
251  }
252 
253 
254 
255 }//namespace
256 
BnfTerm(string name, string errorAlias)
Definition: BnfTerm.cs:59
BnfTerm(string name)
Definition: BnfTerm.cs:58
KeyTerm ToTerm(string text)
Definition: Grammar.cs:460
override string ToString()
Definition: BnfTerm.cs:84
Currently ignored by Parser, may be used in the future to set specific precedence value of the follow...
Flags
Enumeration of the new Assimp's flags.
delegate void AstNodeCreator(ParsingContext context, ParseTreeNode parseNode)
virtual void Init(GrammarData grammarData)
Definition: BnfTerm.cs:73
void SetFlag(TermFlags flag)
Definition: BnfTerm.cs:112
virtual Type GetAstNodeType(ParsingContext context, ParseTreeNode nodeInfo)
Definition: BnfTerm.cs:149
bool FlagIsSet(TermFlags flag)
Definition: BnfTerm.cs:109
EventHandler< AstNodeEventArgs > AstNodeCreated
Definition: BnfTerm.cs:128
BnfTerm(string name, string errorAlias, AstNodeCreator nodeCreator)
Definition: BnfTerm.cs:66
NonTerminal Star()
Definition: BnfTerm.cs:180
void SetFlag(TermFlags flag, bool value)
Definition: BnfTerm.cs:115
NonTerminal Q()
Definition: BnfTerm.cs:163
AstNodeCreator AstNodeCreator
Definition: BnfTerm.cs:127
virtual string GetParseNodeCaption(ParseTreeNode node)
Definition: BnfTerm.cs:77
static Grammar CurrentGrammar
Definition: Grammar.cs:488
BnfTerm(string name, string errorAlias, Type nodeType)
Definition: BnfTerm.cs:63
AstNodeEventArgs(ParseTreeNode parseTreeNode)
Definition: BnfTerm.cs:244
NonTerminal Plus()
Definition: BnfTerm.cs:172
override int GetHashCode()
Definition: BnfTerm.cs:88
readonly ParseTreeNode ParseTreeNode
Definition: BnfTerm.cs:247
GrammarData GrammarData
Definition: BnfTerm.cs:102
virtual void CreateAstNode(ParsingContext context, ParseTreeNode nodeInfo)
Definition: BnfTerm.cs:130