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.
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.
Please sign in to leave a comment.
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
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 ?
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. :)
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.
https://github.com/louisfoucart/statemachines-scxml
The language is StateMachines.
Where the debug info can be found ?
Thanks for your help.
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" ;-)
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.
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?
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.
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.
There is only one option, to mark it as question (in edit thread).