Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
IdentifierResolverHint.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Text.RegularExpressions;
5 
6 using Irony.Parsing;
7 
8 namespace SiliconStudio.Shaders.Grammar
9 {
10 
11  // Semi-automatic conflict resolution hint
13  {
14  private Func<ConflictResolutionArgs, bool> resolver;
15 
16 
17  public ResolveInCode(ParserActionType parserAction, Func<ConflictResolutionArgs, bool> resolver)
18  : base(parserAction)
19  {
20  this.resolver = resolver;
21  }
22 
23  public override bool Match(ConflictResolutionArgs args)
24  {
25  return resolver(args);
26  }
27  }
28 
29 
30 
31  // Semi-automatic conflict resolution hint
33  {
34  private bool isExpectingType;
35 
36  private CustomGrammarHint nextGrammarHint;
37 
38  public IdentifierResolverHint(bool isExpectingType, CustomGrammarHint nextGrammarHint = null)
39  : base(ParserActionType.Reduce)
40  {
41  this.isExpectingType = isExpectingType;
42  this.nextGrammarHint = nextGrammarHint;
43  }
44 
45  private string[] identifierPostFix = new string[] { "_OUTPUT", "OUT", "_INPUT", "IN", "OUTPUT_SCENE", "OUTPUT_SCENEENV", "PSSceneIn" };
46 
47  private Regex regex = new Regex("(.*\r?\n)");
48 
49  public override void Init(GrammarData grammarData)
50  {
51  base.Init(grammarData);
52  if (nextGrammarHint != null)
53  nextGrammarHint.Init(grammarData);
54  }
55 
56  public override bool Match(ConflictResolutionArgs args)
57  {
58  string identifier = args.Context.PreviousToken.Text;
59 
60  //var type = DeclarationManager.Instance.Find(args.Context, identifier);
61 
62  bool result;
63 
64  //if (type == DeclarationType.NotFound)
65  //{
66  result = false;
67  if (isExpectingType)
68  {
69  // We are probably in a type cast
70  if (args.Context.CurrentToken.Text == ")")
71  {
72  // Verify that next token is an identifier, a number or left parenthesis => Then the current expression is certainly a cast
73  args.Scanner.BeginPreview();
74  Token nextToken;
75  do
76  {
77  nextToken = args.Scanner.GetToken();
78  }
79  while (nextToken.Terminal.FlagIsSet(TermFlags.IsNonGrammar) && nextToken.Terminal != Grammar.Eof);
80 
81  var nextTokenName = nextToken.Terminal.Name;
82 
83  if (nextTokenName == "identifier" || nextTokenName == "integer_literal" || nextTokenName == "float_literal" || nextTokenName == "(")
84  result = true;
85  args.Scanner.EndPreview(true);
86  }
87  }
88 
89  if (!result && nextGrammarHint != null)
90  {
91  result = nextGrammarHint.Match(args);
92  }
93 
94  // In case that we found something, use the reduce production where this hint is used
95  if (result)
96  {
97  args.Result = ParserActionType.Reduce;
98  args.ReduceProduction = null;
99  }
100 
101  //} else if (isExpectingType)
102  // result = type == DeclarationType.TypeName;
103  //else
104  // result = type == DeclarationType.Variable;
105  return result;
106 
107  }
108  }
109 
110  // Semi-automatic conflict resolution hint
112  {
113  private TerminalSet skipTokens;
115  {
116  this.skipTokens = skipTokens;
117  }
118 
119  public override bool Match(ConflictResolutionArgs args)
120  {
121  if (args.Context.CurrentParserInput.Term.Name == "<")
122  {
123  args.Scanner.BeginPreview();
124  int ltCount = 0;
125  string previewSym;
126  bool isKeyword = false;
127  while (true)
128  {
129  // Find first token ahead (using preview mode) that is either end of generic parameter (">") or something else
130  Token preview;
131  do
132  {
133  preview = args.Scanner.GetToken();
134  }
135  while ((preview.Terminal.FlagIsSet(TermFlags.IsNonGrammar) || skipTokens.Contains(preview.Terminal)) && preview.Terminal != Grammar.Eof);
136 
137  isKeyword = preview.EditorInfo.Color == TokenColor.Keyword;
138 
139  // See what did we find
140  previewSym = preview.Terminal.Name;
141  if (previewSym == "<")
142  {
143  ltCount++;
144  }
145  else if (previewSym == ">" && ltCount > 0)
146  {
147  ltCount--;
148  }
149  else
150  break;
151  }
152  args.Scanner.EndPreview(true);
153 
154  // if we see ">", then it is type argument, not operator
155  // if previewSym == ">" then shift else reduce
156  if (previewSym == ">" || isKeyword)
157  {
158  args.Result = ParserActionType.Shift;
159  return true;
160  }
161  else
162  {
163  args.Result = ParserActionType.Reduce;
164  return true;
165  }
166  }
167  return false;
168  }
169 
170  }
171 }
override bool Match(ConflictResolutionArgs args)
string Text
Gets the text associated with this token.
Definition: Token.cs:145
The class provides arguments for custom conflict resolution grammar method.
Definition: ParserData.cs:178
bool FlagIsSet(TermFlags flag)
Definition: BnfTerm.cs:109
readonly ParsingContext Context
Definition: ParserData.cs:179
ResolveInCode(ParserActionType parserAction, Func< ConflictResolutionArgs, bool > resolver)
Terminal Terminal
Gets the terminal.
Definition: Token.cs:121
override bool Match(ConflictResolutionArgs args)
override bool Match(ConflictResolutionArgs args)
Tokens are produced by scanner and fed to parser, optionally passing through Token filters in between...
Definition: Token.cs:74
IdentifierResolverHint(bool isExpectingType, CustomGrammarHint nextGrammarHint=null)