Ask a questionAsk a question
 

AnswerDifferences in tree construction?

  • Wednesday, September 23, 2009 10:25 PMPedro J. Molina Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi:

    I want to show you an example of an MGrammar developed with CTP May 2009.

    I tried to make it as small as possible in order to reproduce it.

    So, find enclose 3 files:

     

    1. The repro grammar
    2. A text input sample
    3. A tree output

     

    The point is that there are two productions to parse a property (see variant 1 & 2). The variations changes the way of parsing the “type”. These changes, of course make a structural change in the output tree to the “type” part.

    However, take a look (in the picture) to the “name” of the property built in the tree for Prop1 & Prop2.

     

    • For Prop1:      Name { “Prop1” }
    • For Prop2:      Name  => “Prop2”

     

     

    It’s different!!!! But if you look again to the productions, the parsing for the Name: ( =  name:Id )  is the same in both cases.

    Why is different?

     

     

    Open image.

     

    This subtle difference is important when trying to map the parsed graph to .NET objects using MGraphXamlReader. Ending in case 2 with a type mismatch exception between System.Generic.Collection.List’1<object> & PropertyDef.

    Maybe I am missing something or may be it is a bug in MGrammar? 

    I reviewed the bug database in Connect and found nothing similar to this. Any clue?

     

    Thanks in advance,


    Dr. Pedro J. Molina | Capgemini Spain
    • Edited byPedro J. Molina Wednesday, September 23, 2009 10:28 PMMinor edit changes
    •  

