Child pages
  • External calculations by Ilya

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

Example of synthesized attribute:

Code Block
calculation Evaluate(variables : map<string, int>) : int on CalcGrammar
{
  start => expr; // copy propagation

  add => expr1 + expr2; // equivalent to expr1.Evaluate(variables) + expr2.Evaluate(variables)

  sub(variables : map<string, int>) : int => // full syntax
  {
   expr1.Evaluate(variables) - expr2.Evaluate(variables);
  }

  var => variables[var.name]; // access to context
}

Extending:

Code Block
extend syntax Calc.Expression
{
 | "sin" "(" expr ")";
}
extend calculation Evaluate(...) on Calc
{
  sin => Math.Sin(expr);
}

Cross-using rules from each other, different typing (example itself is meaningless by design)

Code Block
syntax SomeSyntax
{
 | Value = { key=KeySyntax; "="; value=ValueSyntax; }
 | Null = "null";
}

syntax KeySyntax
{
 | Positive = { ... }
 | Negative = { ... }
}

syntax ValueSyntax
{
 | V1 = { ... }
 | V2 = { ... }
}


calculation A : string on SomeSyntax // parameterless calculation of string value on SomeSyntax
{
  SomeSyntax.Value => key.B(value.C()); // key matches KeySyntax, value matches ValueSyntax, B & C are other calculations below
  SomeSyntax.Null => "null";
}

calculation B(index:int) : string on KeySyntax // calculation gets int parameter, returns string on KeySyntax
{
  Positive => index.ToString(); // not using any nested syntax, so calculation stops here
  Negative => (-index).ToString();
}

calculation C : int on ValueSyntax // parameterless calc of type int on ValueSyntax
{
  ValueSyntax => 1; // matches any alternative of ValueSyntax, calculation stops here
}

Naive/manual implementation of visiting pattern on grammar:

Code Block
calculation Accept(visitor : IJsonVisitor) on Json // void calculation with visitor parameter
{
  Property => { visitor.Visit(this); Name; Value; } // exmaple of visiting rule
}

In a language like C# you implement IJsonVisitor and execute calculation on parse result (int array). Extensions can potentially be implemented using C# extension methods syntax on interface. The problem is their discovery, otherwise they are just static functions which gets interface and node data.

Such visitor can be generated with syntactic sugar:

Code Block
visitor Resolve<ICSharpResolver> on CSharpGrammar // same as above
{
  Object => Properties; // Properties is "list" rule, should know how to walk it
  Property => Name, Value; // this-Visit code is generated, productions specify order of ast walk
}