1

私は、単純なプログラミング言語用の字句解析プログラムと構文アナライザーの設計に取り組んでいます。これが私の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によって正しくコンパイルされていますが、いくつかの用語を要約できるかどうかは完全にはわかりません。私の本当の問題は、bisonファイルをコンパイルするときに発生します。これを入力して、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);
}

警告が生成されるのはなぜですか?また、どうすれば警告を取り除くことができますか?完全なプログラムを投稿して申し訳ありませんが、フレックスファイルは生成されているトークンを示し、バイソンファイルにはすべての文法規則があるため、すべての情報が重要だと思います。

4

2 に答える 2

1

あなたの文法は本質的にただです:

programa:
    PROGRAM ID ':' vars_1
    ;
vars_1:
    VAR
    ;

これは、それが受け入れる唯一の有効なプログラムが

program id : var

有効な識別子はどこにidありますか。それ以外の場合は構文エラーになります。

からルールに到達する方法がないため、残りのすべてのルールは到達不能で役に立たないprograma。したがって、バイソンは、それらを削除した方がよいと言っています。

おそらく必要なのは、残りのルールにつながる他のルールprogramaまたはルールを追加して、実際に必要な言語を解析することです。vars_1

于 2013-03-01T18:17:06.177 に答える
-1

一部の文法が実際に正しくないか、記号が欠落しています。文法を書き直しましたが、正しく機能しましたが、3シフトリデュースがあったことを指摘するだけでした。次のことを行うトークンに左結合性を追加しました。

%left '*' '/'
%left '+' '-'

また、予約語「int」と「float」のトークンは追加せず、int定数とfloat定数のトークンのみを追加しました。変数を宣言できなかったので、これは明らかに大きな問題でした。それらを追加し、定数のトークンをFLOATCとINTCに置き換えました。これは、文法ファイルだけでなく語彙ファイルにも追加されました。

于 2013-03-01T15:48:20.583 に答える