我正在为一种简单的编程语言设计一个词法和语法分析器。这是我的flex .l文件:
%{
#include <cstdio>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
#define YY_DECL extern "C" int yylex()
#include "littleDuck.tab.h"
int line_num = 1;
%}
id [a-zA-Z][a-zA-Z0-9]*
cteI [0-9]+
not (<)(>)
cteF {cteI}(\.{cteI}((e|E)("+"|"-")?{cteI})?)?
ctestring (\".*\")
%%
[ \t] ;
program {return PROGRAM;}
var {return VAR;}
print {return PRINT;}
"else" {return ELSE;}
"if" {return IF;}
{id} {return ID;}
\= {return '=';}
\< {return '<';}
\> {return '>';}
{not} {return NOT;}
\+ {return '+';}
\- {return '-';}
\/ {return '/';}
\* {return '*';}
\: {return ':';}
\, {return ',';}
\; {return ';';}
\{ {return '{';}
\} {return '}';}
\( {return '(';}
\) {return ')';}
{cteI} {yylval.ival = atoi(yytext); return INT;}
{cteF} {yylval.fval = atof(yytext); return FLOAT;}
{ctestring} {yylval.sval = strdup(yytext); return STRING;}
\n {++line_num;}
. ;
%%
这个文件正在由flex正确编译,虽然我不完全确定我是否可以总结一些术语。编译我的野牛文件时,我遇到了真正的问题。我是通过输入以下命令从Ubuntu终端进行的:
gabriel@virtualbox:~/Lenguajes/flexBison$ bison -d littleDuck.y
它返回22个语法中无用的非终结符和41个在语法中无用的规则。我的野牛文件是下一个:
%{
#include <cstdio>
#include <iostream>
using namespace std;
extern "C" int yylex();
extern "C" int yyparse();
extern "C" FILE *yyin;
extern int line_num;
void yyerror(const char *s);
%}
%union{
int ival;
float fval;
char *sval;
}
%token ID NOT PROGRAM VAR PRINT IF ELSE
%token <ival> INT
%token <fval> FLOAT
%token <sval> STRING
%%
programa:
PROGRAM ID ':' vars_1
;
vars_1:
VAR
;
vars:
VAR ID id_1
;
id_1:
',' id_1
| ':' tipo tipo_1
;
tipo:
INT
| FLOAT
;
tipo_1:
/* empty */
ID id_1
;
bloque:
'{' e1
;
e1:
estatuto e2
| e2
;
e2:
estatuto e2
| '}'
;
estatuto:
asignacion
| condicion
| escritura
;
asignacion:
ID '=' expresion ';'
;
expresion:
exp exp_1
;
exp:
termino exp_2
;
exp_1:
/* empty */
| '>' exp
| '<' exp
|NOT exp
;
exp_2:
'+' exp
| '-' exp
;
escritura:
PRINT '(' esc_1
;
esc_1:
expresion esc_2
| STRING esc_2
;
esc_2:
',' esc_1
| ')' ';'
;
condicion:
IF '(' expresion ')' bloque cond
;
cond:
';'
| ELSE bloque ';'
;
termino:
factor term
;
term:
'*' termino
| '/' termino
;
var_cte:
ID
| INT
| FLOAT
;
factor:
'(' expresion ')'
| var_cte
| '+' var_cte
| '-' var_cte
;
%%
main() {
FILE *myfile = fopen("testFile", "r");
if (!myfile) {
cout << "I can't open file" << endl;
return -1;
}
yyin = myfile;
do {
yyparse();
} while (!feof(yyin));
}
void yyerror(const char *s) {
cout << "Yikes! Parse error on line " << line_num << "! Message: " << s << endl;
exit(-1);
}
为什么要生成警告,如何摆脱它们?很抱歉发布完整的程序,但我认为所有信息都很重要,因为flex文件显示正在生成令牌,而bison文件具有所有语法规则。
答案 0 :(得分:1)
你的语法基本上只是:
programa:
PROGRAM ID ':' vars_1
;
vars_1:
VAR
;
这意味着它将接受的唯一有效程序是
program id : var
其中id
可能是任何有效的标识符。其他任何东西都是语法错误。
所有其他规则都无法访问且无用,因为无法通过programa
与他们联系。所以野牛告诉你,你也可以删除它们。
您可能想要的是添加一些导致其他规则的programa
或vars_1
规则,以便实际解析您想要的语言
答案 1 :(得分:-1)
某些语法确实不正确或缺少符号。我重写了我的语法并且它工作正常,只指出有3个shift-reduce。我添加左关联性给令牌做下一个:
%left '*' '/'
%left '+' '-'
此外,我没有为保留字“int”和“float”添加一个标记,只有int和float常量的标记。这显然是个大问题,因为我无法声明任何变量。我添加了它们并用FLOATC和INTC替换了常量的标记。这是在词法文件和语法文件中添加的。