compiler-errors - 如何修复Flex代码生成器上的 'unrecognized rule'和 'Fatal parse '错误?

标签 compiler-errors compilation compiler-construction flex-lexer

我正在使用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}的含义
  • {Id}可以写为[[:alpha:]][[:alnum:]]

    使用标准正则表达式的好处是,它可以使您的模式对任何阅读您的代码的人都清晰可见,而不必查找宏定义扩展到的内容(特别是当宏定义中包含错误时)。

    最后,当您将{Id}模式放在所有这些关键字之前时,可以保证扫描程序无法识别任何关键字,因为首选文件中第一个出现的模式({Id})。有关详细信息,请参见the next chapter in the flex manual。 (这也适用于其他许多模式,例如{Char}{CDC}。坦率地说,我根本不理解您对这些模式的意图。)

    而且还有许多其他错误,flex将检测其中的一些错误。例如,未定义宏{Bool}{Rl}的定义在许多级别上都是错误的。 (您的意思是\.吗?即使这样,之前和之后的模式部分也是错误的。为什么您觉得需要两个都表示“一位数字”的宏?)

    关于compiler-errors - 如何修复Flex代码生成器上的 'unrecognized rule'和 'Fatal parse '错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59458955/

    相关文章:

    android - Android NDK : Compiling errors using libpcap for Android - functions “not declared in this scope”

    c# - 编译错误 : 'x' conflicts with the declaration of 'y.x' ?

    java - 从命令行运行java项目

    c++ - 用于空间和性能提升的位对齐

    php - Hiphop for PHP 等工具如何处理异构数组?

    android - 在 build.gradle 中编译具有 useLibrary 'app:transformClassesWithDexForDebug' 的项目时出现 'org.apache.http.legacy' 错误

    java - 我可以构建并运行我的项目,但我的 IDE 一直显示错误

    c++ - GCC C++编译选项-mcpu

    找不到-lpthread

    c++ - 编译器如何知道物理地址的对齐方式?