Answers

  • Tuesday, September 29, 2009 4:35 PMdmatsonMSFTUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Pedro,

    This line should fix your problem:

         syntax PropertyDef1
            = t:TypeRef name:Id Semi => PropertyDef{Type  => t, Name => name};  

    Note the use of Label => Value instead of Label { Value } fixes the problem here. You are correct this problem is the same in the other post you mentioned.

    You are also correct that mixing => and {} within an entity in a production is not allowed.

    I believe all of these issues are relate to a new graph model we have not yet fully implemented throughout the toolchain. For more details on the new graph model, see the paper by Clemens Szyperski (http://msdn.microsoft.com/en-us/library/dd878360.aspx).

    Sorry for the inconvenience/inconsistency here. We are definitely aware of it and are working on making the graph model consistent throughout the "M" toolchain.

    Thanks for your interest in Oslo! Let me know if you have any additional questions.

    David

    P.S. Here's a revised grammar that uses => rather than {} wherever possible. That's what I tend to do, and it seems to give better results.

    module Why
    {
     language Why
     {
            syntax Main = t:TypeDef => t;
           
            syntax TypeDef
                =  "class" n:Id LCurly def:PropertyDefList RCurly => TypeDef { Name  => n, TypeDefinitions => def };

            syntax PropertyDefList
                =  p1:PropertyDef1 p2:PropertyDef2 => [p1, p2];
           
            //Variant 1
         syntax PropertyDef1
            = t:TypeRef name:Id Semi => PropertyDef{Type  => t, Name => name};  

            //Variant 2 (Note the different tree output for Name!!!)
         syntax PropertyDef2
          = t:PrimitiveType name:Id Semi => PropertyDef{Type => t, Name => name};  
              
            syntax TypeRef
                = t:PrimitiveType => PrimitiveType { Name => t };
             
            @{Classification["Identifier"]} token Id = Letter (Alphanumeric | "_")*;

            token Letter = "A".."Z" | "a".."z";
            token Digit = "0".."9";
            token Alphanumeric = Letter | Digit;
           
      @{Classification["Keyword"]} token Class = "class";
      @{Classification["Keyword"]} token PrimitiveType = "int" | "string";
      @{Classification["Keyword"]} token LCurly = "{";
      @{Classification["Keyword"]} token RCurly = "}";
           
      token Semi = ";";
      interleave WhiteSpace = " " | "\t" | "\n" | "\r";  
        }
    }

    • Proposed As Answer bydmatsonMSFTTuesday, September 29, 2009 4:35 PM
    • Marked As Answer byPedro J. Molina Wednesday, September 30, 2009 2:57 PM
    •  

All Replies

  • Friday, September 25, 2009 7:08 PMKraig BrockschmidtMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Thanks for your post. I'll have someone from the "M" team look into this.

    .Kraig
  • Saturday, September 26, 2009 8:00 PMPedro J. Molina Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Thanks Kraig for taking the time to review it.

    May be, could it be also related to this previous topic: Output mismatch between mgx.exe and DynamicParser ? 

    Using Intelipad in MGrammar mode, I found that it is allowed to use the operator “=>” or the operator “{ }” inside a production. But mixing both of them, at the same production, is not allowed. Example:

    syntax PropertyDef1 = t:TypeRef name:Id Semi => PropertyDef{Type { t }, Name { name } };  //Allowed :)
    syntax PropertyDef1 = t:TypeRef name:Id Semi => PropertyDef{Type => t,  Name => name };   //Allowed :)
    
    syntax PropertyDef1 = t:TypeRef name:Id Semi => PropertyDef{Type { t }, Name => name };   //NOT Allowed :(  
    

    Is there a clear definition of the semantics of the “=>” and “{ }” operators in the specification/documentation and how they should influence the tree construction?

    Best regards,

    Dr. Pedro J. Molina, Capgemini Spain
  • Tuesday, September 29, 2009 4:35 PMdmatsonMSFTUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Pedro,

    This line should fix your problem:

         syntax PropertyDef1
            = t:TypeRef name:Id Semi => PropertyDef{Type  => t, Name => name};  

    Note the use of Label => Value instead of Label { Value } fixes the problem here. You are correct this problem is the same in the other post you mentioned.

    You are also correct that mixing => and {} within an entity in a production is not allowed.

    I believe all of these issues are relate to a new graph model we have not yet fully implemented throughout the toolchain. For more details on the new graph model, see the paper by Clemens Szyperski (http://msdn.microsoft.com/en-us/library/dd878360.aspx).

    Sorry for the inconvenience/inconsistency here. We are definitely aware of it and are working on making the graph model consistent throughout the "M" toolchain.

    Thanks for your interest in Oslo! Let me know if you have any additional questions.

    David

    P.S. Here's a revised grammar that uses => rather than {} wherever possible. That's what I tend to do, and it seems to give better results.

    module Why
    {
     language Why
     {
            syntax Main = t:TypeDef => t;
           
            syntax TypeDef
                =  "class" n:Id LCurly def:PropertyDefList RCurly => TypeDef { Name  => n, TypeDefinitions => def };

            syntax PropertyDefList
                =  p1:PropertyDef1 p2:PropertyDef2 => [p1, p2];
           
            //Variant 1
         syntax PropertyDef1
            = t:TypeRef name:Id Semi => PropertyDef{Type  => t, Name => name};  

            //Variant 2 (Note the different tree output for Name!!!)
         syntax PropertyDef2
          = t:PrimitiveType name:Id Semi => PropertyDef{Type => t, Name => name};  
              
            syntax TypeRef
                = t:PrimitiveType => PrimitiveType { Name => t };
             
            @{Classification["Identifier"]} token Id = Letter (Alphanumeric | "_")*;

            token Letter = "A".."Z" | "a".."z";
            token Digit = "0".."9";
            token Alphanumeric = Letter | Digit;
           
      @{Classification["Keyword"]} token Class = "class";
      @{Classification["Keyword"]} token PrimitiveType = "int" | "string";
      @{Classification["Keyword"]} token LCurly = "{";
      @{Classification["Keyword"]} token RCurly = "}";
           
      token Semi = ";";
      interleave WhiteSpace = " " | "\t" | "\n" | "\r";  
        }
    }

    • Proposed As Answer bydmatsonMSFTTuesday, September 29, 2009 4:35 PM
    • Marked As Answer byPedro J. Molina Wednesday, September 30, 2009 2:57 PM
    •  
  • Wednesday, September 30, 2009 2:57 PMPedro J. Molina Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Thanks David.
    Your proposed solution works!

    Dr. Pedro J. Molina, Capgemini Spain
  • 4 hours 30 minutes agoCeyhun Ciper Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals