سؤال

%type <string> Id
%type <ExprRes> Factor
%type <ExprRes> Term
%type <ExprRes> Expr
%type <InstrSeq> StmtSeq
%type <InstrSeq> Stmt
%type <BExprRes> BExpr
%type <ExprRes> Primary

%token Ident        
%token IntLit   
%token Int
%token Write
%token IF
%token EQ
%token GTE
%token LTE
%token UM
%token UP   

%%

Prog            :   Declarations StmtSeq                                {Finish($2); } ;
Declarations    :   Dec Declarations                                    { };
Declarations    :                                                       { };
Dec             :   Int Ident {EnterName(table, yytext, &entry); }';'   { };
StmtSeq         :   Stmt StmtSeq                                        { $$ = AppendSeq($1, $2); } ;
StmtSeq         :                                                       { $$ = NULL;} ;
Stmt            :   Write Expr ';'                                      { $$ = doPrint($2); };
Stmt            :   Id '=' Expr ';'                                     { $$ = doAssign($1, $3);} ;
Stmt            :   IF '(' BExpr ')' '{' StmtSeq '}'                    { $$ = doIf($3, $6);};
BExpr           :   Expr EQ Expr                                        { $$ = doBExpr($1, $3);};
Expr            :   Expr '+' Term                                       { $$ = doAdd($1, $3); } ;
Expr            :   Expr '-' Term                                       { $$ = doMinus($1, $3); };
Expr            :   Term                                                { $$ = $1; } ;
Term            :   Term '*' Factor                                     { $$ = doMult($1, $3); } ;
Term            :   Term '/' Factor                                     { $$ = doDiv($1, $3); } ;
Term            :   Factor                                              { $$ = $1; } ;
Factor          :   Primary                                             { $$ = $1;};
Primary         :   '-'Primary                                              { $$ = doUnaryMinus($1);};

Primary         :   IntLit                                              { $$ = doIntLit(yytext); };
Primary         :   Ident                                               { $$ = doRval(yytext); };
Id              :   Ident                                               { $$ = strdup(yytext);}

this is my yacc grammar. i am trying to get a unary minus to work. x-- for example.

however when I try to run it on my test file

int num1;    
int num2;  
int num3;   
int num4;

num3 = 100;    
num4 = 200;   
num3 = num4 / num3;  
num1 = 1;   
num1 = num3-num1;  
num1--;

print num3;   
print num4;   
print num1;

I get a yyerror at the line num1--;

yyerror is incredibly vague in any details I can find about it. I can only find that it is called when it encounters an error in input. I dont know whether that error comes from my misunderstanding of how I am supposed to write my grammar, or what. I have a program that points to the illegal character and it says that the issue is coming from the first '-' symbol in the line. I would like any ideas on where to look to find my answer or if you see an error.

this is my lex file:

%{
#include "yaccExample.h"
#include "y.tab.h"

#define YY_INPUT(buf,result,max_size) \
    { int c = GetSourceChar(); \
          result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
        }

%}


letter [A-Za-z]
digit [0-9]

%%
if                              {return IF;}
int                             {return Int;}
print                           {return Write;}
{letter}({letter}|{digit})*     {return Ident;}
{digit}{digit}*                 {return IntLit;}
\=\=                            {return EQ;}
\-\-                            {return UM;}
\+\+                            {return UP;}
\>\=                            {return GTE;}
\<\=                            {return LTE;}
\=                              {return '=';}
\+                              {return '+';}
\*                              {return '*';}
\;                              {return ';';}
\{                              {return '{';}
\}                              {return '}';}
\(                              {return '(';}
\)                              {return ')';}

[ ]                             {}
\t                              {}
\r                              {}
\n                              {}

.               {WriteIndicator(GetCurrentColumn());
                   WriteMessage("Illegal Character in lex");}

%%


yywrap () {
}
هل كانت مفيدة؟

المحلول

The problem is a misunderstanding of terminology. Unary minus means a minus sign alone preceding a primary, as per your grammar.

Primary         :   '-'Primary 

The correct test code for your grammar looks like this. It should compile correctly.

num1 = -99;  
num1 = -num3;
num1 = -(num3-num1);  

The operator '--' is called decrement and does not appear in your grammar. If you need to compile a decrement operator, you will have to add it to your grammar.

نصائح أخرى

yacc has only limited support for debugging your grammar. One thing that often helps in cases like this is defining the YYDEBUG preprocessor symbol and setting the yydebug global to non-zero. This will cause a dump to stdout of all the tokens scanned and shifted and rules reduced while parsing, which can help.

Add:

#ifdef YYDEBUG
    extern int yydebug;
    yydebug = 1;
#endif

to your main function (or possibly use a command line switch to set yydebug), and compile all of your source files with -DYYDEBUG

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top