gpt4 book ai didi

c - Flex 和 Bison 代码 - 总是有语法错误

转载 作者:太空宇宙 更新时间:2023-11-04 01:44:21 25 4
gpt4 key购买 nike

首先我要说的是,我对 Flex 和 Bison 还很陌生,我有点困惑。有一个学校项目希望我们使用 Flex 和 Bison 为某种 CLIPS 语言创建一个编译器。我的代码有很多问题,但最主要的是,无论我输入什么,我都会看到语法错误,而结果应该是别的东西。理想的情况是完全适用于 CLIPS 语言。例如,当我写“4”时出现语法错误。阅读我的代码也许会让您更好地理解这一点。如果我写“test 3 4”,它不会显示语法错误,但会将其视为未知标记,这又是错误的……我完全迷路了。代码是学校的原型(prototype),我们需要做一些修改。如果您有任何问题,请随时提出。谢谢你!P.S.:不要介意评论,它们是希腊语。弹性代码:

%option noyywrap


/* Kwdikas C gia orismo twn apaitoumenwn header files kai twn metablhtwn.
Otidhpote anamesa sta %{ kai %} metaferetai autousio sto arxeio C pou
tha dhmiourghsei to Flex. */

%{

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* Header file pou periexei lista me ola ta tokens */
#include "token.h"

/* Orismos metrhth trexousas grammhs */
int line = 1;

%}


/* Onomata kai antistoixoi orismoi (ypo morfh kanonikhs ekfrashs).
Meta apo auto, mporei na ginei xrhsh twn onomatwn (aristera) anti twn,
synhthws idiaiterws makroskelwn kai dysnohtwn, kanonikwn ekfrasewn */
/* dimiourgia KE simfona me ta orismata tis glossas */

DELIMITER [ \t]+
INTCONST [+-]*[1-9][0-9]*
VARIABLE [?][A-Za-z0-9]*
DEFINITIONS [a-zA-Z][-|_|A-Z|a-z|0-9]*
COMMENTS ^;.*$


/* Gia kathe pattern (aristera) pou tairiazei ekteleitai o antistoixos
kwdikas mesa sta agkistra. H entolh return epitrepei thn epistrofh
mias arithmhtikhs timhs mesw ths synarthshs yylex() */
/* an sinantisei diaxoristi i sxolio to agnoei, an sinantisei akeraio,metavliti i orismo ton emfanizei. se kathe alli periptosi ektiponei oti den anagnorizei to token, ti grammi pou vrisketai kai to string pou dothike */

%%

{DELIMITER} {;}
"bind" { return BIND;}
"test" { return TEST;}
"read" { return READ;}
"printout" { return PRINTOUT;}
"deffacts" { return DEFFACTS;}
"defrule" { return DEFRULE;}
"->" { return '->';}
"=" { return '=';}
"+" { return '+';}
"-" { return '-';}
"*" { return '*';}
"/" { return '/';}
"(" { return '(';}
")" { return ')';}
{INTCONST} { return INTCONST; }
{VARIABLE} { return VARIABLE; }
{DEFINITIONS} { return DEFINITIONS; }
{COMMENTS} {;}
\n { line++; printf("\n"); }
.+ { printf("\tLine=%d, UNKNOWN TOKEN, value=\"%s\"\n",line, yytext);}
<<EOF>> { printf("#END-OF-FILE#\n"); exit(0); }

%%

/* Pinakas me ola ta tokens se antistoixia me tous orismous sto token.h */

char *tname[11] = {"DELIMITER","INTCONST" , "VARIABLE", "DEFINITIONS", "COMMENTS", "BIND", "TEST", "READ", "PRINTOUT", "DEFFACTS", "DEFRULE"};

Bison 代码:

%{
/* Orismoi kai dhlwseis glwssas C. Otidhpote exei na kanei me orismo h arxikopoihsh
metablhtwn & synarthsewn, arxeia header kai dhlwseis #define mpainei se auto to shmeio */
#include <stdio.h>
#include <stdlib.h>
int yylex(void);
void yyerror(char *);
%}

/* Orismos twn anagnwrisimwn lektikwn monadwn. */
%token INTCONST VARIABLE DEFINITIONS PLUS NEWLINE MINUS MULT DIV COM BIND TEST READ PRINTOUT DEFFACTS DEFRULE

%%

