Lex和Yacc分段错误
我正在尝试使用lex和yacc为mini-c编写解析器。在单线输入的情况下,它工作得很好;在多线输入的情况下,它抛出了一个分段错误。运行GDB没有帮助 c、 l文件Lex和Yacc分段错误,c,linux,yacc,lex,C,Linux,Yacc,Lex,我正在尝试使用lex和yacc为mini-c编写解析器。在单线输入的情况下,它工作得很好;在多线输入的情况下,它抛出了一个分段错误。运行GDB没有帮助 c、 l文件 alpha [a-zA-Z] digit [0-9] %{ #include <stdlib.h> void yyerror(char *); #include "y.tab.h" %} %% [ \t] ; [ \n] { yylineno = yylineno + 1;} int return I
alpha [a-zA-Z]
digit [0-9]
%{
#include <stdlib.h>
void yyerror(char *);
#include "y.tab.h"
%}
%%
[ \t] ;
[ \n] { yylineno = yylineno + 1;}
int return INT;
float return FLOAT;
char return CHAR;
void return VOID;
double return DOUBLE;
for return FOR;
while return WHILE;
if return IF;
else return ELSE;
printf return PRINTF;
struct return STRUCT;
^"#include ".+ ;
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
"<=" return LE;
">=" return GE;
"==" return EQ;
"!=" return NE;
">" return GT;
"<" return LT;
"." return DOT;
\/\/.* ;
\/\*(.*\n)*.*\*\/ ;
. return yytext[0];
%%
alpha[a-zA-Z]
数字[0-9]
%{
#包括
无效错误(字符*);
#包括“y.tab.h”
%}
%%
[\t];
[\n]{yylineno=yylineno+1;}
int返回int;
浮动返回浮动;
字符返回字符;
无效返回无效;
双回双回;
为了回报;
当返回时;
如果返回如果;
否则返回其他;
printf返回printf;
结构返回结构;
^“#包括”+;
{digit}+返回数值;
{alpha}({alpha}{digit})*返回ID;
“=”返回GE;
“==”返回等式;
“!=”返回NE;
“>”返回GT;
"
如果您使用的是lex(1)而不是flex(1),yytext
是char[]
,而不是char*
但是,如果可能的话,您当然应该使用flex(1)。从1987年前后发布以来,它就一直处于领先地位。lex(1)现在只是一个历史奇观。您使用的是最新版本的lex和yacc吗?是的。今天从终端重新安装。如果您给出一个输入失败的示例,可能会有所帮助。输入:int a;通过但int a;int b;抛出分段错误是的。您是正确的。我可以知道它有什么区别,以及为什么它对单个lin正确工作吗e输入。您能澄清一下吗?您想知道char[]
和char*
之间的区别吗?
%{
#include <stdio.h>
#include <stdlib.h>
int yylex(void);
extern FILE *fp;
extern FILE *yyin;
extern int yylineno;
extern char* yytext;
%}
%token INT FLOAT CHAR DOUBLE VOID
%token FOR WHILE
%token IF ELSE PRINTF
%token STRUCT
%token NUM ID
%token INCLUDE
%token DOT
%right '='
%left AND OR
%left '<' '>' LE GE EQ NE LT GT
%%
start: Function
| Declaration
;
/* Declaration block */
Declaration: Type Assignment ';'
| Assignment ';'
| FunctionCall ';'
| ArrayUsage ';'
| Type ArrayUsage ';'
| StructStmt ';'
| error
;
/* Assignment block */
Assignment: ID '=' Assignment
| ID '=' FunctionCall
| ID '=' ArrayUsage
| ArrayUsage '=' Assignment
| ID ',' Assignment
| NUM ',' Assignment
| ID '+' Assignment
| ID '-' Assignment
| ID '*' Assignment
| ID '/' Assignment
| NUM '+' Assignment
| NUM '-' Assignment
| NUM '*' Assignment
| NUM '/' Assignment
| '\'' Assignment '\''
| '(' Assignment ')'
| '-' '(' Assignment ')'
| '-' NUM
| '-' ID
| NUM
| ID
;
/* Function Call Block */
FunctionCall : ID'('')'
| ID'('Assignment')'
;
/* Array Usage */
ArrayUsage : ID'['Assignment']'
;
/* Function block */
Function: Type ID '(' ArgListOpt ')' CompoundStmt
;
ArgListOpt: ArgList
|
;
ArgList: ArgList ',' Arg
| Arg
;
Arg: Type ID
;
CompoundStmt: '{' StmtList '}'
;
StmtList: StmtList Stmt
|
;
Stmt: WhileStmt
| Declaration
| ForStmt
| IfStmt
| PrintFunc
| ';'
;
/* Type Identifier block */
Type: INT
| FLOAT
| CHAR
| DOUBLE
| VOID
;
/* Loop Blocks */
WhileStmt: WHILE '(' Expr ')' Stmt
| WHILE '(' Expr ')' CompoundStmt
;
/* For Block */
ForStmt: FOR '(' Expr ';' Expr ';' Expr ')' Stmt
| FOR '(' Expr ';' Expr ';' Expr ')' CompoundStmt
| FOR '(' Expr ')' Stmt
| FOR '(' Expr ')' CompoundStmt
;
/* IfStmt Block */
IfStmt : IF '(' Expr ')'
Stmt
;
/* Struct Statement */
StructStmt : STRUCT ID '{' Type Assignment '}'
;
/* Print Function */
PrintFunc : PRINTF '(' Expr ')' ';'
;
/*Expression Block*/
Expr:
| Expr LE Expr
| Expr GE Expr
| Expr NE Expr
| Expr EQ Expr
| Expr GT Expr
| Expr LT Expr
| Assignment
| ArrayUsage
;
%%
#include<ctype.h>
int count=0;
int main(int argc, char *argv[])
{
yyin = fopen(argv[1], "r");
if(!yyparse())
printf("\nParsing complete\n");
else
printf("\nParsing failed\n");
fclose(yyin);
return 0;
}
yyerror(char *s) {
printf("%d : %s %s\n", yylineno, s, yytext );
}
extern char* yytext;