I'm new to Rascal and experimenting with its transformation/term rewriting abilities.
I want to write a script that splits declarations like:
int x = 5;
into declaration/initializations like:
int x; x = 5;
How might I go about this? Let's say the language I'm trying to transform is Java.
Thanks for any help.
Good question. There are several ways to do this and I will show the most simplistic one. Note that your example is not the simplest possible example since it requires a conversion from a single statement to a list of statements (i.e., it is not type preserving).
Here is without further ado a complete example, the explanation follows below.
module Decl
import IO;
import ParseTree;
// Decl, a trivial language, to demo simple program trafo
lexical Id = [a-z][a-z0-9]* !>> [a-z0-9] \ Reserved;
lexical Natural = [0-9]+ ;
lexical String = "\"" ![\"]* "\"";
layout Layout = WhitespaceAndComment* !>> [\ \t\n];
lexical WhitespaceAndComment
= [\ \t\n\r]
;
keyword Reserved = "int" | "str" | "if" | "then" | "else" | "fi" | "while" | "do" | "od";
start syntax Program
= {Statement ";"}* body
;
syntax Type
= "int"
| "str"
;
syntax Statement
= Type tp Id var
| Type tp Id var ":=" Expression exp
| Id var ":=" Expression val
| "if" Expression cond "then" {Statement ";"}* thenPart "else" {Statement ";"}* elsePart "fi"
| "while" Expression cond "do" {Statement ";"}* body "od"
;
syntax Expression
= Id name
| String string
| Natural natcon
| bracket "(" Expression e ")"
> left ( Expression lhs "+" Expression rhs
| Expression lhs "-" Expression rhs
)
;
str trafo1 () {
p = parse(#start[Program], "int x := 1").top;
newBody = "";
for(stat <- p.body){
if((Statement) `<Type tp> <Id var> := <Expression exp>` := stat){
newBody += "<tp> <var>; <var> := <exp>";
} else {
newBody += "<stat>";
}
}
return newBody;
}
The major part is a complete grammar of a simple language. The actual transformation is done by trafo1
which does:
newBody
(used to build the result).The solution style large depends on your goal. Here we just build a string. If desired, you could return the parsed string as result.
Alternatives:
Hope this helps you to get started.