190 likes | 741 Views
ANTLRMorph A new ANTLR text rewrite engine. Sponsor: Professor Terence Parr Leon Jen Yuan Su leonsu@mac.com. ANTLR+“Morph”?. Allow programmers to define translators in terms of concrete syntax rewrite rules.
E N D
ANTLRMorphA new ANTLR text rewrite engine • Sponsor: Professor Terence Parr • Leon Jen Yuan Su • leonsu@mac.com
ANTLR+“Morph”? • Allow programmers to define translators in terms of concrete syntax rewrite rules. • These rules are independent of the original parser grammar and take the form: “this” -> “that”. • Be able to define rewrite strategy on each morph rule.
How it works? • ANTLRMorph engine reads in a script in which rewrite rules are defined, and the script should follow the morph grammar syntax. • Morph engine then translates the script into a corresponding ANTLR grammar file. • It also generates a supporting java file which can be used for executing the task.
Match by grammatical context Morph allows you define rewrite alternatives in the context of the specified rule context. The context here means that which rules you're matching. Therefore, you can utilize it to do something different based on different context. For example, you might have to rewrite something different for variable declarations matched at block level (locals) and for variable declarations matched in methods (parameters) and default rewrite for variables: /** in context of the following rules, match left side, rewrite to right side */[block ... variable]: // context is local type ID -> rewrite1[func variable]: // context is func local type ID -> rewrite2variable: // in context of variable (default, be careful of the order) type ID -> rewrite3 Please note that the morph rule specified first would be given precedence over those specified later. To avoid ambiguity, morph is implemented by a simple law: winner is always the one matched first.
Concrete Exemplar Example: Match the mathematical expression, an integer number plus zero, and rewrite the expression to the integer value only. Before Morph: x=INT ‘+’ pred=INT {$pred.text.equals(“0”)}? -> template(x={$x.text}) “<x>” After Morph: “x+0” -> “x” (Note: need to predefine the label x=INT, but later it can be reused easily in a morph script.)
Partial Match Example: Match the mathematical expression, an integer number plus zero, in every possible location within the expression. Before Morph: No partial match for ANTLR grammar fragment. Need to manually add try-catch block into the grammar for retrying the specific rule. After Morph: “... x+0 ...” -> “x” or “... x+0” -> “x”// match the expression appearing at the end and ignore whatever before it or “x+0 ...” -> “x”// match the expression appearing at the beginning and ignore whatever after it (Note: current ANTLR grammar can perform the last partial match by not adding EOF keyword at the end.)
Conform or not? Generally speaking, there are 2 categories of term rewriting: # input language conforms to output language, e.g. mathematical expression to mathematical expression. # input language does not conform to output language, e.g. C to Java. Both cases are acceptable in Morph, and users can tell morph which type the language is with the syntax: options {conforms=false;} By default, morph assumes the rewritten result conforms to the input.
Example polynomial differentiating + simplifying Input grammar Before morph: You have to add AST rewrite alternatives to the original grammar, and create 2 tree grammars for walking the output AST and performing rewriting tasks.
What is strategy and how it works? Input text: 2x^3 + x^5 + 4x + 10x + 8x + x + 2 complete parse tree before rewriting: morph executor walks the parse tree generated from the input text and apply morph rules with user defined strategies at runtime.
More Example? Yes... We have another a cool language translating example for the not-conforming case ;)