【问题标题】:How to restart start state data in flex如何在flex中重新启动启动状态数据
【发布时间】:2022-07-29 08:35:35
【问题描述】:

我在 flex 中创建了一个开始条件(用于字符串),一切正常。然而, 当我两次解析相同的字符串时,使用开始条件的元素消失了。 我该如何解决? 请帮我 弹性文件

   
%option stack noyywrap
%{
extern int lineNumber; // definie dans prog.y, utilise par notre code pour \n
#include "h5parse.hpp"
#include <iostream>
#include <fstream>

using namespace std;
extern string initialdata;
extern string pdata;
extern bool loop;
string val;
string compile(string content);
string compilefile(string path);
void runwithargs(int argc ,char ** argv);
int saveoutput(string compileddata ,string outputpath="");

%}
%x strenv
i_command       @include
e_command       @extends
l_command       @layout
f_command       @field

command {i_command}|{e_command}|{l_command}|{f_command}

%%
"\""       { val.clear(); BEGIN(strenv); }
<strenv>"\""    { BEGIN(INITIAL);sprintf(yylval.str,"%s",val.c_str());return(STRING); }
<strenv><<EOF>> { BEGIN(INITIAL); sprintf(yylval.str,"%s",val.c_str());return(STRING); }
<strenv>.       { val+=yytext[0]; }
{command}       {sprintf(yylval.str,"%s",yytext);return (COMMAND);}
"("             { return LPAREN; }
")"             { return RPAREN; }
"{"             { return LBRACE; }
"}"             { return RBRACE; }
.|\n            {yylval.c=yytext[0];return TXT; }
%%

//our main function 
int main(int argc,char ** argv)
{

if(argc>1)runwithargs(argc,argv);// if there are arguments run with them

system("pause");//don't quit the app at the end of assembly
return(0);
}

//run h5A by using  arguments
void runwithargs(int argc ,char ** argv)
{
    if(argc == 2)
        saveoutput(compilefile(argv[1]));
    
}

//assemble a string 
string compile(string content)
{

do 
{
loop=false;
pdata.clear();
 YY_BUFFER_STATE b =yy_scan_string(content.c_str());

yyparse();
content=pdata; 

 }while(loop==true);
return content;
}

//assemble file
string compilefile(string path)
{
string data;
ifstream inputfile(path,ios::in|ios::binary|ios::ate);
int length  = inputfile.tellg();           
inputfile.seekg(0, std::ios::beg);  
char * buffer = new char[length];// allocate memory for a buffer of appropriate dimension
inputfile.read(buffer, length);// read the whole file into the buffer
inputfile.close();  
cout<<"start assembly : "<<path<<endl;
return compile(string(buffer));
}

//save  assembled  file to a specified path 
int saveoutput(string compileddata ,string outputpath)
{

outputpath=(outputpath=="")?"output":outputpath;
ofstream outputfile  ("output");
//dhow the compiled data in console if we're in debug 
outputfile<<compileddata;
cout<<compileddata<<endl;
cout<<"operation terminated successfuly , output at :"
    <<outputpath<<endl;

return 0;

}

野牛文件

%{
#include <stdio.h>
#include <iostream>
#include<fstream>
#include<map>
using namespace std;
typedef void* yyscan_t;
int lineNumber; // notre compteur de lignes
map <string,string> clayouts;
void yyerror ( char const *msg);
typedef union YYSTYPE YYSTYPE;


void yyerror ( char const *msg);
int yylex();
bool loop;
string pdata="";
%}
/* token definition */
%token STRING 
%token COMMAND
%token LPAREN RPAREN  LBRACE RBRACE
%token TXT
%union { char c; char str [0Xfff]; double real; int integer; }
%type<c> TXT;
%type<str> STRING COMMAND;
%start program
%%
program:value | command_call |txt | program program ;
value: STRING {pdata+='\"'+$1+'\"'; };
command_call : COMMAND LPAREN STRING  RPAREN   { 
    
    if(string($1)=="@field")
    {
         cout<<"define field :"<<$3;
    }
    else if(string($1)=="@include")
    {
        ifstream t;
        int length;
        char * buffer;
        t.open($3);     
        t.seekg(0, std::ios::end);    
        length = t.tellg();           
        t.seekg(0, std::ios::beg);  
        buffer = new char[length];    
        t.read(buffer, length);       
        t.close(); 
        pdata+=buffer;
    }
    else if (string($1)=="@layout")
    {
        cout<<"define layout for field "<<$3;
    }
    else if (string($1)=="@repeat")
    {
        cout<<"reapeat instruction"<<$3;
    }
    else
    {
        cout<<"extend with : "<<$3;
         ifstream t;
        int length;
        char * buffer;
        t.open($3);     
        t.seekg(0, std::ios::end);    
        length = t.tellg();           
        t.seekg(0, std::ios::beg);  
        buffer = new char[length];    
        t.read(buffer, length);       
        t.close(); 
    }
    loop=true;
     };//LPAREN RPAREN ;
txt: TXT {pdata+=$1;};
%%
void yyerror (const char *msg)
{
    cout<<msg;
}

这是输出

请帮助我理解为什么字符串会消失。 这是完整代码my repository 提前感谢

【问题讨论】:

    标签: c++ parsing bison flex-lexer lexer


    【解决方案1】:

    这里没有任何东西会消失,而且您不会两次解析相同的字符串。

    第二次解析是在您自己创建的新字符串上进行的,其中包含在第一次解析期间复制的数据。所以它们是不同的字符串,Flex 和 Bison 都不知道它们之间的任何关系。

    第二个字符串不包含与第一个字符串相同的数据的原因很简单:您没有复制所有数据。任何你不复制的东西都会“消失”。

    特别是,您只能在双引号之间复制数据;双引号本身不会被复制。所以第二次解析时,没有双引号,双引号之间的数据不再被引用。所以它的“处理”方式不同(即被忽略)。

    老实说,我认为这不是宏预处理器的合适架构。但这是一个不同的问题。

    【讨论】:

    • 我复制了双引号,请在github上查看我的完整代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    相关资源
    最近更新 更多