【发布时间】:2020-01-25 15:59:08
【问题描述】:
首先,我对 flex 和 bison 很陌生,我似乎真的无法解决这个问题。
我已经创建了 flex 和 bison 文件,编译工作正常这里是我的 flex 和 bison 文件
(ps cmets 是法语) 弹性:
%{
// Définitions en language C
#include"minilang.tab.h"
extern int yylval;
extern int nbrligne;
%}
// les définitions des expressions régulières
/*
Définitions de la partie
"Liste Declarations" du language MiniLang
qui inclut les déclarations du language Minilang
*/
chiffre [0-9]
vide [ \t]+|" "+
saut_ligne [\n]+
// les Nombres (valeurs)
integer [- | +]?([1-9][0-9]*|0)
float [- | +]?([1-9][0-9]*|0)\.[0-9]*[1-9]
bool ("true"|"false"|"TRUE"|"FALSE")
constant integer|float
// Définitions
varint "INT"|"int"
varfloat "FLOAT"|"float"
varbool "bool"|"BOOL"
const "CONST"|"const"
comment "{"[^}]*"}"
// Déclarations des éléments du language
// IDF à revoir
idf ([A-Z]([_]?[a-z0-9])*){1,11}
affectation "="
semicolon ";"
vg ","
plus "++"
minus "--"
beginmc "begin"|"BEGIN"
end "end"|"END"
/*
Définitions de la partie
"List Instructions" du language MiniLang
qui inclut les instructions du language Minilang
*/
// Affectation
op "+"|"-"|"*"|"/"|"&&"|"||"
// Condition if
if "if"|"IF"|"If"
comp "=="|"<"|"<="|"<>"|">"|">="
// For loop
for "for"|"FOR"
// Common
paropen "("
parclose ")"
curlopen "{"
curlclose "}"
%%
// Expression Régulière { Action C}
{chiffre} {return token_chiffre;}
{vide}
{saut_ligne} {nbrligne++;}
{integer} { yylval = atoi(yytext); return token_integer;}
{float} { yylval = atof(yytext); return token_float;}
{bool} {return token_bool;}
{varint} {return token_varint;}
{varfloat} {return token_varfloat;}
{varbool} {return token_varbool;}
{const} {return token_const;}
{comment} {return token_comment;}
{idf} {return token_idf;}
{affectation} {return token_affectation;}
{semicolon} {return token_semicolon;}
{vg} {return token_vg;}
{plus} {return token_plus;}
{minus} {return token_minus;}
{beginmc} {return token_begin;}
{end} {return token_end;}
{op} {return token_op;}
{if} {return token_if;}
{comp} {return token_comp;}
{for} {return token_for;}
{paropen} {return token_paropen;}
{parclose} {return token_parclose;}
{curlopen} {return token_curlopen;}
{curlclose} {return token_curlclose;}
{constant} {return token_constant;}
. {printf("\nErreur lexicale a la ligne %d ",nbrligne);}
%%
和野牛:
%{
#include <stdio.h>
#include<stdlib.h>
int nbrligne=0;
int yylex();
void yyerror(const char *s);
%}
// Token definitions
%token token_chiffre
%token token_vide
%token token_integer
%token token_float
%token token_bool
%token token_varint
%token token_varfloat
%token token_varbool
%token token_const
%token token_comment
%token token_idf
%token token_affectation
%token token_semicolon
%token token_vg
%token token_plus
%token token_minus
%token token_begin
%token token_end
%token token_op
%token token_if
%token token_comp
%token token_for
%token token_paropen
%token token_parclose
%token token_curlopen
%token token_curlclose
%token token_constant
%%
Prog: DecList token_begin InstList token_end|;
DecList: Declaration DecList|Declaration | token_comment DecList | token_comment;
Declaration: ConstIntDec | ConstFloatDec | ConstBoolDec | IntDec | FloatDec | BoolDec;
ConstIntDec: token_const token_varint MultiIdfInt token_semicolon;
ConstFloatDec: token_const token_varfloat MultiIdfFloat token_semicolon;
ConstBoolDec: token_const token_varbool MultiIdfBool token_semicolon;
IntDec: token_varint MultiIdfInt token_semicolon;
FloatDec: token_varfloat MultiIdfFloat token_semicolon;
BoolDec: token_varbool MultiIdfBool token_semicolon;
MultiIdfInt: token_idf token_vg MultiIdfInt | token_idf | token_idf token_affectation token_integer MultiIdfInt ;
MultiIdfFloat: token_idf token_vg MultiIdfFloat | token_idf | token_idf token_affectation token_integer MultiIdfFloat ;
MultiIdfBool: token_idf token_vg MultiIdfBool | token_idf | token_idf token_affectation token_integer MultiIdfBool ;
InstList: Instruction InstList | Instruction | token_comment InstList | token_comment;
Instruction: Boucle | Affectation | Condition;
Affectation: token_idf token_affectation Exp token_semicolon | Incrementation;
Incrementation: token_constant token_plus | token_constant token_minus;
Exp: token_idf token_op Exp | token_idf | ExpConst;
ExpConst: token_integer token_op ExpConst | token_float token_op ExpConst | token_bool token_op ExpConst
| token_bool
| token_constant;
Condition: token_if token_paropen ExpCond token_parclose token_curlopen InstList token_curlclose;
ExpCond: token_idf token_comp token_idf
| token_idf token_comp token_constant
| token_idf token_comp token_bool
| token_constant token_comp token_idf
| token_bool token_comp token_idf
| token_constant token_comp token_constant
| token_bool;
Boucle: token_for token_paropen Affectation token_vg ExpCond token_vg Incrementation token_parclose token_curlopen InstList token_curlclose;
%%
#include"lex.yy.c"
int main() {
yyparse();
return yylex();
}
void yyerror(const char *s){ printf("\nERROR %d\n",nbrligne); }
int yywrap(){ return 1; }
// int yywrap(void){
// return 1;
// }
这是我运行的命令来编译它们并执行编译器
flex minilang.l
bison -d minilang.y
gcc -o compiler minilang.tab.c
test.minilang 是我创建的一个文件,它应该是这个编译器应该解释的相同语言,这里是他的内容
int K_ms;
BEGIN
K_ms=16;
END
此代码产生的错误是“ERROR 1”,这意味着它发生在第一行,我不明白代码中的错误在哪里 语言应该是这样的:
// List of Variable Declarations
BEGIN
// List of Instructions
END
【问题讨论】:
-
您的
vide规则包含冗余。您不应将 cmets 返回给解析器。将它们视为空白,不要在作品中提及它们。 -
而且你不应该这样实现你的标识符长度。否则,您会将一个过长的标识符视为两个相邻的标识符,这只会使用户感到困惑,并产生解析错误。您应该在操作代码中进行长度检查。
-
我现在可以看到将 cmets 发送到解析器是多么不正常,可以解决这个问题,但是“vide”是空格,我猜我也不应该将它发送到解析器。对吗?
-
关于标识符长度,我想你的意思是告诉我应该不带长度检查的情况下发送给bison,然后处理长度问题
-
您可以在 Flex 操作中检查长度(请参阅
yyleng)。他的意思是你不应该试图用一种模式来限制它。
标签: c syntax compiler-construction bison flex-lexer