Microsoft Developer Network > 포럼 홈 > Microsoft SQL Server Modeling > MGrammar Equivalent of Yacc's $$?
질문하기질문하기
 

답변됨MGrammar Equivalent of Yacc's $$?

  • 2009년 3월 15일 일요일 오후 9:53JeffFerguson 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     코드 있음
    Consider the following simple calculator implemeted in yacc:

    1 %{
    2     #include <stdio.h>  
    3     int yylex(void);  
    4     void yyerror(char *);  
    5 %}  
    6  
    7 %token INTEGER  
    8  
    9 %%  
    10  
    11 program:  
    12         program expr '\n'         { printf("%d\n", $2); }  
    13         |   
    14         ;  
    15  
    16 expr:  
    17         INTEGER  
    18         | expr '+' expr           { $$ = $1 + $3; }  
    19         | expr '-' expr           { $$ = $1 - $3; }  
    20         ;  
    21  
    22 %%  
    23  
    24 void yyerror(char *s) {  
    25     fprintf(stderr, "%s\n", s);  
    26 }  
    27  
    28 int main(void) {  
    29     yyparse();  
    30     return 0;  
    31 }  
    32  


    I am interested in how to handle yacc's $$ construct in MGrammar. As you can see in lines 18 and 19 above, the $$ holds the result of an expression calculated in the "codebehind" (for lack of a better term) for the expression. This allows the result to be used in parse trees as if it were brought in as a literal.

    How would I do the same in MGrammar? I am familiar with navigating parse trees in .NET, so, if you say "you need C# for that", that's fine ... in fact, I almost expect that answer. I know how to calculate the result in the # code, but where do I return the result of the expression to be used in the parse tree?

    Thank you,
    Jeff Ferguson

답변

  • 2009년 3월 16일 월요일 오후 4:52Lars WilhelmsenMVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨
    Hi Jeff,

     There's no directequivalent in MGrammar for Yacc's $$ macro, but there isn't a 1:1 relationship between these two technologies
     either. MGrammar does both the work that Lex and Yacc solve together - and you can easily output nodes to the AST that will
     do the same thing for you, e.g.:

     syntax SomeSyntax = a:tNumber op:tOperator b:tNumber => Add { Left { a }, Right { b} };

     In the backend you will have to walk the AST and take actions accordingly.

     HTH,

     --larsw

    Lars Wilhelmsen | Senior Consultant | Miles, Norway | Connected Systems MVP | http://larswilhelmsen.com/
    • 답변으로 표시됨JeffFerguson 2009년 3월 16일 월요일 오후 5:16
    •  

모든 응답

  • 2009년 3월 16일 월요일 오후 4:52Lars WilhelmsenMVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨
    Hi Jeff,

     There's no directequivalent in MGrammar for Yacc's $$ macro, but there isn't a 1:1 relationship between these two technologies
     either. MGrammar does both the work that Lex and Yacc solve together - and you can easily output nodes to the AST that will
     do the same thing for you, e.g.:

     syntax SomeSyntax = a:tNumber op:tOperator b:tNumber => Add { Left { a }, Right { b} };

     In the backend you will have to walk the AST and take actions accordingly.

     HTH,

     --larsw

    Lars Wilhelmsen | Senior Consultant | Miles, Norway | Connected Systems MVP | http://larswilhelmsen.com/
    • 답변으로 표시됨JeffFerguson 2009년 3월 16일 월요일 오후 5:16
    •  
  • 2009년 3월 16일 월요일 오후 5:16JeffFerguson 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    Thanks, Lars ... as I said in my original question, "you need C# for that" is an acceptable answer. I just thought that, if there were some equivalent that I was missing, I wanted to find out what it was.
  • 2009년 3월 16일 월요일 오후 5:57jchase 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    Hi jeff,
    I have implemented a grammar that lets me parse various binary expressions in MGrammar I could share with you if you're interested. I found it pretty hard to use MGrammar to parse epxressions and maintain precedence but I managed to figure it out.

    Where:
    x + y => (x + y)
    x + y * z => x + (y * z)
    x + y and z | w => x + (y and (z | w))

    For example. Very tricky.
  • 2009년 3월 16일 월요일 오후 6:09JeffFerguson 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    Hey there! Sure, I'd love to se it. Thanks!
  • 2009년 3월 16일 월요일 오후 7:18Lars WilhelmsenMVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    Hi again,

     I assume that the problem you had with the expressions in your post is related to associativity and precedence. In
     MGrammar you can use precedence, left(n) and right(n) to solve this.

     For the basic mathematical operators, multiply and divide have higher precedence than plus and minus.

     A small example of the use of left & right:

     syntax tOperator = left(1) tPlus => "Plus"
                             | left(1) tMinus => "Minus"
                             | left(2) tDivide => "Divide"
                             | left(2) tMultiply => "Multiply"
                             | right(3) tExponentiation => "Exp";
            token tPlus = "+";
            token tMinus = "-";
            token tDivide = "/";
            token tMultiply = "*";
            token tExponentiation = "**";


     The precedence keyword will help you solve the classical "danging else" problem. A more thorough explanation of this
     is done in the MGrammar specification that is shipped with the Oslo SDK.

     HTH,

     --larsw

    Lars Wilhelmsen | Senior Consultant | Miles, Norway | Connected Systems MVP | http://larswilhelmsen.com/
  • 2009년 3월 31일 화요일 오후 10:28Paul VickMSFT사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    I'm just catching belatedly up on forum threads, but I thought I'd interject that we're considering ways to evaluate expressions directly in grammars. It's a pretty useful feature, and we'd love to provide the full M expression capabilities on the RHS of a grammar production. So stay tuned!

    Paul [MSFT]
    Paul Vick MSFT
  • 2009년 4월 1일 수요일 오후 12:09Lars WilhelmsenMVP사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    Hi Paul,

     That would be awesome! :-)

     --larsw
    Lars Wilhelmsen | Senior Consultant | Miles, Norway | Connected Systems MVP | http://larswilhelmsen.com/