Reputation: 4798
I want to sum the numbers on a single line.
e.g.
1 2 3 '\n' => prints 6
1 '\n' => prints 1
0 '\n' => prints 0
'\n' => prints 0
For this purpose, I have figured that following regular expression would suffice :
((NUMBER)* "\n")+
I make use of lex/yacc combo for it. I understand that lex would suffice but this is just a small throwaway program specifically to know how yacc works.
I made the following grammar for the above regular expression :
lines -> lines line
lines -> line
line -> numbers '\n'
numbers -> numbers NUMBER
numbers -> (empty)
But putting the input as 1 (enter)
generates segmentation fault. I cannot understand why it is happening.
The yacc program (in.y) is:
%{
#include <stdio.h>
extern int yylex();
int yyerror(const char *s);
%}
%union
{
int num;
char ch;
}
%token <num> NUMBER
%type <num> numbers
%start lines
%%
lines : line lines ;
| line ;
;
line : numbers '\n' { printf("%s\n", $1); }
numbers : NUMBER numbers { $$ = $1 + $2; }
| NUMBER { $$ = $1; }
;
%%
int main()
{
return( yyparse() );
}
int yyerror(const char * s)
{
fprintf( stderr, "%s\n", s );
}
And the lex program is (in.l):
%{
#include "y.tab.h"
//extern YYSTYPE yylval;
%}
%%
[0-9]+ { yylval.num = atoi(yytext); return NUMBER; }
\n { return yylval.ch = yytext[0]; }
. { ; }
%%
int yywrap()
{
return 1;
}
To be exhaustive, I am running it under Cygwin emulating using flex/bison as:
yacc -d in.y; flex in.l; gcc y.tab.c lex.yy.c
Upvotes: 1
Views: 2555
Reputation: 641
If you compile your code with gcc flag -s
and then run your program (a.out
) using valgrind (a memory error detector), you would discover that the problem is on the printf
.
So when you have a %s
argument on the printf
, it will be waiting for a pointer to a null-terminated string. However, you are passing an integer. When printf
is accessing it will start at the address on $1
and the continue till a \0
(null char) appear in the memory.
You just want to print a simple integer. Replace the %s
with %d
and it will work.
The entire rule looks like that:
line : numbers '\n' { printf("%d\n", $1); }
Upvotes: 3