I'm experiencing some unexpected behaviors in my DSL. I've shortened it here to make my point, but it seems that if all my tokens (A,B,C,D) are optional, and I assign onlyone of them, MGrammar assumes that is the last token. I would have expected it to be the first:
Grammar: module SAMPLE{ language TEST { syntax Main = a:A? del? b:B? del? c:C? del? d:D? =>{A=>a,B=>b,C=>c,D=>d} ; @{Classification["Delimiter"]} token del = ":"; token A = ("A".."Z" | "a".."z" | "0".."9")+; token B = ("A".."Z" | "a".."z" | "0".."9")+; token C = ("A".."Z" | "a".."z" | "0".."9")+; token D = ("A".."Z" | "a".."z" | "0".."9")+; } }
Input (OK): A:B:C:D Output: { A => "A", B => "B", C => "C", D => "D" }
Input (not OK): A:B Output: { A => null, B => null, C => "A", D => "B" }
I would have expected: { A => "A", B => "B", C => null, D => null }
Is there anything I can do to make this work as I expected? //Mikeal
If this answers your question, please use the "Answer" button to say so... Mikael - http://blogical.se/blogs/mikael - Edited byMikael HåkanssonMVPWednesday, August 05, 2009 7:55 PM
- Edited byMikael HåkanssonMVPWednesday, August 05, 2009 7:58 PM
-
| | Mikael Håkansson | Hi, Mikael!
The following appears to do what you want, more or less:
syntax Main = t1:Term t2:Term t3:Term t4:LastTerm => {A=>t1,B=>t2,C=>t3,D=>t4} | t1:Term t2:Term t3:LastTerm => {A=>t1,B=>t2, C=>t3} | t1:Term t2:LastTerm => {A=>t1,B=>t2} | t1:LastTerm => {A=>t1} ; syntax Term = l:Letter del => {l}; syntax LastTerm = l:Letter del? => {l}; @{Classification["Delimiter"]} token del = ":"; token Letter = ("A".."Z" | "a".."z" | "0".."9")+;
Here's the output it produces, not exactly what you want, but close.
{ A => { "A" }, B => { "B" } }
It also requires the presence of non-final delimiters, but allows the last one to be optional, which I suspect is the behavior you wanted. - Marked As Answer byMikael HåkanssonMVPThursday, August 06, 2009 9:21 PM
-
| | Rick Saling | syntax Main = d:D? del? c:C? del? b:B? del? a:A?
=> { A=>a, B=>b, C=>c, D=>d };
:-) - Proposed As Answer byKraig BrockschmidtMSFT, ModeratorWednesday, August 05, 2009 5:09 PM
- Unproposed As Answer byMikael HåkanssonMVPThursday, August 06, 2009 7:05 AM
-
| | justncase80 | well...closer, but not quite right
Input: A:B Output: { A => "B", B => "A", C => null, D => null }
Expected: { A => "A", B => "B", C => null, D => null }
If this answers your question, please use the "Answer" button to say so...
Mikael - http://blogical.se/blogs/mikael | | Mikael Håkansson | According to the squigglies I might be better off using left or right annotations:
"Annotate the token with left(n) or right(n)"
I tried looking in the help for Production/Term Precedence, but it didn't make me any wiser...:(
//Mikael
If this answers your question, please use the "Answer" button to say so...
Mikael - http://blogical.se/blogs/mikael | | Mikael Håkansson | Hi, Mikael!
The following appears to do what you want, more or less:
syntax Main = t1:Term t2:Term t3:Term t4:LastTerm => {A=>t1,B=>t2,C=>t3,D=>t4} | t1:Term t2:Term t3:LastTerm => {A=>t1,B=>t2, C=>t3} | t1:Term t2:LastTerm => {A=>t1,B=>t2} | t1:LastTerm => {A=>t1} ; syntax Term = l:Letter del => {l}; syntax LastTerm = l:Letter del? => {l}; @{Classification["Delimiter"]} token del = ":"; token Letter = ("A".."Z" | "a".."z" | "0".."9")+;
Here's the output it produces, not exactly what you want, but close.
{ A => { "A" }, B => { "B" } }
It also requires the presence of non-final delimiters, but allows the last one to be optional, which I suspect is the behavior you wanted. - Marked As Answer byMikael HåkanssonMVPThursday, August 06, 2009 9:21 PM
-
| | Rick Saling |
|