我想把数字加在一行上。
e.g。
1 2 3 '\n' => prints 6
1 '\n' => prints 1
0 '\n' => prints 0
'\n' => prints 0
为此,我认为遵循正则表达式就足够了:
((NUMBER)* "\n")+
我使用lex / yacc组合。我明白lex就足够了,但这只是一个小小的一次性程序,专门用来了解yacc是如何工作的。
我为上面的正则表达式做了以下语法:
lines -> lines line
lines -> line
line -> numbers '\n'
numbers -> numbers NUMBER
numbers -> (empty)
但是将输入设为1 (enter)
会产生分段错误。我无法理解为什么会这样。
yacc程序(in.y)是:
%{
#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 );
}
而且lex程序是(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;
}
为了详尽无遗,我在Cygwin下运行它,使用flex / bison模拟:
yacc -d in.y; flex in.l; gcc y.tab.c lex.yy.c
答案 0 :(得分:3)
如果使用gcc标志-s
编译代码然后使用valgrind(内存错误检测器)运行程序(a.out
),您会发现问题出在{{1}上}。
因此,当printf
上有%s
个参数时,它将等待指向以null结尾的字符串的指针。但是,您传递的是整数。当printf
访问时,它将从printf
上的地址开始,并继续直到$1
(空字符)出现在内存中。
您只想打印一个简单的整数。将\0
替换为%s
即可。
整个规则看起来像是:
%d