| Implementing a pre-defined DSL: some approach questions [message #753787] |
Fri, 28 October 2011 14:08  |
Jonathan Whitall Messages: 18 Registered: July 2009 |
Junior Member |
|
|
Hi there,
I'm working on a DSL for knitting patterns. One of the challenges I face is that the DSL syntax essentially already exists; pattern designers already have something fairly close to working abbreviations and layouts for patterns. I'd like to replicate this informal, non-technical DSL into a computer-parseable DSL.
To give an example, a typical written knitting pattern will look like this:
Row 1: knit 10
Row 2: p 5, k 5
As an alternative, row 2 is often instead written as:
I really would like my xtext-based DSL to look as close to the above as possible.
But the closest I've been able to get on my own is this:
Row 1: knit 10
Row 2: purl 5 knit 5
So my problems:
1) I would like the comma to be semantically equivalent to a semicolon in Java (i.e., the end of the data type). How do I take row two from "purl 5 knit 5" to "purl 5, knit 5" (with the comma separating the value list)? I haven't been able to figure out how to do this with the += operator.
2) How to I get "p5" and "p 5" to be semantically equivalent? Note that any time a terminal of type ID ends with a number, this rule could be applied. (I DO realize that this is unusual and can be quite hard to pull off, but it's such a common construct in this DSL it's really not optional)
I have tried several things to attempt to resolve these issues, but I either get errors when I run the MWE workflow or errors in the xtext file itself.
My xtext file to produce the above:
grammar com.knitml.dsl.KnittingExpressionLanguage with org.eclipse.xtext.common.Terminals
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate knittingExpressionLanguage "http://www.knitml.com/dsl/KnittingExpressionLanguage"
Pattern:
elements+=Row*;
Row:
(('Row' | 'Round' | 'Rows' | 'Rounds')) number=INT ':'
instructions += (InlineInstruction)+ ;
InlineInstruction:
(Knit | Purl)
;
Knit:
('knit'|'k') number=INT
;
Purl:
('purl'|'p') number=INT
;
I'm not looking for hand holding here; I just need some general advice about a general strategy for approaching this. I'm sure this has more to do with my lack of knowledge of the some of the terminology that xtext is using and some of the architecture. I'm also somewhat new to lexers / parsers, so be gentle. 
Thanks for any help you can give!
Jonathan
|
|
|
|
| Re: Implementing a pre-defined DSL: some approach questions [message #753789 is a reply to message #753787] |
Fri, 28 October 2011 14:21   |
Meinte Boersma Messages: 429 Registered: July 2009 Location: Leiden, Netherlands |
Senior Member |
|
|
The comma trick is simple enough: instructions+=InlineInstruction (',' instructions+=InlineInstruction)*
The thing with 'p5' is a bit harder: you're re-using the common.Terminals grammar which defines an ID terminal rule which gobbles things like 'p5' and 'k5' as ID tokens instead of as 2 separate tokens - keyword:'p', INT:'5'. That's because the generated lexer works greedy: whatever gobbles up the most characters. You could re-define the ID terminal rule to not match anything that's actually in your grammar, or even not re-use common.Terminals and just copy over the INT terminal rule.
Xtext blogs: executable models...again? | workshop material | custom scoping with Xtend
|
|
|
|
Powered by
FUDForum. Page generated in 0.01991 seconds