Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ShaderGrammar.Ast.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.Collections.Generic;
5 using System.Globalization;
6 
7 using Irony.Parsing;
8 using SiliconStudio.Shaders.Ast;
9 using SiliconStudio.Shaders.Ast.Hlsl;
10 using SiliconStudio.Shaders.Utility;
12 
13 namespace SiliconStudio.Shaders.Grammar
14 {
15  /// <summary>
16  /// Methods used to create the Abstract Syntax Tree..
17  /// </summary>
18  public abstract partial class ShaderGrammar
19  {
20  #region Methods
21 
22  /// <summary>
23  /// The ast.
24  /// </summary>
25  /// <param name="node">
26  /// </param>
27  /// <typeparam name="T">
28  /// </typeparam>
29  /// <returns>
30  /// </returns>
31  protected static T Ast<T>(ParseTreeNode node) where T : class, new()
32  {
33  T value = new T();
34  object obj = value;
35  node.AstNode = value;
36  if (value is Node)
37  {
38  ((Node)obj).Span = SpanConverter.Convert(node.Span);
39  }
40 
41  return value;
42  }
43 
44  /// <summary>
45  /// The ast composite enum.
46  /// </summary>
47  /// <param name="node">
48  /// </param>
49  /// <typeparam name="T">
50  /// </typeparam>
51  /// <returns>
52  /// </returns>
53  protected static T AstCompositeEnum<T>(ParseTreeNode node) where T : CompositeEnum, new()
54  {
55  var value = Ast<T>(node);
56  value.Key = string.Empty;
57  value.Values.Add(value);
58  return value;
59  }
60 
61  /// <summary>
62  /// The collect qualifiers.
63  /// </summary>
64  /// <param name="node">
65  /// </param>
66  /// <returns>
67  /// </returns>
68  protected static Qualifier CollectQualifiers(ParseTreeNode node)
69  {
70  var value = Qualifier.None;
71  foreach (var subNode in node.ChildNodes)
72  {
73  value |= (Qualifier)subNode.AstNode;
74  }
75 
76  if (value != Qualifier.None)
77  {
78  value.Span = SpanConverter.Convert(node.Span);
79  }
80 
81  return value;
82  }
83 
84  /// <summary>
85  /// The create array initializer expression ast.
86  /// </summary>
87  /// <param name="context">
88  /// </param>
89  /// <param name="node">
90  /// </param>
92  {
93  // [0] [1] [3]
94  // "{" + initializer_list + "}";
95  var value = Ast<ArrayInitializerExpression>(node);
96  value.Items = (List<Expression>)node.ChildNodes[1].AstNode;
97  }
98 
99  /// <summary>
100  /// The create assignement expression ast.
101  /// </summary>
102  /// <param name="parsingcontext">
103  /// </param>
104  /// <param name="node">
105  /// </param>
106  protected static void CreateAssignementExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
107  {
108  // [0] [1] [2]
109  // expression + operator + expression
110  var value = Ast<AssignmentExpression>(node);
111 
112  value.Target = GetExpression(node.ChildNodes[0]);
113  value.Operator = (AssignmentOperator)node.ChildNodes[1].AstNode;
114  value.Value = GetExpression(node.ChildNodes[2]);
115  }
116 
117  /// <summary>
118  /// Gets the expression.
119  /// </summary>
120  /// <param name="node">The node.</param>
121  /// <returns>An expression</returns>
122  protected static Expression GetExpression(ParseTreeNode node)
123  {
124  if (node.AstNode is Identifier)
125  {
126  return new VariableReferenceExpression((Identifier)node.AstNode) { Span = SpanConverter.Convert(node.Span) };
127  }
128 
129  return (Expression)node.AstNode;
130  }
131 
132  /// <summary>
133  /// The create assignment operator.
134  /// </summary>
135  /// <param name="parsingContext">
136  /// </param>
137  /// <param name="node">
138  /// </param>
139  protected static void CreateAssignmentOperator(ParsingContext parsingContext, ParseTreeNode node)
140  {
141  node.AstNode = AssignmentOperatorHelper.FromString(node.ChildNodes[0].Token.Text);
142  }
143 
144  /// <summary>
145  /// The create binary expression ast.
146  /// </summary>
147  /// <param name="parsingcontext">
148  /// </param>
149  /// <param name="node">
150  /// </param>
151  protected static void CreateBinaryExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
152  {
153  // [0] [1] [2]
154  // expression + operator + expression
155  var value = Ast<BinaryExpression>(node);
156 
157  value.Left = (Expression)node.ChildNodes[0].AstNode;
158  value.Operator = BinaryOperatorHelper.FromString(node.ChildNodes[1].Token.Text);
159  value.Right = (Expression)node.ChildNodes[2].AstNode;
160  }
161 
162  /// <summary>
163  /// The create block statement ast.
164  /// </summary>
165  /// <param name="context">
166  /// </param>
167  /// <param name="node">
168  /// </param>
169  protected static void CreateBlockStatementAst(ParsingContext context, ParseTreeNode node)
170  {
171  var value = Ast<BlockStatement>(node);
172 
173  // [0] [1] [2]
174  // "{" + block_item.Star() + "}";
175  FillListFromNodes(node.ChildNodes[1].ChildNodes, value.Statements);
176  }
177 
178  /// <summary>
179  /// The create case statement ast.
180  /// </summary>
181  /// <param name="context">
182  /// </param>
183  /// <param name="node">
184  /// </param>
185  protected static void CreateCaseStatementAst(ParsingContext context, ParseTreeNode node)
186  {
187  var caseStatement = Ast<CaseStatement>(node);
188 
189  //// switch_case_statement.Rule =
190  //// [0] [1]
191  //// "case" + constant_expression + ":"
192  //// | _("default") + ":";
193  if (node.ChildNodes.Count == 2)
194  {
195  caseStatement.Case = (Expression)node.ChildNodes[1].AstNode;
196  }
197  }
198 
199  /// <summary>
200  /// The create conditional expression ast.
201  /// </summary>
202  /// <param name="parsingcontext">
203  /// </param>
204  /// <param name="node">
205  /// </param>
206  protected static void CreateConditionalExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
207  {
208  var value = Ast<ConditionalExpression>(node);
209 
210  // [0] [1] [2] [3]
211  // logical_or_expression + "?" + expression + ":" + conditional_expression;
212  value.Condition = (Expression)node.ChildNodes[0].AstNode;
213  value.Left = (Expression)node.ChildNodes[2].AstNode;
214  value.Right = (Expression)node.ChildNodes[3].AstNode;
215  }
216 
217  /// <summary>
218  /// The create declaration specifier.
219  /// </summary>
220  /// <param name="context">
221  /// </param>
222  /// <param name="node">
223  /// </param>
224  protected static void CreateDeclarationSpecifier(ParsingContext context, ParseTreeNode node)
225  {
226  // declaration_specifiers =
227  // type
228  // | storage_qualifier.Plus() + type;
229  var storageQualifier = Qualifier.None;
230  TypeBase typeBase;
231  var i = 0;
232 
233  if (node.ChildNodes.Count == 2)
234  {
235  storageQualifier = CollectQualifiers(node.ChildNodes[0]);
236  i++;
237  }
238 
239  typeBase = (TypeBase)node.ChildNodes[i].AstNode;
240  node.AstNode = new Tuple<Qualifier, TypeBase>(storageQualifier, typeBase);
241  }
242 
243  /// <summary>
244  /// The create declaration statement ast.
245  /// </summary>
246  /// <param name="context">
247  /// </param>
248  /// <param name="node">
249  /// </param>
250  protected static void CreateDeclarationStatementAst(ParsingContext context, ParseTreeNode node)
251  {
252  var declarationStatement = Ast<DeclarationStatement>(node);
253  declarationStatement.Content = (Node)node.ChildNodes[0].AstNode;
254  }
255 
256  /// <summary>
257  /// The create do while statement ast.
258  /// </summary>
259  /// <param name="context">
260  /// </param>
261  /// <param name="node">
262  /// </param>
263  protected static void CreateDoWhileStatementAst(ParsingContext context, ParseTreeNode node)
264  {
265  var value = Ast<WhileStatement>(node);
266 
267  //// do_switch_statement.Rule =
268  //// [0] [1] [2] [3] [4]
269  //// _("do") + statement + "while" + "(" + expression + ")" + ";";
270  value.Condition = (Expression)node.ChildNodes[4].AstNode;
271  value.Statement = (Statement)node.ChildNodes[1].AstNode;
272  value.IsDoWhile = true;
273  }
274 
275  /// <summary>
276  /// The create expression or empty ast.
277  /// </summary>
278  /// <param name="context">
279  /// </param>
280  /// <param name="node">
281  /// </param>
282  protected static void CreateExpressionOrEmptyAst(ParsingContext context, ParseTreeNode node)
283  {
284  if (node.ChildNodes.Count == 1)
285  {
286  node.AstNode = node.ChildNodes[0].AstNode;
287  }
288 
289  if (node.AstNode == null)
290  {
291  Ast<EmptyExpression>(node);
292  }
293  }
294 
295  protected static void CreateEmptyStatementAst(ParsingContext context, ParseTreeNode node)
296  {
297  Ast<EmptyStatement>(node);
298  }
299 
300  /// <summary>
301  /// The create expression statement ast.
302  /// </summary>
303  /// <param name="context">
304  /// </param>
305  /// <param name="node">
306  /// </param>
307  protected static void CreateExpressionStatementAst(ParsingContext context, ParseTreeNode node)
308  {
309 
310  //// expression_statement.Rule =
311  //// empty_statement
312  //// | expression + ";";
313  if (node.ChildNodes[0].AstNode is EmptyStatement)
314  {
315  node.AstNode = node.ChildNodes[0].AstNode;
316  return;
317  }
318 
319  var expressionStatement = Ast<ExpressionStatement>(node);
320  if (node.ChildNodes[0].AstNode is Expression)
321  {
322  // Standard expression statement
323  expressionStatement.Expression = (Expression)node.ChildNodes[0].AstNode;
324  }
325  else
326  {
327  // Expression statement like "break;" "continue;" "discard;"
328  // Standard expression statement
329  CreateIdentifierAst(context, node.ChildNodes[0]);
330  expressionStatement.Expression = new KeywordExpression((Identifier)node.ChildNodes[0].AstNode) { Span = SpanConverter.Convert(node.Span) };
331  }
332  }
333 
334  /// <summary>
335  /// The create for statement ast.
336  /// </summary>
337  /// <param name="context">
338  /// </param>
339  /// <param name="node">
340  /// </param>
341  protected static void CreateForStatementAst(ParsingContext context, ParseTreeNode node)
342  {
343  var value = Ast<ForStatement>(node);
344 
345  //// for_statement.Rule = _
346  //// [0] [1] [2] [3] [4] [5] [6]
347  //// _("for") + "(" + expression_statement + expression.Q() + ";" + expression.Q() + ")" + statement
348  //// | _("for") + "(" + variable_declaration_raw + expression.Q() + ";" + expression.Q() + ")" + statement;
349  var start = (Node)node.ChildNodes[2].AstNode;
350  if (start is Variable)
351  {
352  value.Start = new DeclarationStatement { Content = start, Span = start.Span };
353  }
354  else
355  {
356  value.Start = (Statement)start;
357  }
358 
359  value.Condition = GetOptional<Expression>(node.ChildNodes[3]);
360  value.Next = GetOptional<Expression>(node.ChildNodes[4]);
361  value.Body = (Statement)node.ChildNodes[6].AstNode;
362  }
363 
364  /// <summary>
365  /// The create identifier ast.
366  /// </summary>
367  /// <param name="parsingcontext">
368  /// </param>
369  /// <param name="node">
370  /// </param>
371  protected static void CreateIdentifierAst(ParsingContext parsingcontext, ParseTreeNode node)
372  {
373  var nextNode = node;
374 
375  // Get the deepest valid node (either an AstNode or a Token)
376  while (nextNode.AstNode == null && nextNode.ChildNodes.Count > 0)
377  {
378  nextNode = nextNode.ChildNodes[0];
379  }
380 
381  node.AstNode = nextNode.AstNode as Identifier;
382 
383  // Handle special names (sample, point...)
384  if (node.AstNode == null)
385  {
386  var value = Ast<Identifier>(node);
387  value.Text = nextNode.Token.Text;
388  }
389  }
390 
391  /// <summary>
392  /// The create identifier indexable ast.
393  /// </summary>
394  /// <param name="parsingcontext">
395  /// </param>
396  /// <param name="node">
397  /// </param>
398  protected static void CreateIdentifierIndexableAst(ParsingContext parsingcontext, ParseTreeNode node)
399  {
400  // identifier + rankSpecifier.Star();
401  var value = Ast<Identifier>(node);
402  var identifier = (Identifier)node.ChildNodes[0].AstNode;
403  value.Text = identifier.Text;
404  value.Indices = new List<Expression>();
405  FillListFromNodes(node.ChildNodes[1].ChildNodes, value.Indices);
406  }
407 
408  /// <summary>
409  /// The create identifier list ast.
410  /// </summary>
411  /// <param name="parsingcontext">
412  /// </param>
413  /// <param name="node">
414  /// </param>
415  protected static void CreateIdentifierListAst(ParsingContext parsingcontext, ParseTreeNode node)
416  {
417  var identifiers = Ast<List<Identifier>>(node);
418  FillListFromNodes(node.ChildNodes, identifiers);
419  }
420 
421  /// <summary>
422  /// The create if statement ast.
423  /// </summary>
424  /// <param name="context">
425  /// </param>
426  /// <param name="node">
427  /// </param>
428  protected static void CreateIfStatementAst(ParsingContext context, ParseTreeNode node)
429  {
430  var value = Ast<IfStatement>(node);
431 
432  //// if_statement.Rule =
433  //// [0] [1] [2] [3] [4] [5] [6]
434  //// _("if") + "(" + expression + ")" + statement
435  ////| _("if") + "(" + expression + ")" + statement + PreferShiftHere() + "else" + statement;
436  value.Condition = (Expression)node.ChildNodes[2].AstNode;
437  value.Then = (Statement)node.ChildNodes[4].AstNode;
438  if (node.ChildNodes.Count == 7)
439  {
440  value.Else = (Statement)node.ChildNodes[6].AstNode;
441  }
442  }
443 
444  /// <summary>
445  /// The create indexer expression ast.
446  /// </summary>
447  /// <param name="parsingcontext">
448  /// </param>
449  /// <param name="node">
450  /// </param>
451  protected static void CreateIndexerExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
452  {
453  var value = Ast<IndexerExpression>(node);
454 
455  // [0] [1]
456  // postfix_expression + array_indexer
457  value.Target = (Expression)node.ChildNodes[0].AstNode;
458  value.Index = (Expression)node.ChildNodes[1].AstNode;
459  }
460 
461  /// <summary>
462  /// The create literal ast.
463  /// </summary>
464  /// <param name="context">
465  /// </param>
466  /// <param name="node">
467  /// </param>
468  protected static void CreateLiteralAst(ParsingContext context, ParseTreeNode node)
469  {
470  var literalValueNode = node.ChildNodes[0].AstNode;
471  if (literalValueNode is Literal)
472  {
473  node.AstNode = literalValueNode;
474  }
475  else
476  {
477  var value = Ast<Literal>(node);
478  value.Value = literalValueNode;
479  value.Text = GetTokenText(node.ChildNodes[0]);
480  }
481  }
482 
483  /// <summary>
484  /// The create literal expression ast.
485  /// </summary>
486  /// <param name="parsingcontext">
487  /// </param>
488  /// <param name="node">
489  /// </param>
490  protected static void CreateLiteralExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
491  {
492  var value = Ast<LiteralExpression>(node);
493  value.Literal = (Literal)node.ChildNodes[0].AstNode;
494  }
495 
496  /// <summary>
497  /// The create member reference expression ast.
498  /// </summary>
499  /// <param name="parsingcontext">
500  /// </param>
501  /// <param name="node">
502  /// </param>
503  protected static void CreateMemberReferenceExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
504  {
505  var value = Ast<MemberReferenceExpression>(node);
506 
507  // [0] [1] [2]
508  // postfix_expression + "." + identifier
509  value.Target = (Expression)node.ChildNodes[0].AstNode;
510  value.Member = (Identifier)node.ChildNodes[2].AstNode;
511  }
512 
513  /// <summary>
514  /// The create method declaration ast.
515  /// </summary>
516  /// <param name="context">
517  /// </param>
518  /// <param name="node">
519  /// </param>
520  protected static void CreateMethodDeclarationAst(ParsingContext context, ParseTreeNode node)
521  {
522  //// method_declaration_raw + ";";
523  node.AstNode = node.ChildNodes[0].AstNode;
524  }
525 
526  /// <summary>
527  /// The create method declaration raw ast.
528  /// </summary>
529  /// <param name="context">
530  /// </param>
531  /// <param name="node">
532  /// </param>
533  protected static void CreateMethodDeclarationRawAst(ParsingContext context, ParseTreeNode node)
534  {
535  //// method_declaration_raw.Rule =
536  //// [0] [1] [2] [3]
537  //// attribute_qualifier_pre + declaration_specifiers + method_declarator + method_qualifier_post;
538  var methodDeclaration = (MethodDeclaration)node.ChildNodes[2].AstNode;
539  node.AstNode = methodDeclaration;
540  methodDeclaration.Span = SpanConverter.Convert(node.Span);
541 
542  methodDeclaration.Attributes.AddRange((List<AttributeBase>)node.ChildNodes[0].AstNode);
543  var declarationSpecifiers = (Tuple<Qualifier, TypeBase>)node.ChildNodes[1].AstNode;
544  methodDeclaration.Qualifiers = declarationSpecifiers.Item1;
545  methodDeclaration.ReturnType = declarationSpecifiers.Item2;
546  methodDeclaration.Qualifiers |= (Qualifier)node.ChildNodes[3].AstNode;
547 
548  methodDeclaration.UpdateParameters();
549  }
550 
551  /// <summary>
552  /// The create method declarator ast.
553  /// </summary>
554  /// <param name="context">
555  /// </param>
556  /// <param name="node">
557  /// </param>
558  protected static void CreateMethodDeclaratorAst(ParsingContext context, ParseTreeNode node)
559  {
560  var methodDeclaration = Ast<MethodDeclaration>(node);
561 
562  //// method_declarator.Rule =
563  //// [0] [1] [2] [3]
564  //// identifier + "(" + parameter_list + ")"
565  ////| identifier + "(" + identifier_list + ")"
566  ////| identifier + "(" + "void" + ")"
567  ////| identifier + "(" + ")";
568  methodDeclaration.Name = (Identifier)node.ChildNodes[0].AstNode;
569  if (node.ChildNodes.Count == 4)
570  {
571  if (node.ChildNodes[2].AstNode is List<Parameter>)
572  {
573  methodDeclaration.Parameters = (List<Parameter>)node.ChildNodes[2].AstNode;
574  }
575  else if (node.ChildNodes[2].AstNode is List<Identifier>)
576  {
577  var identifiers = (List<Identifier>)node.ChildNodes[2].AstNode;
578  foreach (var identifier in identifiers)
579  {
580  methodDeclaration.Parameters.Add(new Parameter() { Name = identifier, Span = identifier.Span });
581  }
582  }
583  }
584  }
585 
586  /// <summary>
587  /// The create method definition ast.
588  /// </summary>
589  /// <param name="context">
590  /// </param>
591  /// <param name="node">
592  /// </param>
593  protected static void CreateMethodDefinitionAst(ParsingContext context, ParseTreeNode node)
594  {
595  //// method_definition.Rule =
596  //// [0] [1] [2] [3]
597  //// method_declaration_raw + "{" + block_item.ListOpt() + "}" + semi_opt;
598  var methodDefinition = Ast<MethodDefinition>(node);
599 
600  ((MethodDeclaration)node.ChildNodes[0].AstNode).CopyTo(methodDefinition);
601  methodDefinition.UpdateParameters();
602 
603  // [0] [1] [2]
604  // "{" + block_item.Star() + "}";
605  FillListFromNodes(node.ChildNodes[2].ChildNodes, methodDefinition.Body);
606  }
607 
608  /// <summary>
609  /// The create method invoke expression ast.
610  /// </summary>
611  /// <param name="parsingcontext">
612  /// </param>
613  /// <param name="node">
614  /// </param>
615  protected static void CreateMethodInvokeExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
616  {
617  var value = Ast<MethodInvocationExpression>(node);
618 
619  //// method_invoke_expression.Rule
620  // [0] [1] [2]
621  // = identifier + "(" + argument_expression_list.Q() + ")";
622  value.Target = GetExpression(node.ChildNodes[0]);
623 
624  var arguments = GetOptional<List<Expression>>(node.ChildNodes[2]);
625  if (arguments != null)
626  {
627  value.Arguments = arguments;
628  }
629  }
630 
631  /// <summary>
632  /// The create parameter ast.
633  /// </summary>
634  /// <param name="context">
635  /// </param>
636  /// <param name="node">
637  /// </param>
638  protected virtual void CreateParameterAst(ParsingContext context, ParseTreeNode node)
639  {
640  //// parameter_declaration.Rule =
641  //// [0] [1] [2] [3] [4]
642  //// attribute_qualifier_pre + parameter_qualifier_pre + parameter_type + indexable_identifier.Opt() + parameter_qualifier_post;
643  var parameter = Ast<Parameter>(node);
644 
645  parameter.Attributes.AddRange((List<AttributeBase>)node.ChildNodes[0].AstNode);
646  parameter.Type = (TypeBase)node.ChildNodes[2].AstNode;
647  parameter.Name = GetOptional<Identifier>(node.ChildNodes[3]);
648 
649  // If it is an identifier with indices, transform it to a plain identifier with an array type
650  if (parameter.Name != null && parameter.Name.HasIndices)
651  {
652  // base type of the array will be added by variable declaration
653  parameter.Type = new ArrayType { Dimensions = new List<Expression>(parameter.Name.Indices), Type = parameter.Type, Span = parameter.Name.Span };
654 
655  parameter.Name.Indices = null;
656  }
657  }
658 
659  /// <summary>
660  /// The create parenthesized expression ast.
661  /// </summary>
662  /// <param name="context">
663  /// </param>
664  /// <param name="node">
665  /// </param>
666  protected static void CreateParenthesizedExpressionAst(ParsingContext context, ParseTreeNode node)
667  {
668  var value = Ast<ParenthesizedExpression>(node);
669 
670  // [0] [1] [2]
671  // "(" + argument_expression_list + ")"
672  value.Content = (Expression)node.ChildNodes[1].AstNode;
673  }
674 
675  /// <summary>
676  /// The create postfix unary expression ast.
677  /// </summary>
678  /// <param name="context">
679  /// </param>
680  /// <param name="node">
681  /// </param>
682  protected static void CreatePostfixUnaryExpressionAst(ParsingContext context, ParseTreeNode node)
683  {
684  var value = Ast<UnaryExpression>(node);
685 
686  //// post_incr_decr_expression.Rule =
687  //// [0] [1]
688  //// postfix_expression + incr_or_decr;
689  value.Expression = (Expression)node.ChildNodes[0].AstNode;
690  var operatorText = node.ChildNodes[1].Token.Text;
691  value.Operator = (operatorText == "++") ? UnaryOperator.PostIncrement : UnaryOperator.PostDecrement;
692  }
693 
694  /// <summary>
695  /// The create qualifiers.
696  /// </summary>
697  /// <param name="context">
698  /// </param>
699  /// <param name="node">
700  /// </param>
701  protected static void CreateQualifiers(ParsingContext context, ParseTreeNode node)
702  {
703  var qualifier = node.ChildNodes.Count == 0 ? Qualifier.None : CollectQualifiers(node.ChildNodes[0]);
704  if (qualifier != Qualifier.None)
705  {
706  qualifier.Span = SpanConverter.Convert(node.Span);
707  }
708 
709  node.AstNode = qualifier;
710  }
711 
712  protected static void CreateQualifiersAst(ParsingContext context, ParseTreeNode node)
713  {
714  node.AstNode = CollectQualifiers(node.ChildNodes[0]);
715  }
716 
717  /// <summary>
718  /// The create rank specifier ast.
719  /// </summary>
720  /// <param name="parsingcontext">
721  /// </param>
722  /// <param name="node">
723  /// </param>
724  protected static void CreateRankSpecifierAst(ParsingContext parsingcontext, ParseTreeNode node)
725  {
726  // [0] [1] [2]
727  // "[" + expression + "]";
728  node.AstNode = node.ChildNodes[1].AstNode;
729  }
730 
731  /// <summary>
732  /// The create return statement ast.
733  /// </summary>
734  /// <param name="context">
735  /// </param>
736  /// <param name="node">
737  /// </param>
738  protected static void CreateReturnStatementAst(ParsingContext context, ParseTreeNode node)
739  {
740  var value = Ast<ReturnStatement>(node);
741 
742  //// _("return") + ";" | _("return") + expression + ";";
743  if (node.ChildNodes.Count == 2)
744  {
745  value.Value = (Expression)node.ChildNodes[1].AstNode;
746  }
747  }
748 
749  /// <summary>
750  /// The create shader ast.
751  /// </summary>
752  /// <param name="parsingcontext">
753  /// </param>
754  /// <param name="node">
755  /// </param>
756  protected static void CreateShaderAst(ParsingContext parsingcontext, ParseTreeNode node)
757  {
758  var value = Ast<Shader>(node);
759  // For top level node, embed it into a browsable node in order for Irony to browse it.
760  node.AstNode = new IronyBrowsableNode(value);
761  value.Declarations = (List<Node>)node.ChildNodes[0].AstNode;
762  }
763 
764  /// <summary>
765  /// The create statement ast.
766  /// </summary>
767  /// <param name="context">
768  /// </param>
769  /// <param name="node">
770  /// </param>
771  protected static void CreateStatementAst(ParsingContext context, ParseTreeNode node)
772  {
773  // statement.Rule =
774  // attribute_list_opt + statement_raw;
775  var value = (Statement)node.ChildNodes[1].AstNode;
776  node.AstNode = value;
777  value.Span = SpanConverter.Convert(node.Span);
778  value.Attributes = (List<AttributeBase>)node.ChildNodes[0].AstNode;
779  }
780 
781  /// <summary>
782  /// The create structure ast.
783  /// </summary>
784  /// <param name="parsingcontext">
785  /// </param>
786  /// <param name="node">
787  /// </param>
788  protected static void CreateStructureAst(ParsingContext parsingcontext, ParseTreeNode node)
789  {
790  var value = Ast<StructType>(node);
791 
792  //// struct_specifier.Rule =
793  //// [0] [1] [2] [3]
794  //// "struct" + identifier.Q() + "{" + variable_declaration.ListOpt() + "}"
795  value.Name = GetOptional<Identifier>(node.ChildNodes[1]);
796  FillListFromNodes(node.ChildNodes[3].ChildNodes, value.Fields);
797  }
798 
799  /// <summary>
800  /// The create switch cast group ast.
801  /// </summary>
802  /// <param name="context">
803  /// </param>
804  /// <param name="node">
805  /// </param>
806  protected static void CreateSwitchCastGroupAst(ParsingContext context, ParseTreeNode node)
807  {
808  var group = Ast<SwitchCaseGroup>(node);
809 
810  //// switch_case_group.Rule = switch_case_statement.Plus() + statement.Plus();
811  FillListFromNodes(node.ChildNodes[0].ChildNodes, group.Cases);
812  FillListFromNodes(node.ChildNodes[1].ChildNodes, group.Statements);
813  }
814 
815  /// <summary>
816  /// The create switch statement ast.
817  /// </summary>
818  /// <param name="context">
819  /// </param>
820  /// <param name="node">
821  /// </param>
822  protected static void CreateSwitchStatementAst(ParsingContext context, ParseTreeNode node)
823  {
824  var value = Ast<SwitchStatement>(node);
825 
826  //// switch_statement.Rule =
827  //// [0] [1] [2] [3] [4] [5] [6]
828  //// _("switch") + "(" + expression + ")" + "{" + switch_case_group.Star() + "}";
829  value.Condition = (Expression)node.ChildNodes[2].AstNode;
830  FillListFromNodes(node.ChildNodes[5].ChildNodes, value.Groups);
831  }
832 
833  /// <summary>
834  /// The create type name ast.
835  /// </summary>
836  /// <param name="parsingcontext">
837  /// </param>
838  /// <param name="node">
839  /// </param>
840  protected static void CreateTypeNameAst(ParsingContext parsingcontext, ParseTreeNode node)
841  {
842  var value = Ast<TypeName>(node);
843  value.Name = (Identifier)node.ChildNodes[0].AstNode;
844  }
845 
846  /// <summary>
847  /// The create type name from token ast.
848  /// </summary>
849  /// <param name="parsingcontext">
850  /// </param>
851  /// <param name="node">
852  /// </param>
853  protected static void CreateTypeNameFromTokenAst(ParsingContext parsingcontext, ParseTreeNode node)
854  {
855  CreateTypeFromTokenAst<TypeName>(parsingcontext, node);
856  }
857 
858  protected static void CreateTypeFromTokenAst<T>(ParsingContext parsingcontext, ParseTreeNode node) where T : TypeBase, new()
859  {
860  if (node.ChildNodes.Count == 1 && node.ChildNodes[0].AstNode is T)
861  {
862  node.AstNode = node.ChildNodes[0].AstNode;
863  }
864  else
865  {
866  var value = Ast<T>(node);
867  var nextNode = node;
868  while (nextNode.Token == null)
869  {
870  nextNode = nextNode.ChildNodes[0];
871  }
872 
873  value.Name = new Identifier(nextNode.Token.Text) { Span = SpanConverter.Convert(node.Span) };
874  }
875  }
876 
877  /// <summary>
878  /// The create unary expression ast.
879  /// </summary>
880  /// <param name="parsingcontext">
881  /// </param>
882  /// <param name="node">
883  /// </param>
884  protected static void CreateUnaryExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
885  {
886  var value = Ast<UnaryExpression>(node);
887 
888  //// unary_expression_raw.Rule =
889  //// [0] [1] [0] [1]
890  //// incr_or_decr + unary_expression | unary_operator + cast_expression;
891  value.Operator = UnaryOperatorHelper.FromString(node.ChildNodes[0].Token.Text);
892  value.Expression = (Expression)node.ChildNodes[1].AstNode;
893  }
894 
895  /// <summary>
896  /// Creates the variable group ast.
897  /// </summary>
898  /// <param name="parsingContext">
899  /// The parsing context.
900  /// </param>
901  /// <param name="node">
902  /// The tree node.
903  /// </param>
904  protected static void CreateVariableGroupAst(ParsingContext parsingContext, ParseTreeNode node)
905  {
906  // variable_group.Rule =
907  // [0] [1]
908  // attribute_qualifier_pre + variable_group_raw
909 
910  // This is a type declaration and not a variable
911  if (node.ChildNodes[1].AstNode is TypeBase)
912  {
913  var typeBase = (TypeBase)node.ChildNodes[1].AstNode;
914  var attributes = (List<AttributeBase>)node.ChildNodes[0].AstNode;
915  typeBase.Attributes = attributes;
916  node.AstNode = typeBase;
917  }
918  else
919  {
920  // else this is a standard variable declaration.
921  var var = (Variable)node.ChildNodes[1].AstNode;
922  var.Attributes.AddRange((List<AttributeBase>)node.ChildNodes[0].AstNode);
923  node.AstNode = var;
924  }
925  }
926 
927  /// <summary>
928  /// The create variable group raw ast.
929  /// </summary>
930  /// <param name="parsingContext">
931  /// </param>
932  /// <param name="node">
933  /// </param>
934  protected static void CreateVariableGroupRawAst(ParsingContext parsingContext, ParseTreeNode node)
935  {
936  var var = Ast<Variable>(node);
937 
938  //// [0] [1]
939  // declaration_specifiers + variable_declarator_list.Q() + ";";
940  var declarationSpecifiers = (Tuple<Qualifier, TypeBase>)node.ChildNodes[0].AstNode;
941  var.Qualifiers = declarationSpecifiers.Item1;
942  var.Type = declarationSpecifiers.Item2;
943 
944  var declarators = GetOptional<List<Variable>>(node.ChildNodes[1]);
945 
946  if (declarators != null)
947  {
948  var.SubVariables = declarators;
949 
950  // Update array type for sub variables
951  foreach(var subVariable in declarators)
952  {
953  if (subVariable.Type is ArrayType)
954  ((ArrayType)subVariable.Type).Type = var.Type;
955  else
956  subVariable.Type = var.Type;
957  }
958  }
959 
960  // If this is a variable group, check if we can transform it to a single variable declaration.
961  if (var.IsGroup)
962  {
963  // If the variable is a single variable declaration, replace the group
964  if (var.SubVariables.Count == 1)
965  {
966  var subVariable = var.SubVariables[0];
967  subVariable.MergeFrom(var);
968  node.AstNode = subVariable;
969  }
970  }
971  else
972  {
973  // If variable declarators is 0, check if this is a named struct
974  var.Type.Qualifiers = var.Qualifiers;
975  if (var.Type is StructType)
976  {
977  node.AstNode = var.Type;
978  }
979  else if (var.Type is InterfaceType)
980  {
981  node.AstNode = var.Type;
982  }
983  else if (var.Type is ClassType)
984  {
985  node.AstNode = var.Type;
986  }
987  else
988  {
989  parsingContext.AddParserError("Expecting identifier for variable declaration [{0}]", var.Type);
990  }
991 
992  if (var.Type.Name == null)
993  {
994  parsingContext.AddParserError("Cannot declare anonymous type at the top level");
995  }
996  }
997  }
998 
999  /// <summary>
1000  /// The create while statement ast.
1001  /// </summary>
1002  /// <param name="context">
1003  /// </param>
1004  /// <param name="node">
1005  /// </param>
1006  protected static void CreateWhileStatementAst(ParsingContext context, ParseTreeNode node)
1007  {
1008  var value = Ast<WhileStatement>(node);
1009 
1010  //// switch_statement.Rule =
1011  //// [0] [1] [2] [3] [4]
1012  //// _("while") + "(" + expression + ")" + statement;
1013  value.Condition = (Expression)node.ChildNodes[2].AstNode;
1014  value.Statement = (Statement)node.ChildNodes[4].AstNode;
1015  }
1016 
1017  /// <summary>
1018  /// The create float literal.
1019  /// </summary>
1020  /// <param name="context">
1021  /// </param>
1022  /// <param name="node">
1023  /// </param>
1024  protected void CreateFloatLiteral(ParsingContext context, ParseTreeNode node)
1025  {
1026  var literalFloat = Ast<Literal>(node);
1027  float value;
1028  var floatStr = node.Token.Text;
1029  bool isHalf = floatStr.EndsWith("h", StringComparison.CurrentCultureIgnoreCase);
1030 
1031  // Remove postfix
1032  if (floatStr.EndsWith("d", StringComparison.CurrentCultureIgnoreCase)
1033  || floatStr.EndsWith("f", StringComparison.CurrentCultureIgnoreCase)
1034  || isHalf)
1035  {
1036  floatStr = floatStr.Substring(0, floatStr.Length - 1);
1037  }
1038 
1039  if (!float.TryParse(
1040  floatStr,
1041  NumberStyles.Float,
1042  CultureInfo.InvariantCulture,
1043  out value))
1044  {
1045  context.AddParserError("Unable to parse float [{0}]", node.Token.Text);
1046  }
1047 
1048  literalFloat.Value = value;
1049  literalFloat.Text = node.Token.Text;
1050 
1051  // Don't output half
1052  // TODO MOVE THIS TO GLSL WRITER
1053  if (isHalf)
1054  {
1055  literalFloat.Text = floatStr;
1056  }
1057  }
1058 
1059  /// <summary>
1060  /// The create integer literal.
1061  /// </summary>
1062  /// <param name="context">
1063  /// </param>
1064  /// <param name="node">
1065  /// </param>
1066  protected void CreateIntegerLiteral(ParsingContext context, ParseTreeNode node)
1067  {
1068  var literalInt = Ast<Literal>(node);
1069  int value = 0;
1070  bool isOctal = false;
1071  var intStr = node.Token.Text;
1072  var style = NumberStyles.Integer;
1073 
1074  // Remove post-fix
1075  if (intStr.EndsWith("l", StringComparison.CurrentCultureIgnoreCase))
1076  {
1077  intStr = intStr.Substring(0, intStr.Length - 1);
1078  }
1079 
1080  // Check for Hexa decimal
1081  if (intStr.StartsWith("0x", StringComparison.CurrentCultureIgnoreCase))
1082  {
1083  intStr = intStr.Substring(2);
1084  style = NumberStyles.HexNumber;
1085  }
1086  else if (intStr.StartsWith("0") && intStr.Length > 1)
1087  {
1088  // Else parse Octal
1089  isOctal = true;
1090  try
1091  {
1092  value = Convert.ToInt32(intStr, 8);
1093  }
1094  catch (FormatException)
1095  {
1096  context.AddParserError("Unable to parse octal number [{0}]", node.Token.Text);
1097  }
1098  }
1099 
1100  // If on octal, parse regular hexa
1101  if (!isOctal && !int.TryParse(
1102  intStr,
1103  style,
1104  CultureInfo.InvariantCulture,
1105  out value))
1106  {
1107  context.AddParserError("Unable to parse integer [{0}]", node.Token.Text);
1108  }
1109 
1110  literalInt.Value = value;
1111  literalInt.Text = node.Token.Text;
1112  }
1113 
1114  /// <summary>
1115  /// The create storage qualifier.
1116  /// </summary>
1117  /// <param name="context">
1118  /// </param>
1119  /// <param name="node">
1120  /// </param>
1121  protected virtual void CreateStorageQualifier(ParsingContext context, ParseTreeNode node)
1122  {
1123  var qualifier = Qualifier.None;
1124  if (node.ChildNodes.Count == 1)
1125  {
1126  qualifier = Shaders.Ast.StorageQualifier.Parse(node.ChildNodes[0].Token.Text);
1127  qualifier.Span = SpanConverter.Convert(node.Span);
1128  }
1129 
1130  node.AstNode = qualifier;
1131  }
1132 
1133  /// <summary>
1134  /// The create variable declarator ast.
1135  /// </summary>
1136  /// <param name="parsingcontext">
1137  /// </param>
1138  /// <param name="node">
1139  /// </param>
1140  protected virtual void CreateVariableDeclaratorAst(ParsingContext parsingcontext, ParseTreeNode node)
1141  {
1142  var value = (Variable)node.ChildNodes[0].AstNode;
1143  node.AstNode = value;
1144 
1145  //// variable_declarator.Rule =
1146  //// [0] [1] [2]
1147  //// variable_declarator_raw
1148  ////| variable_declarator_raw + "=" + initializer;
1149 
1150  // Get initial value
1151  if (node.ChildNodes.Count == 3)
1152  {
1153  value.InitialValue = (Expression)node.ChildNodes[2].AstNode;
1154  }
1155  }
1156 
1157  /// <summary>
1158  /// The create variable declarator raw ast.
1159  /// </summary>
1160  /// <param name="parsingcontext">
1161  /// </param>
1162  /// <param name="node">
1163  /// </param>
1164  protected virtual void CreateVariableDeclaratorRawAst(ParsingContext parsingcontext, ParseTreeNode node)
1165  {
1166  var value = Ast<Variable>(node);
1167 
1168  //// variable_declarator_raw.Rule =
1169  //// [0] [1]
1170  //// indexable_identifier_declarator + variable_declarator_qualifier_post
1171  var identifier = (Identifier)node.ChildNodes[0].AstNode;
1172 
1173  // Get modifiers
1174  value.Qualifiers = (Qualifier)node.ChildNodes[1].AstNode;
1175 
1176  value.Name = identifier;
1177 
1178  // If it is an identifier with indices, transform it to a plain identifier with an array type
1179  if (identifier.HasIndices)
1180  {
1181  // base type of the array will be added by variable declaration
1182  value.Type = new ArrayType { Dimensions = new List<Expression>(identifier.Indices), Span = identifier.Span };
1183  identifier.Indices = null;
1184  }
1185  }
1186 
1187  private static void CheckFieldDeclarationAst(ParsingContext context, ParseTreeNode node)
1188  {
1189  //// field_declaration.Rule =
1190  //// [0] [1] [2]
1191  //// field_qualifier_pre + type + variable_declarator_list + ";";
1192  // Check that field has a declarator
1193 
1194  // If field declaration is a type, then this is an error
1195  if (node.ChildNodes[0].AstNode is TypeBase)
1196  {
1197  var typeBase = (TypeBase)node.ChildNodes[0].AstNode;
1198  var baseTypeSpan = typeBase.Span;
1199  var location = ((Irony.Parsing.IBrowsableAstNode)typeBase).Location;
1200  location.Position += baseTypeSpan.Length;
1201 
1202  context.AddParserMessage(ParserErrorLevel.Error, location, "Field declaration must contain an identifier");
1203  return;
1204  }
1205 
1206  var var = (Variable)node.ChildNodes[0].AstNode;
1207  node.AstNode = var;
1208 
1209  // Check that declarator doesn't contain initial values
1210  foreach (var variableDeclarator in var.Instances())
1211  {
1212  if (variableDeclarator.InitialValue != null)
1213  {
1214  context.AddParserMessage(
1215  ParserErrorLevel.Error, ((Irony.Parsing.IBrowsableAstNode)variableDeclarator.InitialValue).Location, "Field declaration cannot contain an initial value");
1216  }
1217  }
1218  }
1219 
1220  private static void CreateVariableReferenceExpressionAst(ParsingContext context, ParseTreeNode node)
1221  {
1222  //// variable_identifier.Rule = identifier;
1223  var value = Ast<VariableReferenceExpression>(node);
1224 
1225  value.Name = (Identifier)node.ChildNodes[0].AstNode;
1226  }
1227  #endregion
1228 
1229  private static void CreateTypeReferenceExpression(ParsingContext context, ParseTreeNode node)
1230  {
1231  //// variable_identifier.Rule = identifier;
1232  var value = Ast<TypeReferenceExpression>(node);
1233 
1234  value.Type = (TypeBase)node.ChildNodes[0].AstNode;
1235  }
1236 
1237  private static void CreateExpressionListAst(ParsingContext context, ParseTreeNode node)
1238  {
1239  //// expression.Rule =
1240  //// [0] [1] [2]
1241  //// assignment_expression
1242  //// | expression + "," + assignment_expression;
1243 
1244  if (node.ChildNodes.Count == 1)
1245  {
1246  node.AstNode = node.ChildNodes[0].AstNode;
1247  }
1248  else
1249  {
1250  var value = Ast<ExpressionList>(node);
1251  FillListFromNodes(node.ChildNodes, value);
1252  }
1253  }
1254  }
1255 }
Methods used to create the Abstract Syntax Tree..
static void CreateTypeNameAst(ParsingContext parsingcontext, ParseTreeNode node)
The create type name ast.
static void CreateTypeNameFromTokenAst(ParsingContext parsingcontext, ParseTreeNode node)
The create type name from token ast.
static void CreateParenthesizedExpressionAst(ParsingContext context, ParseTreeNode node)
The create parenthesized expression ast.
static void CreateVariableGroupAst(ParsingContext parsingContext, ParseTreeNode node)
Creates the variable group ast.
static void CreateIdentifierAst(ParsingContext parsingcontext, ParseTreeNode node)
The create identifier ast.
static BinaryOperator FromString(string operatorStr)
Converts from string an operator.
static Qualifier CollectQualifiers(ParseTreeNode node)
The collect qualifiers.
virtual void CreateStorageQualifier(ParsingContext context, ParseTreeNode node)
The create storage qualifier.
static void CreateMethodDeclarationAst(ParsingContext context, ParseTreeNode node)
The create method declaration ast.
SourceSpan Span
Gets or sets the source span.
Definition: Node.cs:37
static void CreateShaderAst(ParsingContext parsingcontext, ParseTreeNode node)
The create shader ast.
static void CreateIfStatementAst(ParsingContext context, ParseTreeNode node)
The create if statement ast.
static void CreateMethodInvokeExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
The create method invoke expression ast.
Keyword expression statement like continue; break; discard;
static void CreateEmptyStatementAst(ParsingContext context, ParseTreeNode node)
static void CreateRankSpecifierAst(ParsingContext parsingcontext, ParseTreeNode node)
The create rank specifier ast.
static void CreateArrayInitializerExpressionAst(ParsingContext context, ParseTreeNode node)
The create array initializer expression ast.
static void CreateMethodDefinitionAst(ParsingContext context, ParseTreeNode node)
The create method definition ast.
SiliconStudio.Shaders.Ast.StorageQualifier StorageQualifier
static void CreateDeclarationSpecifier(ParsingContext context, ParseTreeNode node)
The create declaration specifier.
void CreateFloatLiteral(ParsingContext context, ParseTreeNode node)
The create float literal.
static void CreateUnaryExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
The create unary expression ast.
static SourceLocation Convert(Irony.Parsing.SourceLocation sourceLocation)
static void CreateMethodDeclarationRawAst(ParsingContext context, ParseTreeNode node)
The create method declaration raw ast.
AssignmentOperator
Assignment operator used in assignment expression (a = b) or statements (a = b;)
static void CreateAssignmentOperator(ParsingContext parsingContext, ParseTreeNode node)
The create assignment operator.
static void CreatePostfixUnaryExpressionAst(ParsingContext context, ParseTreeNode node)
The create postfix unary expression ast.
static void CreateMethodDeclaratorAst(ParsingContext context, ParseTreeNode node)
The create method declarator ast.
Abstract node.
Definition: Node.cs:15
void CreateIntegerLiteral(ParsingContext context, ParseTreeNode node)
The create integer literal.
static Expression GetExpression(ParseTreeNode node)
Gets the expression.
static void CreateVariableGroupRawAst(ParsingContext parsingContext, ParseTreeNode node)
The create variable group raw ast.
virtual void CreateParameterAst(ParsingContext context, ParseTreeNode node)
The create parameter ast.
static void CreateDoWhileStatementAst(ParsingContext context, ParseTreeNode node)
The create do while statement ast.
static void CreateStatementAst(ParsingContext context, ParseTreeNode node)
The create statement ast.
static void CreateIdentifierListAst(ParsingContext parsingcontext, ParseTreeNode node)
The create identifier list ast.
static void CreateLiteralAst(ParsingContext context, ParseTreeNode node)
The create literal ast.
static void CreateCaseStatementAst(ParsingContext context, ParseTreeNode node)
The create case statement ast.
A variable declaration.
Definition: Variable.cs:11
Base root class for all statements.
Definition: Statement.cs:11
A single parameter declaration.
Definition: Parameter.cs:10
static void CreateIdentifierIndexableAst(ParsingContext parsingcontext, ParseTreeNode node)
The create identifier indexable ast.
ParseTreeNodeList ChildNodes
Definition: ParseTree.cs:41
static void CreateConditionalExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
The create conditional expression ast.
static void CreateSwitchStatementAst(ParsingContext context, ParseTreeNode node)
The create switch statement ast.
static void CreateWhileStatementAst(ParsingContext context, ParseTreeNode node)
The create while statement ast.
static void CreateStructureAst(ParsingContext parsingcontext, ParseTreeNode node)
The create structure ast.
Base type for all types.
Definition: TypeBase.cs:11
static void CreateDeclarationStatementAst(ParsingContext context, ParseTreeNode node)
The create declaration statement ast.
static void CreateForStatementAst(ParsingContext context, ParseTreeNode node)
The create for statement ast.
static void CreateExpressionStatementAst(ParsingContext context, ParseTreeNode node)
The create expression statement ast.
static void CreateLiteralExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
The create literal expression ast.
static void CreateQualifiersAst(ParsingContext context, ParseTreeNode node)
static void CreateExpressionOrEmptyAst(ParsingContext context, ParseTreeNode node)
The create expression or empty ast.
static void CreateReturnStatementAst(ParsingContext context, ParseTreeNode node)
The create return statement ast.
static void CreateBlockStatementAst(ParsingContext context, ParseTreeNode node)
The create block statement ast.
static void CreateQualifiers(ParsingContext context, ParseTreeNode node)
The create qualifiers.
static void CreateSwitchCastGroupAst(ParsingContext context, ParseTreeNode node)
The create switch cast group ast.
static void CreateMemberReferenceExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
The create member reference expression ast.
virtual void CreateVariableDeclaratorRawAst(ParsingContext parsingcontext, ParseTreeNode node)
The create variable declarator raw ast.
static readonly Qualifier None
None Enum.
Definition: Qualifier.cs:18
virtual void CreateVariableDeclaratorAst(ParsingContext parsingcontext, ParseTreeNode node)
The create variable declarator ast.
A field of a struct.
Definition: Literal.cs:13
static void CreateBinaryExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
The create binary expression ast.
static void CreateIndexerExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
The create indexer expression ast.
static void CreateAssignementExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
The create assignement expression ast.