Compile time lex + parse + semantic = 300 lines of code

Don Clugston dac at nospam.com.au
Tue Sep 11 23:46:58 PDT 2007


I've finally released the compile-time parser I mentioned in my conference 
presentation.

http://www.dsource.org/projects/mathextra/browser/trunk/blade/SyntaxTree.d

contains one publicly usable function:

char [] syntaxtreeof(char [] expression).

When mixed in, this lexes and parses the expression, determines precedence and 
associativity, creating an object of type AbstractSyntaxTree, which contains a 
standardized 'placeholder expression' (eg "A+=(B*C)")
and a symbol table for the variables, constants and functions A,B,C,...
The symbol table includes the type and value for each symbol.
All aliases and compile-time constants are resolved and converted to a standard 
form.
All symbols must be reachable from the scope where syntaxtreeof() is mixed into.

The created AbstractSyntaxTree is a compile-time constant, so it can be used for 
  further compile-time operations and code generation.

Works for almost any expression (templates, functions, strings, slicing, struct 
literals,...); the biggest omission is relational operators.
Less than 300 lines of code in D1.020.
Probably could simplified using __traits in D2.0.
Enjoy.


Return type:
-----
struct Symbol {
     char [] type; // the name of the type, as text
     char [] value; // the value, as text. Either the symbol name, or a literal
}

// The result of semantic analysis of the original expression
struct AbstractSyntaxTree {
     char [] expression; // syntax tree in Placeholder format, eg A+=(B*C)
     Symbol[] symbolTable; // The types and values of A,B,C,...
}
------

Example:
-----
import SyntaxTree;

const foo = "abc";
int bar(real x, char [] s) { return 0; }
struct Duck{};
Duck duck;

AbstractSyntaxTree a = mixin(syntaxtreeof(`foo*   bar(2.18_3242e+45L, "xyz") in 
duck`));



More information about the Digitalmars-d-announce mailing list