Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
NonTerminal.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.Text;
16 using System.Reflection;
17 
18 namespace Irony.Parsing {
19 
20  internal class IntList : List<int> { }
21 
22  public class NonTerminal : BnfTerm {
23 
24  #region constructors
25  public NonTerminal(string name) : base(name, null) { } //by default display name is null
26  public NonTerminal(string name, string errorAlias) : base(name, errorAlias) { }
27  public NonTerminal(string name, string errorAlias, Type nodeType) : base(name, errorAlias, nodeType ) { }
28  public NonTerminal(string name, string errorAlias, AstNodeCreator nodeCreator) : base(name, errorAlias, nodeCreator) {}
29  public NonTerminal(string name, Type nodeType) : base(name, null, nodeType) { }
30  public NonTerminal(string name, AstNodeCreator nodeCreator) : base(name, null, nodeCreator) { }
31  public NonTerminal(string name, BnfExpression expression)
32  : this(name) {
33  Rule = expression;
34  }
35  #endregion
36 
37  #region properties/fields: Rule, ErrorRule
38 
40  //Separate property for specifying error expressions. This allows putting all such expressions in a separate section
41  // in grammar for all non-terminals. However you can still put error expressions in the main Rule property, just like
42  // in YACC
44 
45  //A template for representing ParseTreeNode in the parse tree. Can contain '#{i}' fragments referencing
46  // child nodes by index
47  public string NodeCaptionTemplate;
48  //Converted template with index list
49  private string _convertedTemplate;
50  private IntList _captionParameters;
51  #endregion
52 
53  #region overrides: ToString, Init
54  public override string ToString() {
55  return Name;
56  }
57  public override void Init(GrammarData grammarData) {
58  base.Init(grammarData);
59  if (!string.IsNullOrEmpty(NodeCaptionTemplate))
60  ConvertNodeCaptionTemplate();
61  if (TokenPreviewHint != null)
62  TokenPreviewHint.Init(grammarData);
63  }
64  #endregion
65 
66  #region data used by Parser builder
67  public readonly ProductionList Productions = new ProductionList();
68  #endregion
69 
70  #region custom grammar hints
72  internal void InsertCustomHints() {
73  if (TokenPreviewHint != null && Productions.Count > 0) {
74  foreach (var production in Productions) {
75  foreach (var lr0item in production.LR0Items) {
76  lr0item.Hints.Add(TokenPreviewHint);
77  }
78  }
79  }
80  }
81  public TokenPreviewHint ReduceIf(string first) {
82  return TokenPreviewHint = new TokenPreviewHint(ParserActionType.Reduce, first);
83  }
85  return TokenPreviewHint = new TokenPreviewHint(ParserActionType.Reduce, first);
86  }
87  public TokenPreviewHint ShiftIf(string first) {
88  return TokenPreviewHint = new TokenPreviewHint(ParserActionType.Shift, first);
89  }
91  return TokenPreviewHint = new TokenPreviewHint(ParserActionType.Shift, first);
92  }
93  #endregion
94 
95  public static string NonTerminalsToString(IEnumerable<NonTerminal> terms, string separator) {
96  var sb = new StringBuilder();
97  foreach (var term in terms) {
98  sb.Append(term.ToString());
99  sb.Append(separator);
100  }
101  return sb.ToString().Trim();
102  }
103 
104  #region NodeCaptionTemplate utilities
105  //We replace original tag '#{i}' (where i is the index of the child node to put here)
106  // with the tag '{k}', where k is the number of the parameter. So after conversion the template can
107  // be used in string.Format() call, with parameters set to child nodes captions
108  private void ConvertNodeCaptionTemplate() {
109  _captionParameters = new IntList();
110  _convertedTemplate = NodeCaptionTemplate;
111  var index = 0;
112  while(index < 100) {
113  var strParam = "#{" + index + "}";
114  if(_convertedTemplate.Contains(strParam)) {
115  _convertedTemplate = _convertedTemplate.Replace(strParam, "{" + _captionParameters.Count + "}");
116  _captionParameters.Add(index);
117  }
118  if (!_convertedTemplate.Contains("#{")) return;
119  index++;
120  }//while
121  }//method
122 
123  public string GetNodeCaption(ParseTreeNode node) {
124  var paramValues = new string[_captionParameters.Count];
125  for(int i = 0; i < _captionParameters.Count; i++) {
126  var childIndex = _captionParameters[i];
127  if(childIndex < node.ChildNodes.Count) {
128  var child = node.ChildNodes[childIndex];
129  //if child is a token, then child.ToString returns token.ToString which contains Value + Term;
130  // in this case we prefer to have Value only
131  paramValues[i] = (child.Token != null? child.Token.ValueString : child.ToString());
132  }
133  }
134  var result = string.Format(_convertedTemplate, paramValues);
135  return result;
136  }
137  #endregion
138 
139  }//class
140 
141  public class NonTerminalList : List<NonTerminal> {
142  public override string ToString() {
143  return NonTerminal.NonTerminalsToString(this, " ");
144  }
145  }
146 
147  public class NonTerminalSet : HashSet<NonTerminal> {
148  public override string ToString() {
149  return NonTerminal.NonTerminalsToString(this, " ");
150  }
151  }
152 
153 
154 }//namespace
override string ToString()
Definition: NonTerminal.cs:148
NonTerminal(string name, string errorAlias, Type nodeType)
Definition: NonTerminal.cs:27
override string ToString()
Definition: NonTerminal.cs:54
TokenPreviewHint ShiftIf(string first)
Definition: NonTerminal.cs:87
BnfExpression ErrorRule
Definition: NonTerminal.cs:43
TokenPreviewHint ReduceIf(string first)
Definition: NonTerminal.cs:81
NonTerminal(string name, AstNodeCreator nodeCreator)
Definition: NonTerminal.cs:30
delegate void AstNodeCreator(ParsingContext context, ParseTreeNode parseNode)
NonTerminal(string name)
Definition: NonTerminal.cs:25
static string NonTerminalsToString(IEnumerable< NonTerminal > terms, string separator)
Definition: NonTerminal.cs:95
NonTerminal(string name, BnfExpression expression)
Definition: NonTerminal.cs:31
ParseTreeNodeList ChildNodes
Definition: ParseTree.cs:41
TokenPreviewHint ShiftIf(Terminal first)
Definition: NonTerminal.cs:90
string GetNodeCaption(ParseTreeNode node)
Definition: NonTerminal.cs:123
override string ToString()
Definition: NonTerminal.cs:142
NonTerminal(string name, Type nodeType)
Definition: NonTerminal.cs:29
TokenPreviewHint ReduceIf(Terminal first)
Definition: NonTerminal.cs:84
NonTerminal(string name, string errorAlias, AstNodeCreator nodeCreator)
Definition: NonTerminal.cs:28
NonTerminal(string name, string errorAlias)
Definition: NonTerminal.cs:26
override void Init(GrammarData grammarData)
Definition: NonTerminal.cs:57