Adding Line Slopes and Print Statements to Calculatix Using MGrammar

I have added, thanks to MGrammar, a few new constructs to my fledgling Calculatix language:

  • unary operators, used primarily so that I can specify negative whole numbers
  • support for string literals
  • the slopeof expression, allowing for the calculation of the slope of a line
  • the show statement, allowing for the output of an expression’s value to the console

This allows me to write input such as this:

line LineA (4, -3) (2, 5);
show "The slope of LineA is:";
show slopeof LineA;

The MGrammar for this language now looks like this:

   1: module JeffFerguson.Calculatix.Grammars
   2: {
   3:     language Calculus
   4:     {
   5:         
   6:         // ignore whitespace
   7:         
   8:         syntax LF = "\u000A";
   9:         syntax CR = "\u000D";
  10:         syntax Space = "\u0020";
  11:         interleave Whitespace = LF | CR | Space;
  12:         
  13:         // punctuation
  14:         token Comma = ',';
  15:         
  16:         // operators
  17:         token UnaryOperator = "+" | "-";
  18:         token Quote = "\"";
  19:  
  20:         // keywords
  21:         token LineKeyword = "line";
  22:         token ShowKeyword = "show";
  23:         token SlopeKeyword = "slopeof";
  24:         
  25:          // numbers
  26:         token Digit = "0".."9";
  27:         token WholeNumber = UnaryOperator? Digit+;
  28:  
  29:  
  30:         // strings
  31:         token StringLiteral = Quote a:any* Quote => StringLiteral[a];
  32:         
  33:         // identifiers
  34:         token Uppercase = "A".."Z";
  35:         token Lowercase = "a".."z";
  36:         token Alphabetic = Uppercase | Lowercase;
  37:         token Identifier = Alphabetic (Alphabetic | Digit)*;
  38:                         
  39:         // expressions
  40:         syntax SlopeExpression = SlopeKeyword i:Identifier => Slope[i];
  41:         syntax Expression =
  42:             SlopeExpression
  43:             | StringLiteral
  44:             ;
  45:                     
  46:         // points
  47:         token XCoordinate = WholeNumber;
  48:         token YCoordinate = WholeNumber;
  49:         syntax Point = "(" x:XCoordinate "," y:YCoordinate ")" =>Point[x,y];
  50:         
  51:         // lines
  52:         syntax LineStatement = LineKeyword i:Identifier p1:Point p2:Point => Line[i, p1, p2];
  53:         syntax SlopeStatement = SlopeKeyword i:Identifier => Slope[i];
  54:         
  55:         // expression display
  56:         syntax ShowStatement = ShowKeyword e:Expression => Show[valuesof(e)];
  57:         
  58:         // statements
  59:         syntax StatementExpression =
  60:             LineStatement
  61:             | ShowStatement;
  62:                         
  63:         // language syntax
  64:         syntax Statement = e:StatementExpression ";" =>Statement[valuesof(e)];
  65:         syntax Main = Statement*;
  66:     }
  67: }

This input shown above produces a graph that looks like this:

Main[
  [
    Statement[
      Line[
        "LineA",
        Point[
          "4",
          "-3"
        ],
        Point[
          "2",
          "5"
        ]
      ]
    ],
    Statement[
      Show[
        StringLiteral[
          "The slope of LineA is:"
        ]
      ]
    ],
    Statement[
      Show[
        Slope[
          "LineA"
        ]
      ]
    ]
  ]
]

It is worth noting that I have used two terms here - expression and statement – and it is probably important to discuss the difference (at least according to how I have defined them). A statement is an action. When a statement is encountered, an action is taken: perhaps an object is created in the .NET code that processes the source input, or information is displayed to the user. When an expression is encountered, an evaluation is made: perhaps a calculation is performed, or some memory is reserved for a value. Expressions do nothing, however, until used in a statement. The current grammar defines two types expressions:

  • string literals
  • slope expressions via the slopeof keyword

Since the show statement is defined as accepting an expression, either expression type can be used in the show statement, and, as you can see, the source input uses both of those types.

It’s also important to note what the grammar doesn’t do:

  • Identifier Validation: The intent of the slopeof expression is that the identifier used in the expression was previously used to define a line. The grammar doesn’t check that, nor can it, nor should it. That has to be checked by the .NET code that is processing the input. This is an example of semantics versus syntax. MGrammar will handle the syntax, but you need to handle the semantics. In this example, the code that checks to ensure that the identifier used in the slopeof expression actually belongs to a line will be code that I have to write in the .NET processor.
  • Calculation: The grammar doesn’t calculate the actual slope of the line. Again, that’s code that must be left to the .NET processor.

Next up – processing this input in C#. With any luck, I will be able to show the slope’s calculation on the console.

Print | posted @ Tuesday, March 17, 2009 11:40 AM

Comments on this entry:

No comments posted yet.

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
 
Twitter