首页 > 解决方案 > 弯曲过早的EOF

问题描述

我已经编写了这段代码来在 flex 中创建一个编译器。我使用的编辑器是 vs code 2019,当我编译代码时它在第 1 行抛出错误早熟 EOF。我不知道该怎么做,我已经看到了答案同样的问题,但他们没有解决我的问题。

//------DECLARATIONS ----
%{
    #include <stdio.h>
    #include <stlib.h>
    #include <string.h>
    #include "token.h"       

    void lexprint(char *token);
    void yyerror();
    int lineno = 1 ;  // that means that we start to count lines from 1  
'%}

 // reads only one file
/%option noyywrap 
 // shows the current inout line
%option yylineno   

 

CHARACHTER  [a-zA-Z]
DIGIT       [0-9]
NUMBER      {DIGIT}*|0
WORD        ({WORD}*|{NUMBER}*)*
VARIABLE    _?({WORD}*|{NUMBER}*)*
tab          [ \t]  




    /* -----TRANSLATION RULES  ---- */
%%


    /*KEYWORDS*/
"PROGRAM"         {lexprint(PROGRAM); return PROGRAM; } 
"FUNCTION"        {lexprint(FUNCTION); return FUNCTION;}
"VARS"           {lexprint(VARS); return VARS;}
"CHAR"           {lexprint(CHAR); return CHAR;}    
"INTEGER"         {lexprint(INTEGER); return INTEGER;}
"END_FUNCTION"     {lexprint(END_FUNCTION); return END_FUNCTION;}
"RETURN"            {lexprint(RETURN); return RETURN;}
"STARTMAIN"       {lexprint(STARTMAIN); return STARTMAIN;}
"ENDMAIN"         {lexprint(ENDMAIN); return ENDMAIN;}
"WHILE"           {lexprint(WHILE); return WHILE;}
"ENDWHILE"        {lexprint(ENDWHILE); return ENDWHILE;}
"FOR"               {lexprint(FOR); return FOR;}
"TO"                {lexprint(TO); return TO;}
"STEP"             {lexprint(STEP); return STEP;}   
"ENDFOR"             {lexprint(ENDFOR); return ENDFOR;}
"IF"                {lexprint(IF); return IF;}
"THEN"           {lexprint(THEN);return THEN;}
"ELSEIF"             {lexprint(ELSEIF); return ELSEIF;}
"ELSE"            {lexprint(ELSE); return ELSE;}
"ENDIF"          {lexprint(ENDIF); return ENDIF;}       
"SWITCH"             {lexprint(SWITCH); return SWITCH;}
"CASE"           {lexprint(CASE); return CASE;}
"DEFAULT"         {lexprint(DEFAULT); return DEFAULT;}
"ENDSWITCH"       {lexprint(ENDSWITCH); return ENDSWITCH;}
"PRINT"          {lexprint(PRINT); return PRINT;}
"BREAK"          {lexprint(BREAK); return BREAK;}

   
{VARIABLE}      {lexprint("VARIABLE\n"); return VARIABLE;}    
{NUMBER}        {lexprint("NUMBER\n"); return NUMBER;}  
{NEWLINE}       {lexprint("New Line\n"); return NEWLINE;} 
{TAB}           {}

    /*OPERATORS*/
"#"        {lexprint(hashtag); return hashtag;}
","        {lexprint(comma); return comma;}
"+"        {lexprint(syn); return syn;}
"-"        {lexprint(meion); return meion;}
"*"        {lexprint(asteriskos); return asteriskos;}
"/"        {lexprint(divison); return divison;}
"%"        {lexprint(module); return module;}
"("        {lexprint(A_parenthesi); return A_parenthesi;}
")"        {lexprint(D_parenthesi); return D_parenthesi;}
"["        {lexprint(A_aggili); return A_aggili;}
"]"        {lexprint(D_aggili); return D_aggili;}
"<"        {lexprint(A_eisagogika); return A_eisagogika;}
">"        {lexprint(D_eisagogika); return D_eisagogika;}
"!"        {lexprint(thaumastiko); return thaumastiko;}
"!="       {lexprint(diaforetiko); return diaforetiko;}
"=="       {lexprint(ison); return ison;}
"AND"      {lexprint(And); return And;}
"OR"       {lexprint(or); return or;}

"/n"       {lineno++;}
"."        {yyerror("unknown character");}




%%

  //this function prints all the token that analyzer can recognize
void lexprint(char *token){
    printf("yytext: %s\ttoken: %s\tlineno: %d\n", yytext, token_type, lineno);
}

void yyerror(char *message){
    printf("Error: \"%s\" in line %d. Token = %s\n", message, lineno, yytext);
    exit(1);
}

标签: cflex-lexer

解决方案


您的 Flex 输入中有几个错误。这些至少是其中的一些:


Flex 可以识别 C 样式的块注释 ( /* ... */),但没有记录识别 C99 样式的内联注释 ( // ...)。

如果是flex抛出错误,那么这可能就是原因。


这里有一个流浪撇号:

'%}

这个 ...

NUMBER      {DIGIT}*|0

... 匹配零长度输入。这更清楚,没有那个问题:

NUMBER      {DIGIT}+

这个 ...

WORD        ({WORD}*|{NUMBER}*)*

...根据自身定义符号WORD,它匹配零长度输入,并且它还匹配仅数字序列(但也许允许后者是有意的?)。也许你的意思是...

 WORD        ({CHARACHTER}|{NUMBER})+

...(从原件复制的“字符”的拼写错误),但如果您确实是要匹配全数字标记,那么我只会写...

 WORD        [a-zA-Z0-9]+

……,我自己。

如果您想避免匹配全数字序列,这有点棘手,除非您遵循要求第一个字符是非数字的传统路径:

 WORD        {CHARACHTER}[a-zA-Z0-9]*

这个 ...

VARIABLE    _?({WORD}*|{NUMBER}*)*

... 还匹配零长度输入和仅数字输入。假设这些都不是故意的,您可以改为将其写为

VARIABLE    (_|{CHARACHTER})[a-zA-Z0-9]*

在这种情况下,您可以摆脱那种讨厌的WORD模式,因为它不会在其他任何地方使用。


这里 ...

{NEWLINE}       {lexprint("New Line\n"); return NEWLINE;} 

...您尝试使用名为 的模式NEWLINE,但尚未定义此类模式。


此外,您还有...

"/n"       {lineno++;}

... 这似乎是为了处理换行符,而是匹配两个字符序列 '/' 'n'。如果是生成的编译器抛出错误,那么这可能就是为什么在第 1 行报告问题发生的原因——这条规则很可能永远不会被触发,因此lineno永远不会增加。可能您想将其与以前的结合为:

\n       {lineno++; lexprint("New Line\n"); return NEWLINE;} 

这个 ...

"."        {yyerror("unknown character");}

... 似乎旨在成为匹配任何字符的后备规则,但它仅匹配由文字句点“.”组成的单字符标记。你似乎想要这个,而不是:

.          {yyerror("unknown character");}

推荐阅读