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