gpt4 book ai didi

c++ - 回复 : Help with Boost Grammar

转载 作者:行者123 更新时间:2023-11-28 08:29:49 24 4
gpt4 key购买 nike

我已经重新设计并扩展了我之前询问的语法,如下所示:

// BIFAnalyser.cpp : Defines the entry point for the console application.
//
//
/*=============================================================================
Copyright (c) Temitope Jos Onunkun 2010
http://www.dcs.kcl.ac.uk/pg/onun/

Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
////////////////////////////////////////////////////////////////////////////
// //
// B Machine parser using the Boost "Grammar" and "Semantic Actions". //
// //
////////////////////////////////////////////////////////////////////////////

#include <boost/spirit/core.hpp>
#include <boost/tokenizer.hpp>
#include <iostream>
#include <string>
#include <fstream>
#include <vector>


////////////////////////////////////////////////////////////////////////////
using namespace std;
using namespace boost::spirit;

////////////////////////////////////////////////////////////////////////////
//
// Semantic Actions
//
////////////////////////////////////////////////////////////////////////////
//
//
namespace
{



//semantic action function on individual lexeme
void do_noint(char const* start, char const* end)
{
string str(start, end);

if (str != "NAT1")
cout << "PUSH(" << str << ')' << endl;
}

//semantic action function on addition of lexemes
void do_add(char const*, char const*)
{
cout << "ADD" << endl;
// for(vector<string>::iterator vi = strVect.begin(); vi < strVect.end(); ++vi)
// cout << *vi << " ";
}

//semantic action function on subtraction of lexemes
void do_subt(char const*, char const*)
{
cout << "SUBTRACT" << endl;
}

//semantic action function on multiplication of lexemes
void do_mult(char const*, char const*)
{
cout << "\nMULTIPLY" << endl;
}

//semantic action function on division of lexemes
void do_div(char const*, char const*)
{
cout << "\nDIVIDE" << endl;

}


//

//

vector<vector<string> > flowTable;


//semantic action function on simple substitution
void do_sSubst(char const* start, char const* end)
{
string str(start, end);

//use boost tokenizer to break down tokens
typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
boost::char_separator<char> sep(" -+/*:=()",0,boost::drop_empty_tokens); // char separator definition
Tokenizer tok(str, sep);
Tokenizer::iterator tok_iter = tok.begin();

pair<string, string > dependency; //create a pair object for dependencies


//create a vector object to store all tokens
vector<string> dx;
//

int counter = 0; // tracks token position

for(tok.begin(); tok_iter != tok.end(); ++tok_iter) //save all tokens in vector
{
dx.push_back(*tok_iter );
}
counter = dx.size();

//
vector<string> d_hat; //stores set of dependency pairs

string dep; //pairs variables as string object

//
dependency.first = *tok.begin();
vector<string> FV;

for(int unsigned i=1; i < dx.size(); i++)
{
//
if(!atoi(dx.at(i).c_str()) && (dx.at(i) !=" "))
{
dependency.second = dx.at(i);
dep = dependency.first + "|->" + dependency.second + " ";
d_hat.push_back(dep);

vector<string> row;
row.push_back(dependency.first); //push x_hat into first column of each row

for(unsigned int j=0; j<2; j++)
{

row.push_back(dependency.second);//push an element (column) into the row
}

flowTable.push_back(row); //Add the row to the main vector

}
}

//displays internal representation of information flow table
cout << "\n******************************\nDependency Table\n******************************\n";
cout << "X_Hat\tDx\tG_Hat\n";
cout << "-----------------------------\n";
for(unsigned int i=0; i < flowTable.size(); i++)
{
for(unsigned int j=0; j<2; j++)
{
cout << flowTable[i][j] << "\t ";
}
if (*tok.begin() != "WHILE" ) //if there are no global flows,
cout << "\t{}"; //display empty set

cout << "\n";
}
cout << "*****************************\n\n";


for(int unsigned j=0; j < FV.size(); j++)
{
if(FV.at(j) != dependency.second)
dep = dependency.first + "|->" + dependency.second + " ";
d_hat.push_back(dep);
}





cout << "PUSH(" << str << ')' << endl;

cout << "\n****************\nDependency pairs\n****************\n";

for(int unsigned i=0; i < d_hat.size(); i++)
cout << d_hat.at(i) << "\n...\n";

cout << "\nSIMPLE SUBSTITUTION\n\n";

}

//semantic action function on multiple substitution
void do_mSubst(char const* start, char const* end)
{
string str(start, end);


cout << "PUSH(" << str << ')' << endl;
//cout << "\nMULTIPLE SUBSTITUTION\n\n";
}


//semantic action function on unbounded choice substitution
void do_mChoice(char const* start, char const* end)
{
string str(start, end);

cout << "PUSH(" << str << ')' << endl;
cout << "\nUNBOUNDED CHOICE SUBSTITUTION\n\n";
}


void do_logicExpr(char const* start, char const* end)
{
string str(start, end);

//use boost tokenizer to break down tokens
typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
boost::char_separator<char> sep(" -+/*=:()><",0,boost::drop_empty_tokens); // char separator definition
Tokenizer tok(str, sep);
Tokenizer::iterator tok_iter = tok.begin();

//pair<string, string > dependency; //create a pair object for dependencies


//create a vector object to store all tokens
vector<string> dx;

for(tok.begin(); tok_iter != tok.end(); ++tok_iter) //save all tokens in vector
{
dx.push_back(*tok_iter );
}

for(unsigned int i=0; i<dx.size(); i++)
if(!atoi(dx.at(i).c_str()) && (dx.at(i) !=" ") )
{
cout << "\nFree Variables: " << dx.at(i)<< endl;
}


cout << "PUSH(" << str << ')' << endl;
cout << "\nPREDICATE\n\n";
}


void do_predicate(char const* start, char const* end)
{
string str(start, end);

cout << "PUSH(" << str << ')' << endl;
cout << "\nMULTIPLE PREDICATE\n\n";
}


void do_ifSelectPre(char const* start, char const* end)
{
string str(start, end);

//if

cout << "PUSH(" << str << ')' << endl;
cout << "\nPROTECTED SUBSTITUTION\n\n";
}


//semantic action function on machine substitution
void do_machSubst(char const* start, char const* end)
{
string str(start, end);



cout << "PUSH(" << str << ')' << endl;
cout << "\nMACHINE SUBSTITUTION\n\n";
}
}

////////////////////////////////////////////////////////////////////////////
//
// Machine Substitution Grammar
//
////////////////////////////////////////////////////////////////////////////

// Simple substitution grammar parser with integer values removed
struct Substitution : public grammar<Substitution>
{
template <typename ScannerT>
struct definition
{
definition(Substitution const& )
{

machine_subst
= ( (simple_subst)
| (multi_subst)
| (if_select_pre_subst)
| (unbounded_choice) )[&do_machSubst]
;


unbounded_choice
= str_p("ANY") >> ide_list
>> str_p("WHERE") >> predicate
>> str_p("THEN")
>> machine_subst
>> str_p("END")
;

if_select_pre_subst
= ( ( str_p("IF") >> predicate >> str_p("THEN") >> machine_subst
>> *( str_p("ELSIF") >> predicate >> machine_subst )
>> !( str_p("ELSE") >> machine_subst)
>> str_p("END") )
| ( str_p("SELECT") >> predicate >> str_p("THEN") >> machine_subst
>> *( str_p("WHEN") >> predicate >> machine_subst )
>> !( str_p("ELSE") >> machine_subst)
>> str_p("END"))
| ( str_p("PRE") >> predicate >> str_p("THEN") >> machine_subst
>> str_p("END") ) )[&do_ifSelectPre]
;



multi_subst
= ( (machine_subst)
>> *( ( str_p("||") >> (machine_subst) )
| ( str_p("[]") >> (machine_subst) ) ) ) [&do_mSubst]
;

simple_subst
= (identifier
>> str_p(":=") >> arith_expr) [&do_sSubst]
;

expression
= predicate
| arith_expr
;

predicate
= ( (logic_expr)
>> *( ( ch_p('&') >> (logic_expr) )
| ( str_p("OR") >> (logic_expr) ) ) )[&do_predicate]
;

logic_expr
= ( identifier
>> (str_p("<") >> arith_expr)
| (str_p("<") >> arith_expr)
| (str_p("/:") >> arith_expr)
| (str_p("<:") >> arith_expr)
| (str_p("/<:") >> arith_expr)
| (str_p("<<:") >> arith_expr)
| (str_p("/<<:") >> arith_expr)
| (str_p("<=") >> arith_expr)
| (str_p("=") >> arith_expr)
| (str_p(">=") >> arith_expr)
| (str_p("=>") >> arith_expr)
) [&do_logicExpr]
;

arith_expr
= term
>> *( ('+' >> term)[&do_add]
| ('-' >> term)[&do_subt] )
;

term
= factor
>> *( ('*' >> factor)[&do_mult]
| ('/' >> factor)[&do_div] )
;


factor
= lexeme_d[( identifier | +digit_p)[&do_noint]]
| '(' >> expression >> ')'
| ('+' >> factor)
;


ide_list
= identifier
>> *( ch_p(',') >> identifier )
;


identifier
= alpha_p >> +( alnum_p | ch_p('_') )
;

}

rule<ScannerT> machine_subst, unbounded_choice, if_select_pre_subst, multi_subst,
simple_subst, expression, predicate, logic_expr, arith_expr,
term, factor, ide_list, identifier;

rule<ScannerT> const&
start() const
{
return predicate;
//return multi_subst;
//return machine_subst;
}
};
};

////////////////////////////////////////////////////////////////////////////
//
// Main program
//
////////////////////////////////////////////////////////////////////////////
int
main()
{
cout << "************************************************************\n\n";
cout << "\t\t...Machine Parser...\n\n";
cout << "************************************************************\n\n";
// cout << "Type an expression...or [q or Q] to quit\n\n";

string str;
int machineCount = 0;
char strFilename[256]; //file name store as a string object
do
{

cout << "Please enter a filename...or [q or Q] to quit:\n\n "; //prompt for file name to be input
//char strFilename[256]; //file name store as a string object
cin >> strFilename;

if(*strFilename == 'q' || *strFilename == 'Q') //termination condition
return 0;

ifstream inFile(strFilename); // opens file object for reading
//output file for truncated machine (operations only)

if (inFile.fail())
cerr << "\nUnable to open file for reading.\n" << endl;

inFile.unsetf(std::ios::skipws);


Substitution elementary_subst; // Simple substitution parser object


string next;

while (inFile >> str)
{
getline(inFile, next);

str += next;

if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;

parse_info<> info = parse(str.c_str(), elementary_subst >> !end_p, space_p);

if (info.full)
{
cout << "\n-------------------------\n";
cout << "Parsing succeeded\n";
cout << "\n-------------------------\n";
}
else
{
cout << "\n-------------------------\n";
cout << "Parsing failed\n";
cout << "stopped at: " << info.stop << "\"\n";
cout << "\n-------------------------\n";
}

}


}
while ( (*strFilename != 'q' || *strFilename !='Q'));

return 0;
}

但是,我在测试时遇到以下意外行为:

我使用的文本文件是:

f1.txt,  ... containing ...:  debt:=(LoanRequest+outstandingLoan1)*20 .
f2.txt, ... containing ...: debt:=(LoanRequest+outstandingLoan1)*20 || newDebt := loanammount-paidammount || price := purchasePrice + overhead + bb .
f3.txt, ... containing ...: yy < (xx+7+ww) .
f4.txt, ... containing ...: yy < (xx+7+ww) & yy : NAT .

当我使用 multi_subst 作为开始规则时,两个文件(f1 和 f2)都被正确解析;

当我使用 machine_subst 作为起始规则时,文件 f1 正确解析,而文件 f2 失败,产生错误:“Parsing failed
停在: ||新债务 := loanammount-paidamount || price := purchasePrice + overhead + bb”

当我使用谓词作为开始符号时,文件 f3 解析正确,但文件 f4 产生错误:
“解析失败
停在:& yy : NAT”

请问有谁能帮忙补一下语法吗?看来语法有问题,我至今无法发现。

最佳答案

我重新设计了如下语法,似乎解决了这个问题:

替换 = 多项选择 | machine_subst ;

        multi_choice 
= machine_subst
>> +( str_p("[]") >> machine_subst )
;


machine_subst
= ( multi_subst
| simple_subst
| if_select_pre_subst
| unbounded_choice )[&do_machSubst]
;

......

多物质 = ( simple_subst

+( str_p("||") >> simple_subst ) ) [&do_mSubst] ;

        simple_subst
= (identifier
>> str_p(":=") >> arith_expr) [&do_sSubst]
;

expression
= predicate
| logic_expr
| arith_expr
;

predicate
= ( logic_expr
>> +( ( str_p("&") >> logic_expr )
| ( str_p("OR") >> logic_expr ) ) )[&do_predicate]
;

logic_expr
= ( identifier
>> ( (str_p("<") >> arith_expr)
| (str_p(">") >> arith_expr)
| (str_p("/:") >> arith_expr)
| (str_p("<:") >> arith_expr)
| (str_p("/<:") >> arith_expr)
| (str_p("<<:") >> arith_expr)
| (str_p("/<<:") >> arith_expr)
| (str_p("<=") >> arith_expr)
| (str_p("=") >> arith_expr)
| (str_p(">=") >> arith_expr)
| (str_p("=>") >> arith_expr) )
) [&do_logicExpr]
;

......我现在对文件 f1.txt 和 f2.txt 使用开始规则“subst”,对 f3.txt 和 f4.txt 使用“expression”。

开始() 常量 { 返回替代; //返回machine_subst; //返回表达式; //返回 if_select_pre_subst; //返回多项选择; //返回无界选择;

我仍在构建语法,所以如果我有任何其他问题,我会发布。

关于c++ - 回复 : Help with Boost Grammar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2670354/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com