0

字句解析および構文解析用に次のファイルがあります。

lexico.l

%{
    #include <iostream>
    #include <stdio.h>
    #include <string>   
    using namespace std;
    extern int yylex();
    #include "sintactico.h" // to get token types from Bison
%}
%option noyywrap
vfit1                       (?i:ff)
vfit2                       (?i:bf)
vfit3                       (?i:wf)
%%
#(.)*                       { printf("COMENTARIO\n"); }
[ \t\n]                     { /* Ignorar espacios en blanco */ }
[0-9]+                      { printf("INT\n"); yylval.sval = new string(yytext); return INT; }
\"([^\\\"]|\\.)*\"          { printf("STRING\n"); /*return STRING*/ }
(?i:mkdisk)                 { printf("MKDISK\n"); return MKDISK; }
(?i:size)                   { printf("SIZE\n");  yylval.sval = new string(yytext); return SIZE; }
(?i:unit)                   { printf("UNIT\n");  yylval.sval = new string(yytext); return UNIT; }
(?i:path)                   { printf("PATH\n");  yylval.sval = new string(yytext); return PATH; }
(?i:fit)                    { printf("FIT\n");  yylval.sval = new string(yytext); return FIT; }
-                           { printf("GUION\n"); return GUION; }
=                           { printf("IGUAL\n"); return IGUAL; }
{vfit1}|{vfit2}|{vfit3}     { printf("VFIT\n");  yylval.sval = new string(yytext); return VFIT; }
[bkmKBM]                    { printf("VUNIT\n"); yylval.sval = new string(yytext); return VUNIT; }
[a-zA-Z0-9/._]+             { printf("VSTRING\n"); yylval.sval = new string(yytext); return VSTRING; }
.                           { printf("ERROR\n"); }
%%

シンタクティコ

%{  
    #include <cstdio>   
    #include <cstdlib>
    #include <string>
    #include <iostream>
    #include <map>
    using namespace std;
    map<string, string> opc;
    // Declare stuff from Flex that Bison needs to know about:
    extern int yylex();
    //extern int yyparse();
    extern FILE *yyin;
    #include "lexico.h"
    #include "cadena.h"

    void yyerror(const char *s);

    void test_map(){        
        cout << "opc.size() is " << opc.size() << endl;
        for(auto it : opc){
            cout << "*************************\n";
            cout << it.first << endl;
            cout << it.second << endl;
            cout << "*************************\n";
        }
    }       
%}

%union{
    int ival;       
    char cval;
    std::string *sval;  
}

%token        MKDISK RMDISK FDISK MOUNT UNMOUNT 
%token        TYPE DELETE 
%token        NAME ADD ID STRING GUION IGUAL

%token <sval> SIZE FIT PATH UNIT 
%token <sval> VSTRING INT VFIT VUNIT

%type <sval>  val_path

%%

axioma:             instr{
                        cout << "Finaliza" << endl;
                    };  

instr:              mkdisk{
                        analisis_mkdisk(opc);
                    };

mkdisk:             MKDISK list_mkdisk;

list_mkdisk:        list_mkdisk opc_mkdisk
                |   opc_mkdisk;

opc_mkdisk:         size
                |   fit
                |   unit
                |   path;

size:               GUION SIZE IGUAL INT{
                        cout << *$2 << ": " << *$4 << endl;
                        a_minus(*$2);                   
                        opc[*$2] = *$4;
                        delete $4;                      
                    };

fit:                GUION FIT IGUAL VFIT{
                        cout << *$2 << ": " << *$4 << endl;
                        a_minus(*$2); 
                        a_minus(*$4);
                        opc[*$2] = *$4; delete $4;
                    };

unit:               GUION UNIT IGUAL VUNIT{
                        cout << *$2 << ": " << *$4 << endl;
                        a_minus(*$2);
                        a_minus(*$4);
                        opc[*$2] = *$4; delete $4;
                    };

path:               GUION PATH IGUAL val_path{
                        cout << *$2 << ": " << *$4 << endl;
                        a_minus(*$2);
                        opc[*$2] = *$4; delete $4;
                    };

val_path:           VSTRING;                

%%

次のエントリは正しい必要があります: mkdisk -size=20。size ルールのコードは実行されますが、instr ルールのコードを実行するには CTRL + D を押す必要があります。コードに追加するために何が欠けていますか? パーサーは語彙的ですか、それとも構文的ですか?

編集: パーサーから EOL トークンを削除しました。私が本当に理解していないのは、パーサーがエントリが終了したことをどのように認識するのですか? コンソールで mkdisk -size = 20 コマンドを入力した後、ENTER キーを押します。入力が ENTER で終わることを Bison に伝えるにはどうすればよいですか? アナライザーがエントリーを待って分析を終了するのはなぜですか?

4

1 に答える 1