c - 弯曲过早的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);
}
解决方案
您的 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");}
推荐阅读
- java - 如何使用 OneSignal 打开特定活动?
- angular - 如何为主机组件创建 ComponentFixture
- angularjs - AngularJS:在 ng-min 中使用 ng-messages
- javascript - 谷歌策略匿名函数未被调用
- azure-data-factory-2 - ADF v2 取消 InProgress 管道
- jmeter - 如何通过添加 if 控制器来跳过 Beanshell PostProcessor(基于先前 http 请求的正则表达式输出)
- r - 如何在单个图中实现 rgamma 和 dgamma
- javascript - 提交表单后会发生什么?
- eclipse - 在调试模式下运行时输入不起作用 - eclipse cdt
- python - 在 python 中按它们的索引顺序连接两个列表列表