Textgen - How to override texgen component for used language ?

Hi,

I am working on a generator for xml using baselanguage expressions.
I wnat to format expressions in other way than the textgen defined in baselanguage.
For example :
for baseLang.StringLiteral
  texgen does :
"content"
I want to have instead :
'content'

Thus I tried to write textgen component for StringLiteral in my language :
text gen concept StringLiteral
append ' $node.value '

But this textgen component is not called and instead I have double quotes.
Is there configuration somewhere to specify order of precedence for textgen or to tell to override default one ?

Thanks for your help.
12 comments
Hi Louis,

I don't know if it is the most elegant way but the following could fit the purpose:
1. Create a new LanguageTextGenDeclaration component
2. Add the following function to the new component:
     operation valueWithSingleQuotes(node<Expression> expr) {
        ifInstanceOf (expr is StringLiteral string) {
           append {'} ${string.value} {'} ;
           return;
        }
        append ${expr} ;
     }
3. When printing the the expression call "append value with single quotes" instead of appending ${node.value} directly.

I hope this works for you.

Regards,
LaAck
0
Hi LaAck,

Thanks for your answer, I tried this solution and I can't make it work.
I have ExpressionWrapper for baseLang.Expression and ExpressionWrapper_TextGen calling append value with single quotes. But in the result it is still double quotes.
Can we debug or add log in textgen components ?
0
Hi again,

logging should be possible using the debug keyword. Just add a message behind and it will be shown in the MPS logfile.
But the solution I provided should work. Is the ExpressionWrapper a root node in your AST or did you provide any other TextGen component for your root node? If not the TextGen will not be called since, as far as I know, TextGen has to start with the root. Inside the root ConteptTextGenDeclaration component you can append any other generated text parts, e.g. by referencing a node's own TextGen (${node}) or calling an operation of a LanguageTextGenDeclaration component.
If you want, upload your project and I will have a look. :)
0
I tried the debug keyword in text gen component for ExpressionWrapper and valueWithQuotes operation. But I don't know where to look for them. They don't appear anywhere.
ExrpessionWrapper is not a root concept, it extends XmlValuePart (from mps.xml). But it is called (if I put dummy constant I see it in result).
So it should call the new valueWithQuotes operation. But id didn't change result.
Maybe sinceit is called for root expression, my expressionwrapper textgen for stringliteral is not called.
0
Here is the repository.
https://github.com/louisfoucart/statemachines-scxml
The language is StateMachines.
Where the debug info can be found ?
Thanks for your help.
0
Sorry for the delayed answer. The debug info can be found in C:\Users\<your user name>\.MPS30\system\log\mps.log (assuming that you're using Windows).

I cloned your repository but it does not seem to include the MPS project file. Only the languages are available. That's why I could not open your project using MPS. :-/

Could you give an example which expression you want to process? The operation I provided only works for a single string literal. Alternatively you could ZIP your project and upload it here so I can open it with MPS and have a look. Otherwise I have to perform "remote guessing" ;-)
0
Thanks for your attention !
I checked the logs in ~/Library/Logs/MPS31/mps.log (I am on mac os x), but I didn't find anything. It should mean my ExpressionWrapper textgen is not called.
I added .mps folder to github so you should be able to use it.
I am wrapping expressions like test == "some text". I can have what I want when I use InternalString concept to wrap around StringLiteral (with reduction rule for StringLiteral in main), but I want to find a better solution (less overhead) with overwriting textgen of the used language (baseLang).
You will find a sample model for test in sandbox (in StateMachines language folder).
Please don't hesitate to check the language and give me hints or tips.
0
Hm, the log file does not tell us anything, right. However, I switched "debug" to "error" to see if it is a matter of messaging policies. Now I can see the log messages. But I wonder why "debug" did not work.

But back to the actual issue. I now understand what you are trying to do. It is possible but not very comfortable. In your "StringLiteral_TG" you could provide an additional operation. The whole file then looks as follows:

base text gen component StringLiteral_TG extends <no baseTextGen> {
  operation valueWithSingleQuotes(node<Expression> expr) {
  error "valueWithSingleQuotes called";
  ifInstanceOf (expr is StringLiteral string) {
    append {'} ${string.value} {'} ;
    return;
  }
}      

  << ... >>
}
            
operation binaryExpressionWithSingleQuotedRightSide(node<Expression> expression) {
  ifInstanceOf (expression is EqualsExpression binExpr) {
    append ${binExpr.leftExpression} { == } ;
    append value with single quotes binExpr.rightExpression ;
    return;
  }
  append ${expression} ;
}   

From ExpressionWrapper_TextGen just "call binary expression ..." instead of the StringLiteral processing operation. You now get single quoted right sides for EqualsExpressions. The problem is that the concept hierarchy of the concept Expression is large. The operators are, as far as I know, specified via the concept alias. If these operators are sufficient for your purposes you can write the operation as generic as it name suggests. In order to do so just replace the "{ == }" node by "${binExpr.concept.conceptAlias}".

Do the upper explanations work for your purposes?
0
Yes, ok it works doing it like this.
So in fact, I have only one operation jexlExpression, which does ifInstanceOf for each kind of expression to customize (and, or, string, eq etc...).
So I like this solution better than creating Internal<ExpressionType> concepts for each expression to customize as I have done for StringLiteral.
But I would have liked to have a simple way to override textgen for specific contexts, as a kind of facet for each own language.
So thank you very much for your help ! I can continue now with upper level concepts.
0
Great!
Sure, if you want to customize the different expression type TextGen outputs you'll have to handle them on your own.

Yeah, it is the same with the editors. Some language concepts are very useful for me but I could not integrate them because of an insufficient editor aspect. As far as I know there is no possiblity for providing a custom editor implementation without changing the language. This seems odd referring to separation of concerns. Maybe this will be a topic of future MPS versions.

I'm glad that I could help you.

Regards,
LaAck

P.S.: With respect of forum tidiness you should mark this thread as "solved" or "answered". ;) I don't know how it is called exactly.
0
it seems it is not possible to close this thread.
There is only one option, to mark it as question (in edit thread).
0
True. I think you have to mark it as question and then you may mark it as answered as well.
0

Please sign in to leave a comment.