Solved

yylineno in error recovery

Posted on 2009-04-02
7
1,216 Views
Last Modified: 2012-08-13
Hello,

How can i print the number of line where there is a syntax error using yylineno ?

I did the following thing but i constantly get "Number 1 : syntax error"

void yyerror( const char *msg )
{
  printf("Number %d: %s\n", yylineno, msg);
}


Thanks in advance for any help !
0
Comment
Question by:unknown_
  • 3
  • 3
7 Comments
 
LVL 40

Accepted Solution

by:
mrjoltcola earned 500 total points
ID: 24055100
In my grammars I declare a variable called line and I increment it in token rules

Below is an example, my language supports // comments so I increment it in that rule as well.
If you have multiline comments (like C) you'll need to do the same in that rule.




int line = 0;
 

%%
 

\n              line++;

\/\/.*\n        line++;    /* COMMENT */

Open in new window

0
 

Author Comment

by:unknown_
ID: 24055275
I still have the same problem

my input is :
int x ;

Error


But i get :

VARIABLE
rule 15
INT_VARIABLE
Unknown character [E]
Line 0: syntax error

%{

	

#include "y.tab.h"
 

int line = 0;
 

%}
 

letter          [a-zA-Z_]

letter_digit     [a-zA-Z0-9_]	

comment 	"/*"."*/"

digit 		[0-9]

variable	[a-z_]({letter_digit})*

integer		{digit}+

float		{digit}+(\.{digit}+)?(e[+ -]?{digit}+)?

