#c #linux #parsing #yacc #lex
#c #linux #синтаксический анализ #yacc #лекс
Вопрос:
Я пишу код для синтаксического анализатора (синтаксического анализатора). Я получаю сообщение об ошибке, но я не знаю, что вызывает эту ошибку.
syntax_analyzer.y
%{
#include<stdio.h>
#include<stdlib.h>
extern void yyerror(char *);
extern FILE *yyin;
extern int yylineno;
extern char *yytext;
%}
%token FOR EQUAL INC DEC alpha num GE LE GT LT NE AND OR END IF ELSE WHILE DO SWITCH CASE BREAK DEFAULT VOID INT FLOAT CHAR SHORT DOUBLE
%token LPAREN RPAREN LCURLY RCURLY COMMA SEMICOLON ASSIGN
%token PLUS MINUS MULT DIVIDE XOR
%left PLUS MINUS MULT DIVIDE
%right ASSIGN
%right XOR
%nonassoc UMINUS
%left LT GT LE GE EQUAL NE
%left AND OR
%start STRT
%%
STRT: S END {printf("nAcceptedn"); exit(0);}
;
S: STATEMENT S
|STATEMENT
;
STATEMENT: DATA_TYPE alpha LPAREN RPAREN LCURLY STATEMENT RCURLY
|IF LPAREN F RPAREN LCURLY STATEMENT RCURLY %prec IF
|IF LPAREN F RPAREN LCURLY STATEMENT RCURLY ELSE LCURLY STATEMENT RCURLY
|FOR LPAREN EXP SEMICOLON F SEMICOLON EXP RPAREN LCURLY STATEMENT RCURLY
|WHILE LPAREN F RPAREN LCURLY STATEMENT RCURLY
|DO LCURLY STATEMENT RCURLY WHILE LPAREN F RPAREN SEMICOLON
|DATA_TYPE declare SEMICOLON
|EXP SEMICOLON
|EXP SEMICOLON STATEMENT
;
DATA_TYPE: INT | VOID | FLOAT | CHAR | SHORT | DOUBLE
;
declare: declare COMMA declare
|alpha
|alpha ASSIGN DATA_TYPE
;
F: C LOGICAL_OP C
|C
;
C: EXP RELATION_OP EXP
|EXP
;
LOGICAL_OP: AND
|OR
;
RELATION_OP: LT|
GT|
LE|
GE|
EQUAL|
NE
;
EXP: alpha ASSIGN EXP
|EXP PLUS EXP
|EXP MINUS EXP
|EXP MULT EXP
|EXP DIVIDE EXP
|EXP XOR EXP
|LPAREN EXP RPAREN
|MINUS EXP %prec UMINUS
|alpha
|DATA_TYPE
|alpha INC
|alpha DEC
;
%%
int main(int argc, char **argv){
FILE *fp1;
fp1=fopen(argv[1],"r");
yyin=fp1;
if (yyparse()==0) printf("Parsed Successfully for string %sn", yytext);
else printf("nParsing Error for string %sn", yytext);
return 0;
}
int yywrap(){
return 0;
}
void yyerror(char*s){
printf("Error: %s n", s);
}
syntax_analyzer.l
%{
#include "y.tab.h"
%}
digits [0-9]*
letters [a-zA-Z]
%%
"for" return FOR;
"if" return IF;
"else" return ELSE;
"while" return WHILE;
"do" return DO;
"switch" return SWITCH;
"case" return CASE;
"break" return BREAK;
"default" return DEFAULT;
"void" return VOID;
"int" return INT;
"float" return FLOAT;
"char" return CHAR;
"double" return DOUBLE;
"(" return LPAREN;
")" return RPAREN;
"{" return LCURLY;
"}" return RCURLY;
[0-9] return INT;
[0-9]*.?[0-9] |[0-9] return FLOAT;
("_")*{letters}("_"|{letters}|{digits})* return alpha;
[ nt] {;}
" " return PLUS;
"-" return MINUS;
"/" return DIVIDE;
"*" return MULT;
"^" return XOR;
"=" return ASSIGN;
"==" return EQUAL;
" " return INC;
"--" return DEC;
">=" return GE;
"<=" return LE;
">" return GT;
"<" return LT;
"!=" return NE;
"amp;amp;" return AND;
"||" return OR;
"$" return END;
"," return COMMA;
";" return SEMICOLON;
. return yytext[0];
%%
input.txt
void func()
{
if(a==b)
{
b=a;
}
else
{
c=a;
}
}
Правила грамматики очень просты и просты. Я постоянно получаю ошибку «Ошибка синтаксического анализа для строки b». По-видимому, я не смог выяснить, что не так. Кто-нибудь может мне помочь??
Редактировать 1: По-видимому, правила грамматики, включающие IF, требуют фигурных скобок, которых не было в моем входном файле. Это было причиной синтаксической ошибки. После этих изменений я столкнулся с бесконечным циклом при выполнении. Я не знаю, почему.
Комментарии:
1. Ваши правила синтаксического
if
анализа оператора требуют фигурных скобок вокруг подчиненного кода. Ваш пример ввода пропускает их. Так что это синтаксическая ошибка. Попробуйте добавить фигурные скобки к вашему образцу ввода или изменить грамматику, чтобы фигурные скобки не требовались.2. @TomKarzes Спасибо, что указали на это. Я думал, что проблема будет решена, но теперь выполнение переходит в бесконечный цикл.
3. Хм, не уверен насчет цикла. Похоже, что ваша грамматика требует конечного символа
$
. Вы пытались добавить a$
в конец вашего входного файла?4. @TomKarzes Охххх … глупый я. Большое спасибо.