Template switch macro

Hi there,

I recently attempted to learn to use MPS by means of writing a simple language and generating java classes from it. I'm stuck at the following problem, which I thought could be solved with the "switch" macro, but I couldn't figure out how to make it work. There doesn't appear to be any documentation available on this macro, and there are only a few examples that use it. Unfortunately, one can scarcely guess how this macro works by simply looking at the examples. So, I would really appreciate if someone explains how to use them in a few words.

So, the problem I'm trying to solve is generating a tree-like structure from a source tree, using recursive templates. It's best described by an example:

E.g. for something like the following in XML:

   
      
      
        
        
      
   

One would write a corresponding transformation in XSLT similar to:


    A(
    
       
       ,
    
    )



    B()



    C()

Which should produce

  A(B(),A(B(),C()))

Now, how do I achieve the same result in MPS? My thought was I could employ the switch macro for this task, since it's the only tool I found that allows me to call templates recursively. Please correct me if I'm wrong and there is another, simpler and more elegant way.

I believe, one could simply create mapping from source nodes to templates and just run a substitution (AKA transformation) with the root source node. This would be most natural, but unfortunately it's unclear how one achieves this mapping.

Thanks in advance.

Regards,

Fedor.

4 comments
Comment actions Permalink

Hi Fedor!

To generate nodes recursively we use combination of ‘reduction rules’ and $COPY_SRC$ macro (or $COPY_SRCL$ macro).

In course of generations, if the $COPY_SRC$ is encountered, then generator tries to find and apply a ‘reduction rule’. If applicable ‘reduction rule’ is found and it also contains $COPY_SRC$ macro then the same procedure is repeated. This provides a way to make a recursion.

I’ve attached sample project containing simple source language (myxml) and generator from it to baseLanguage (java).

The generator contains single reduction rule which is applicable to any Element in source model and which reduces an Element to a static method call which will look like:

element(“A”, new String[]{ element(“B”,..), .. })

Igor.



Attachment(s):
recursivegen_myxml_java.zip
0
Comment actions Permalink

Hi,

thanks Igor, this appears to be exactly what I require. However, I'm stuck at another problem, the generator throws an exception in a seemingly legal situation:

  ERROR - mps.generator.GeneratorManager - Exception

java.lang.ClassCastException: jetbrains.mps.baseLanguage.ExpressionStatement

        at jetbrains.mps.baseLanguage.ReturnStatement.getExpression(ReturnStatement.java:19)

        at jetbrains.mps.baseLanguage.textGen.ReturnStatement_TextGen.doGenerateText(ReturnStatement_TextGen.java:16)

        at jetbrains.mps.textGen.TextGenManager.appendNodeText(TextGenManager.java:49)

        at jetbrains.mps.textGen.SNodeTextGen.appendNodeText(SNodeTextGen.java:24)

        at jetbrains.mps.baseLanguage.textGen.StatementList_TextGen.doGenerateText(StatementList_TextGen.java:20)

        at jetbrains.mps.textGen.TextGenManager.appendNodeText(TextGenManager.java:49)

        at jetbrains.mps.textGen.SNodeTextGen.appendNodeText(SNodeTextGen.java:24)

        at jetbrains.mps.baseLanguage.textGen.InstanceMethodDeclaration_TextGen.doGenerateText(InstanceMethodDeclaration_TextGen.java:43)

        at jetbrains.mps.textGen.TextGenManager.appendNodeText(TextGenManager.java:49)

        at jetbrains.mps.textGen.SNodeTextGen.appendNodeText(SNodeTextGen.java:24)

        at jetbrains.mps.baseLanguage.textGen.ClassConcept_TextGen.doGenerateText(ClassConcept_TextGen.java:115)

        at jetbrains.mps.textGen.TextGenManager.appendNodeText(TextGenManager.java:49)

        at jetbrains.mps.textGen.TextGenManager.generateText(TextGenManager.java:29)

        at jetbrains.mps.generator.generationTypes.TextGenerationUtil.generateText(TextGenerationUtil.java:17)

        at jetbrains.mps.generator.generationTypes.GenerateTextGenerationType.handleOutput(GenerateTextGenerationType.java:25)

        at jetbrains.mps.generator.GeneratorManager.generateModels(GeneratorManager.java:319)

        at jetbrains.mps.generator.GeneratorManager$3$1.run(GeneratorManager.java:214)

        at jetbrains.mps.ide.command.CommandProcessor.executeCommand_internal(CommandProcessor.java:85)

        at jetbrains.mps.ide.command.CommandProcessor.executeCommand(CommandProcessor.java:71)

        at jetbrains.mps.ide.command.CommandProcessor.executeCommand(CommandProcessor.java:48)

        at jetbrains.mps.generator.GeneratorManager$3.run(GeneratorManager.java:212)

I attach my small project here, could you take a look if you have time?

Thanks,

Fedor.



Attachment(s):
Qlog.zip
0
Comment actions Permalink

So, I figured out what the problem was.

Simply put, the "template fragment" braces of the template referred from the $COPY_SRC$ macro were introduced at the ExpressionStatement node, which is a parent of InstanceMethodCall. Apparently, the template fragment should be introduced instead at the latter node. Unfortunately, one can not distinguish between the two cases by simply reading the screen: visually they look absolutely the same.

Thanks anyway, MPS is a great toy!

0
Comment actions Permalink

Thanks for feedback!

Incorrect positioning of a template-fragment is common yet not easily detectable error.

Certainly we need improvements on the matter.

Igor.

0

Please sign in to leave a comment.