string           \"[^"\n]*["\n]

whitespace	[ \t\n]

ws              {whitespace}+
 
 
 

%%
 

"+"			{ return('+'); }

"-"			{ return('-'); }

"("			{ return('('); }

")"			{ return(')'); }

","			{ return(','); }

";"			{ return(SEMICOLON); }

"="			{ return('='); } 

"*"			{ return('*'); }

"/"			{ return('/'); }

"%"			{ return('%'); }

"||"		        { return(OR2); }

"&&"		        { return(AND2); }

"|"			{ return(OR); }

"&"			{ return(AND); }

"if"                    { return(IF);       }

"else"                  { return(ELSE);     }

"do"                    { return(DO);       }

"int"                   { return(INT);      }

"return"                { return(RETURN);   }

"void"                  { return(VOID);     }

"float"                 { return(FLOAT);    }

"while"                 { return(WHILE);   }
 
 

{string} { 

 printf("STRING\n",yylval.sval);

 return(STRING);

 }

  

  

{variable}* { 

   printf("VARIABLE\n",yylval.sval);

 return(VARIABLE);

 }
 

{digit}+ {  

  yylval.ival = atoi(yytext);

   printf("INTEGER\n",yylval.ival);

 return(INTEGER);

 }
 

{float}+ {

  yylval.ival = atoi(yytext);

   printf("FLOAT\n",yylval.ival);

   return (FLOAT);

 }
 

{ws} {};

[ ] {} ;
 

\n              line++;

\/\/.*\n        line++;    /* COMMENT */
 

  

[ \t\n\r]            /* skip whitespace */

  

.                    { printf("Unknown character [%c]\n",yytext[0]);

		       return UNKNOWN;    }

 

%%
 
 
 
 
 
 
 
 
 
 

%{

#include <stdio.h>

#include <stdlib.h>

#include <string.h>
 

	

#define YYDEBUG 1
 
 
 
 

extern int  yyparse();

 extern int yylex();

 extern int line  ;
 
 

extern FILE *yyin;	
 

int yywrap()

 {

    return 1;

 }

/*

void yyerror(const char *s)

 {

    fflush(stdout);

    printf("\n%*s\n%*s\n", s);

 }*/
 
 
 

// void yyerror (char *s) {fprintf (stderr, "%s\n", s);}

/*void yyerror(char *s) 

{ 

  fprintf(stderr,"%s\n",s,"%d", yylineno); 

  return; 

} 

*/
 

void yyerror( const char *msg )

{

  printf("Line %d: %s\n",line, msg); 

}
 
 

%}

 

%start goal
 

%union {

	int ival;

	char * sval;

}

 

%token <sval> IDENTIFIER

%token <sval> VARIABLE

%token <ival> INTEGER

 /*%token <ival> FLOAT*/

%token <sval> STRING

%token <sval> LITERAL

%token <sval> UNKNOWN 

%token <sval> PLUS

%token <sval> MINUS

%token <sval> TIMES

%token <sval> SLASH

%token <sval> LPAREN

%token <sval> RPAREN

%token <sval> SEMICOLON

%token <sval> COMMA

%token <sval> EQL

%token <sval> OR 

%token <sval> OR2

%token <sval> AND

%token <sval> AND2
 
 

/* keywords */

%token <sval> IF

%token <sval> ELSE

%token <sval> DO

%token <sval> INT

%token <sval> RETURN

%token <sval> VOID

%token <sval> FLOAT

%token <sval> WHILE
 

%type <sval> goal

%type <ival> expression

%type <ival> term 

%type <ival> factor 

%type <sval> ifstatement

%type <sval> whilestatement

%type <sval> dostatement

%type <sval> variable_list

%type <sval> variable 
 
 
 

%%
 

goal			: statement_list;

                        ;
 

statement_list: { /*empty*/ }

                | statement_list statement

		;
 

statement : declaration_statement

          | ifstatement 

          | whilestatement

          | variable '=' expression SEMICOLON 

          | dostatement 

          ;
 

declaration_statement : INT variable_list SEMICOLON {printf("INT_VARIABLE\n");}

                      | FLOAT variable_list SEMICOLON {printf("FLOAT_VARIABLE\n");}

                      ;
 
 
 

expression		:	term '+' term {printf("RULE 1\n");} {$$ = $1 + $3;}

|	term '-' term {printf("rule 2\n");} {$$ = $1 - $3;}

|	term {printf("rule 3\n");}  {$$ = $1;}   ;
 

term			:	factor '*' factor  {printf("rule 4\n");} {$$ = $1 * $3;}

|	factor '/' factor  {printf("rule 5\n");} {$$ = $1 / $3;} 

|	factor {printf("rule 6\n");}  {$$ = $1;}  ;
 

factor			:	variable {printf("rule 7\n");} 

|	INTEGER {printf("rule 8\n");} 

|	FLOAT {printf("rule 9\n");} 

|	STRING {printf("rule 10\n");}

|	'(' expression ')' {printf("rule 11\n");};
 

ifstatement		:	IF '(' expression ')' goal ELSE goal SEMICOLON {printf("rule: IF_ELSE_STATEMENT\n");}

|	IF '(' expression ')' goal {printf("rule: IF_STATEMENT\n");};
 

whilestatement	:	WHILE '(' expression ')' goal {printf("rule: WHILE_STATEMENT\n");};	

		

dostatement : DO expression WHILE '(' expression ')'   {printf("rule DO_STATEMENT\n");} ;
 
 

variable : VARIABLE {printf("rule var2\n");} {$$= $1; };
 

	

variable_list : VARIABLE {printf("rule 15\n");}  {$$= $1; }

|  	variable ',' variable_list {printf("rule 16\n");}  ;
 
 

%%
 

#include "lex.yy.c"
 

main(int argc,char *argv[])

{

 if(argc<1)

   {

    printf("Please specify the input file\n");

    exit(0);

   }

 FILE *fp=fopen(argv[1],"r");

 if(!fp)

   {

     printf("couldn't open file for reading\n");

     exit(0);

   }

 yyin=fp;

 

 do {

   yyparse();

 }while (!feof(yyin));

 

 fclose(fp);

}

 

 

Open in new window

0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24055771
You now have multiple lexer rules for the same thing, whitespace and newlines.

ws -> whitespace
as well as the ones I just gave you both map to the same thing.

Also:

[ \t\n\r]            /* skip whitespace */


Review your lexer rules, you don't want a lot of the same thing, for one it is confusing, plus it will ignore the redundant rules. Combine down to unique rules.

You said your input  is:

my input is :
int x ;

Error


How in your lexer grammar are you handling "Error". It looks like your lexer rule for "variable" does not allow a variable to start with an uppercase letter. So when it sees "Error", which is in your sample, it handles it with the default rule, which prints "Unknown character"
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:unknown_
ID: 24058065
How can i do the same rule for single line comment ?
I mean about the // comment is \/\/.*\n        line++;  

I tried something similar for /* comment */  but is not valid

\/* .* */\

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 24058139
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24062296
@unknown_: You have 5 open C questions all on different areas of your compiler, but some are overlapping a bit. Can I suggest you wrap several of them up so we can narrow down. Too much overlap becomes confusing for us to track, and can also be suspect to moderator's getting involved.

Lets keep the questions to specific topics, and accomplish 1 or 2 things at a time? I am less willing to work with you on 5 threads at once.
0
 

Author Closing Comment

by:unknown_
ID: 31566025
Thanks !

Can you please have a look to that question :
http://www.experts-exchange.com/Programming/Languages/C/Q_24305800.html

Thanks !

0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
C# GridRow get Old/New Value 1 55
Sum Column in GridView 3 42
LINQ - C# to VB convertion 12 46
User Authentication using Digital Certificate 2 20
Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.

914 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now