/* Orismos twn grammatikwn kanonwn. Kathe fora pou antistoixizetai enas grammatikos
kanonas me ta dedomena eisodou, ekteleitai o kwdikas C pou brisketai anamesa sta
agkistra. H anamenomenh syntaksh einai:
onoma : kanonas { kwdikas C } */
program:
program expr NEWLINE { printf("%d\n", $2); }
|
;
expr:
INTCONST { $$ = $1; }
| VARIABLE { $$ = $1; }//prosthiki tis metavlitis
| PLUS expr expr { $$ = $2 + $3; }//prosthiki tis prosthesis os praksi
| MINUS expr expr { $$ = $2 - $3; } //prosthiki tis afairesis os praksi
| MULT expr expr { $$ = $2 * $3; }//prosthiki tou pollaplasiasmou os praksi
| DIV expr expr { $$ = $2 / $3; }//prosthiki tis diairesis os praksi
| COM { $$ = $1; }//prosthiki ton sxolion
| DEFFACTS expr { $$ = $2; }//prosthiki ton gegonoton
| DEFRULE expr { $$ = $2; }//prosthiki ton kanonon
| BIND expr expr { $$ = $2;}//prosthiki tis bind
| TEST expr expr { $$ = $2 ;}//prosthiki tis test
| READ expr expr { $$ = $2 ;}//prosthiki tis read
| PRINTOUT expr expr { $$ = $2 ;}//prosthiki tis printout
;

%%



/* H synarthsh yyerror xrhsimopoieitai gia thn anafora sfalmatwn. Sygkekrimena kaleitai
apo thn yyparse otan yparksei kapoio syntaktiko lathos. Sthn parakatw periptwsh h
synarthsh epi ths ousias typwnei mhnyma lathous sthn othonh. */
void yyerror(char *s) {
fprintf(stderr, "Error: %s\n", s);
}


/* H synarthsh main pou apotelei kai to shmeio ekkinhshs tou programmatos.
Sthn sygkekrimenh periptwsh apla kalei thn synarthsh yyparse tou Bison
gia na ksekinhsei h syntaktikh analysh. */
int main(void) {
yyparse();
return 0;
}

token 文件:

#define DELIMITER 1
#define INTCONST 2
#define VARIABLE 3
#define DEFINITIONS 4
#define COMMENTS 5
#define BIND 6
#define TEST 7
#define READ 8
#define PRINTOUT 9
#define DEFFACTS 10
#define DEFRULE 11

生成文件:

all:
bison -d simple-bison-code.y
flex mini-clips-la.l
gcc simple-bison-code.tab.c lex.yy.c -o B2
./B2
clean:
rm simple-bison-code.tab.c simple-bison-code.tab.h lex.yy.c B2

最佳答案

  1. 您的顶级规则是:

    program:
    program expr NEWLINE

    除非解析器看到 NEWLINE,否则不会成功 token 。但它永远不会看到一个,因为你的词法扫描器永远不会发送一个;当它看到换行符时,它会增加行数但不返回任何内容。

  2. 您的所有标记都被视为无效,因为您的词法扫描器使用其自己的标记值定义。你不应该那样做。解析器生成器(bison/yacc)将生成一个包含正确定义的头文件;也就是说,它期望看到的值。

  3. 还有其他各种问题,可能比我注意到的要多。最重要的是你不应该调用 exit(0)<<EOF>>规则,因为这意味着解析器永远不会成功;在传递 EOF token 之前,它不会成功。事实上,你通常不应该有 <<EOF>>规则;默认操作是返回 0,这是唯一有意义的操作。

  4. 此外,'->'不是正确的 C 文字。如果您启用了编译器警告 ( -Wall ),编译器会提示它,您应该始终这样做,即使您正在编译生成的代码。

  5. 而你的扫描仪的最后一个模式,旨在触发坏 token ,是 .+ , 这将匹配整行,而不仅仅是错误的字符。由于 (f)lex 扫描器接受具有最长匹配的模式,因此您的大多数其他模式将永远不会匹配。 (Flex 通常会警告您有关无法匹配的模式。您没有收到这样的警告吗?)

    后备模式应该是 .|\n , 尽管您可以使用 .如果您绝对确定每个换行符都将符合某些规则。我喜欢用 %option nodefault ,如果有一些可能的输入不符合任何规则,这将导致 flex 警告我。

关于c - Flex 和 Bison 代码 - 总是有语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56619774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com