Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
GrammarHint.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 namespace Irony.Parsing {
19 
20  public enum HintType {
21  /// <summary>
22  /// Instruction to resolve conflict to shift
23  /// </summary>
25  /// <summary>
26  /// Instruction to resolve conflict to reduce
27  /// </summary>
29  /// <summary>
30  /// Instruction to resolve the conflict using special code in grammar in OnResolvingConflict method.
31  /// </summary>
33  /// <summary>
34  /// Currently ignored by Parser, may be used in the future to set specific precedence value of the following terminal operator.
35  /// One example where it can be used is setting higher precedence value for unary + or - operators. This hint would override
36  /// precedence set for these operators for cases when they are used as unary operators. (YACC has this feature).
37  /// </summary>
38  Precedence,
39  /// <summary>
40  /// Provided for all custom hints that derived solutions may introduce
41  /// </summary>
42  Custom
43  }
44 
45 
46  public class GrammarHintList : List<GrammarHint> {
47 #if SILVERLIGHT
48  public delegate bool HintPredicate(GrammarHint hint);
49  public GrammarHint Find(HintPredicate match) {
50  foreach(var hint in this)
51  if (match(hint)) return hint;
52  return null;
53  }
54 #endif
55  }
56 
57  //Hints are additional instructions for parser added inside BNF expressions.
58  // Hint refers to specific position inside the expression (production), so hints are associated with LR0Item object
59  // One example is a conflict-resolution hint produced by the Grammar.PreferShiftHere() method. It tells parser to perform
60  // shift in case of a shift/reduce conflict. It is in fact the default action of LALR parser, so the hint simply suppresses the error
61  // message about the shift/reduce conflict in the grammar.
62  public class GrammarHint : BnfTerm {
63  public readonly HintType HintType;
64  public readonly object Data;
65 
66  public GrammarHint(HintType hintType, object data) : base("HINT") {
67  HintType = hintType;
68  Data = data;
69  }
70  } //class
71 
72  // Base class for custom grammar hints
73  public abstract class CustomGrammarHint : GrammarHint {
74  public ParserActionType Action { get; private set; }
75  public CustomGrammarHint(ParserActionType action) : base(HintType.Custom, null) {
76  Action = action;
77  }
78  public abstract bool Match(ConflictResolutionArgs args);
79  }
80 
81  // Semi-automatic conflict resolution hint
83  public int MaxPreviewTokens { get; set; } // preview limit
84  private string FirstString { get; set; }
85  private ICollection<string> OtherStrings { get; set; }
86  private Terminal FirstTerminal { get; set; }
87  private ICollection<Terminal> OtherTerminals { get; set; }
88 
89  private TokenPreviewHint(ParserActionType action) : base(action) {
90  FirstString = String.Empty;
91  OtherStrings = new HashSet<string>();
92  FirstTerminal = null;
93  OtherTerminals = new HashSet<Terminal>();
94  MaxPreviewTokens = 0;
95  }
96 
97  public TokenPreviewHint(ParserActionType action, string first) : this(action) {
98  FirstString = first;
99  }
100 
101  public TokenPreviewHint(ParserActionType action, Terminal first) : this(action) {
102  FirstTerminal = first;
103  }
104 
105  public TokenPreviewHint ComesBefore(params string[] others) {
106  Array.ForEach(others, term => OtherStrings.Add(term));
107  return this;
108  }
109 
110  public TokenPreviewHint ComesBefore(params Terminal[] others) {
111  Array.ForEach(others, term => OtherTerminals.Add(term));
112  return this;
113  }
114 
115  public TokenPreviewHint SetMaxPreview(int max) {
116  MaxPreviewTokens = max;
117  return this;
118  }
119 
120  public override void Init(GrammarData grammarData) {
121  base.Init(grammarData);
122  // convert strings to terminals, if needed
123  FirstTerminal = FirstTerminal ?? Grammar.ToTerm(FirstString);
124  if (OtherTerminals.Count == 0 && OtherStrings.Count > 0)
125  Array.ForEach(OtherStrings.Select(s => Grammar.ToTerm(s)).ToArray(), term => OtherTerminals.Add(term));
126  }
127 
128  public override bool Match(ConflictResolutionArgs args) {
129  try {
130  args.Scanner.BeginPreview();
131 
132  var count = 0;
133  var token = args.Scanner.GetToken();
134  while (token != null && token.Terminal != args.Context.Language.Grammar.Eof) {
135  if (token.Terminal == FirstTerminal)
136  {
137  args.Result = Action;
138  return true;
139  }
140  if (OtherTerminals.Contains(token.Terminal))
141  return false;
142  if (++count > MaxPreviewTokens && MaxPreviewTokens > 0)
143  return false;
144  token = args.Scanner.GetToken();
145  }
146  return false;
147  }
148  finally {
149  args.Scanner.EndPreview(true);
150  }
151  }
152  }
153 }
readonly HintType HintType
Definition: GrammarHint.cs:63
Instruction to resolve the conflict using special code in grammar in OnResolvingConflict method...
override void Init(GrammarData grammarData)
Definition: GrammarHint.cs:120
readonly object Data
Definition: GrammarHint.cs:64
TokenPreviewHint ComesBefore(params string[] others)
Definition: GrammarHint.cs:105
CustomGrammarHint(ParserActionType action)
Definition: GrammarHint.cs:75
TokenPreviewHint(ParserActionType action, string first)
Definition: GrammarHint.cs:97
Currently ignored by Parser, may be used in the future to set specific precedence value of the follow...
_In_ size_t count
Definition: DirectXTexP.h:174
The class provides arguments for custom conflict resolution grammar method.
Definition: ParserData.cs:178
TokenPreviewHint(ParserActionType action, Terminal first)
Definition: GrammarHint.cs:101
readonly ParsingContext Context
Definition: ParserData.cs:179
TokenPreviewHint SetMaxPreview(int max)
Definition: GrammarHint.cs:115
Instruction to resolve conflict to shift
Instruction to resolve conflict to reduce
TokenPreviewHint ComesBefore(params Terminal[] others)
Definition: GrammarHint.cs:110
function s(a)
readonly Terminal Eof
Definition: Grammar.cs:425
GrammarHint(HintType hintType, object data)
Definition: GrammarHint.cs:66
readonly LanguageData Language
override bool Match(ConflictResolutionArgs args)
Definition: GrammarHint.cs:128
Grammar Grammar
The linked Grammar
Definition: LanguageData.cs:35