我正在使用Flex / Lex为法语的通用算法代码创建小型编译器,我不知道它的真正概念和一些基本符号...
这里是Flex代码:
%{
#include "MiniCompil.tab.h"
#include<stdio.h>
%}
espace [" "]
chiffre [0-9]
lettre [a-z A-Z]
Id {lettre}({lettre}|{chiffre})*
Int {chiffre}
Rl {Int}/.{chiffre}
Nb {chiffre}*
Char {lettre}
CDC {lettre}+
%%
{Nb} {yylval.entier=atof(yytext);return(NB);}
{Id} {yylval.chaine=strdup(yytext);return(ID);}
{ Rl } {yylval.reel=atof(yytext);return(RL);}
{ Int } { yylval.entier=atof(yytext); return(INT);}
{ Char } {yylval.chaine=strdup(yytext);return(CHAR);}
{Cdc } {yylval.chaine=strdup(yytext);return(CDC);}
{Bool } {yylval.chaine=strdup(yytext);return(BOOL);}
Algorithme {yylval.chaine=strdup(yytext);return(ALGORITHME);}
Debut {yylval.chaine=strdup(yytext);return(DEBUT);}
Fin {yylval.chaine=strdup(yytext);return(FINN);}
Debut {yylval.chaine=strdup(yytext);return(DEBUTF);}
FinF {yylval.chaine=strdup(yytext);return(FINF);}
Variables {yylval.chaine=strdup(yytext);return(VARIABLES);}
Fonction {yylval.chaine=strdup(yytext);return(FONCTION);}
Procedure {yylval.chaine=strdup(yytext);return(PROCEDURE);}
Var {yylval.chaine=strdup(yytext);return(VAR);}
Si {yylval.chaine=strdup(yytext);return(SI);}
Sinon {yylval.chaine=strdup(yytext);return(SINON);}
Alors {yylval.chaine=strdup(yytext);return(ALORS);}
Finsi {yylval.chaine=strdup(yytext);return(FINSII);}
Pour {yylval.chaine=strdup(yytext);return(POUR);}
A {yylval.chaine=strdup(yytext);return(A);}
Pas {yylval.chaine=strdup(yytext);return(PAS);}
Faire {yylval.chaine=strdup(yytext);return(FAIRE);}
FinPour {yylval.chaine=strdup(yytext);return(FINPOUR);}
Tantque {yylval.chaine=strdup(yytext);return(TANTQUE);}
FinTq {yylval.chaine=strdup(yytext);return(FINTQ);}
Repeter {yylval.chaine=strdup(yytext);return(REPETER);}
Jusqua {yylval.chaine=strdup(yytext);return(JUSQUA);}
Selon {yylval.chaine=strdup(yytext);return(SELON);}
Autres {yylval.chaine=strdup(yytext); return(AUTRES);}
Sin {yylval.chaine=strdup(yytext);return(SIN);}
Cos {yylval.chaine=strdup(yytext);return(COS);}
Tan {yylval.chaine=strdup(yytext);return(TAN);}
Log {yylval.chaine=strdup(yytext);return(LOG);}
Mod {yylval.chaine=strdup(yytext);return(MOD);}
Div {yylval.chaine=strdup(yytext);return(DIV);}
Lire {yylval.chaine=strdup(yytext); return(LIRE);}
Ecrire {yylval.chaine=strdup(yytext);return(ECRIRE);}
"(" return(OV);
")" return(FER);
";" return(PVER);
"," return(VER);
"+" return(PLUS);
"*" return(FOIS);
"-" return(MOINS);
"<" return(INF);
">" return(SUP);
"<=" return(INFEG);
">=" return(SUPEG);
"<-" return(AFFEC);
"==" return(EGAL);
"<>" return(DIFF);
"And" return(AND);
"Or" return(OR);
":" return(DP);
["]["] return(DQ);
[']['] return(UQ);
{espace}+
"\n" return(FIN);
"." return(ERREUR);
%%
当我在命令行上运行代码时,出现以下错误:
MiniCompil.l:78: unrecognized rule
MiniCompil.l:78: fatal parse error
第78行代表写在其上的代码的最后一行%% ...
代码有什么问题?
问题出在从第17行开始的五行中:
{ Rl } {yylval.reel=atof(yytext);return(RL);}
您不能在{...}
宏扩展内放置空格。这使(f)lex感到困惑。该规则和接下来的四个规则必须写成没有多余的空格:
{Rl} {yylval.reel=atof(yytext);return(RL);}
而且,您的许多宏定义都是错误的。您应该重新读取flex manual page on the syntax of patterns。例如,
espace [" "]
定义一个可以识别空格或双引号的宏。 (双引号在模式中出现两次的事实没有任何区别。)
类似地,模式
lettre [a-z A-Z]
将识别字母或空格字符。
确实,您不需要所有这些宏,因为(f)lex已经为您提供了简单的自文档命名字符类:
[[:digit:]]
-您定义为{chiffre}
[[:alpha:]]
-{lettre}
的正确版本>[[:blank:]]
—空格或制表符,可能是您所指的{espace}