弹性过早 EOF

-3 c flex-lexer

我编写了这段代码来在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);
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*ger 5

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


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

如果是这样flex引发错误,那么这可能就是原因。


这里有一个迷失的撇号:

'%}
Run Code Online (Sandbox Code Playgroud)

这 ...

NUMBER      {DIGIT}*|0
Run Code Online (Sandbox Code Playgroud)

...匹配零长度输入。这样就更清楚了,不存在这个问题:

NUMBER      {DIGIT}+
Run Code Online (Sandbox Code Playgroud)

这 ...

WORD        ({WORD}*|{NUMBER}*)*
Run Code Online (Sandbox Code Playgroud)

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

 WORD        ({CHARACHTER}|{NUMBER})+
Run Code Online (Sandbox Code Playgroud)

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

 WORD        [a-zA-Z0-9]+
Run Code Online (Sandbox Code Playgroud)

...,我自己。

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

 WORD        {CHARACHTER}[a-zA-Z0-9]*
Run Code Online (Sandbox Code Playgroud)

这 ...

VARIABLE    _?({WORD}*|{NUMBER}*)*
Run Code Online (Sandbox Code Playgroud)

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

VARIABLE    (_|{CHARACHTER})[a-zA-Z0-9]*
Run Code Online (Sandbox Code Playgroud)

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


这里 ...

{NEWLINE}       {lexprint("New Line\n"); return NEWLINE;} 
Run Code Online (Sandbox Code Playgroud)

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


此外,您还有...

"/n"       {lineno++;}
Run Code Online (Sandbox Code Playgroud)

...似乎旨在处理换行符,但它匹配两个字符序列“/”“n”。如果是构建的编译器抛出错误,那么这可能就是报告问题发生在第 1 行的原因——很可能该规则永远不会被触发,因此lineno永远不会增加。也许您想将其与之前的结合起来,如下所示:

\n       {lineno++; lexprint("New Line\n"); return NEWLINE;} 
Run Code Online (Sandbox Code Playgroud)

这 ...

"."        {yyerror("unknown character");}
Run Code Online (Sandbox Code Playgroud)

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

.          {yyerror("unknown character");}
Run Code Online (Sandbox Code Playgroud)