帮助提升语法 [英] Help with Boost Grammar

查看:76
本文介绍了帮助提升语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用以下win32控制台代码来尝试使用Boost Spirit语法模板解析C ++中嵌入的B机器语法.我是一个相对较新的Boost用户.代码可以编译,但是当我运行VC ++ 2008生成的.exe文件时,程序会部分解析输入文件.我认为问题出在我的语法定义上.

代码如下:

I have been using the following win32 console code to try to parse a B Machine Grammar embedded within C++ using Boost Spirit grammar template. I am a relatively new Boost user. The code compiles, but when I run the .exe file produced by VC++2008, the program partially parses the input file. I believe the problem is with my grammar definition.

The code is given below:

// 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>
#include <utility>

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

////////////////////////////////////////////////////////////////////////////
//
//  Semantic actions
//
////////////////////////////////////////////////////////////////////////////
vector<string> strVect;


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

        if(atoi(str))
        {
            ;
        }
        else
        {
        strVect.push_back(s);
        cout << "PUSH(" << s << ')' << 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;

 for(vector<string>::iterator vi = strVect.begin(); vi < strVect.end(); ++vi)

   cout << *vi << " ";

}



    //semantic action function on multiplication of lexemes

void do_mult(char const*, char const*)

{

 cout << "\nMULTIPLY" << endl;

 for(vector<string>::iterator vi = strVect.begin(); vi < strVect.end(); ++vi)

   cout << *vi << " ";

 cout << "\n";

}



    //semantic action function on division of lexemes

void do_div(char const*, char const*)

{

 cout << "\nDIVIDE" << endl;

 for(vector<string>::iterator vi = strVect.begin(); vi < strVect.end(); ++vi)

   cout << *vi << " ";

}



    //semantic action function on simple substitution

void do_sSubst(char const* str, char const* end)

{

   string  s(str, end);



        //use boost tokenizer to break down tokens

    typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
    boost::char_separator<char> sep("-+/*:=()"); // default char separator
      Tokenizer tok(s, sep);
    Tokenizer::iterator tok_iter = tok.begin();

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

        //save first variable token in simple substitution
    dependency.first = *tok.begin();

        //create a vector object to store all tokens
    vector<string> dx;
       //
      for( ; tok_iter != tok.end(); ++tok_iter)  //save all tokens in vector
        {
            dx.push_back(*tok_iter );
        }

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

    string dep; //pairs variables as string object



    for(int unsigned i=1; i < dx.size()-1; i++)

    {

        dependency.second = dx.at(i);

      dep = dependency.first + "|->" + dependency.second + " ";
      d_hat.push_back(dep);
    }


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



    for(int unsigned i=0; i < d_hat.size(); i++)

       cout <<"\n...\n" << d_hat.at(i) << " ";



    cout << "\nSIMPLE SUBSTITUTION\n";



}



    //semantic action function on multiple substitution

void do_mSubst(char const* str, char const* end)

{

  string  s(str, end);



        //use boost tokenizer to break down tokens

  typedef boost::tokenizer<boost::char_separator<char> > Tok;
  boost::char_separator<char> sep("-+/*:=()"); // default char separator
  Tok tok(s, sep);
  Tok::iterator tok_iter = tok.begin();

    //  string start = *tok.begin();

  vector<string> mx;

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

    mx.push_back("END\n");  //add a marker "end"

    for(unsigned int i=0; i<mx.size(); i++)

    {

        //  if(mx.at(i) == "END" || mx.at(i) == "||" )

        //      break;

        //  else if( mx.at(i) == "||")

        //          do_sSubst(str, end);

        //  else

        //  {

        //          do_sSubst(str, end);



        //  }



        cout << "\nTokens ... " << mx.at(i) << " ";

    }





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

        cout << "MULTIPLE SUBSTITUTION\n";

    }



}



////////////////////////////////////////////////////////////////////////////

//

//  Simple Substitution Grammar

//

////////////////////////////////////////////////////////////////////////////



//  Simple substitution grammar parser with integer values removed

struct Substitution : public grammar<Substitution>
{
    template <typename ScannerT>
    struct definition
    {
        definition(Substitution const& )
        {
        multi_subst
                = (simple_subst [&do_mSubst]
                >> +( str_p("||") >> simple_subst [&do_mSubst])
                )
                ;

        simple_subst
                =  (Identifier >> str_p(":=")
>> expression)[&do_sSubst]
                  ;

        Identifier
                = alpha_p >> +alnum_p//[do_noint]
                ;

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

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

            factor
                =   lexeme_d[( (alpha_p >> +alnum_p) | +digit_p)[&do_noint]]
                |   '(' >> expression >> ')'
                |   ('+' >> factor)
                ;
        }
rule<ScannerT> expression, term, factor, Identifier, simple_subst,
   multi_subst ;

        rule<ScannerT> const&
        start() const
        {
            return multi_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";



//prompt for file name to be input

cout << "Please enter a filename...or [q or Q] to quit:\n\n ";

char strFilename[256]; //file name store as a string object

cin >> strFilename;

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


Substitution elementary_subst;  //  Simple substitution parser object

string str, next;
//  inFile.open(strFilename);
while (inFile >> str)
  {
        getline(cin, next);

        str += next;

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

        parse_info<> info = parse(str.c_str(), elementary_subst, 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";

        }

    }

    cout << "Please enter a filename...or [q or Q] to quit\n";

    cin >> strFilename;


    return 0;
}




The contents of the file I tried to parse, which I named "mf5.txt" is given below:




The contents of the file I tried to parse, which I named "mf5.txt" is given below:

debt:=(LoanRequest+outstandingLoan1)*20 || newDebt := loanammount-paidammount



The output when I execute the program is:



The output when I execute the program is:

************************************************************
                ...Machine Parser...
************************************************************
Please enter a filename...or [q or Q] to quit:
 c:\tplat\mf7.txt
PUSH(LoanRequest)
PUSH(outstandingLoan1)
ADD
LoanRequest outstandingLoan1
MULTIPLY
LoanRequest outstandingLoan1
PUSH(debt:=(LoanRequest+outstandingLoan1)*20)
...
debt|->LoanRequest
...
debt|->outstandingLoan1
SIMPLE SUBSTITUTION
Tokens ... debt
Tokens ... LoanRequest
Tokens ... outstandingLoan1
Tokens ... 20
Tokens ... END
 PUSH(debt:=(LoanRequest+outstandingLoan1)*20)
MULTIPLE SUBSTITUTION
-------------------------
Parsing failed
stopped at: ": "
-------------------------




My intention is to capture only the variables in the file, which I managed to do up to the "||"细绳. Clearly, the program is not parsing beyond the "||" string in the input file. I will appreciate assistance to fix the grammar. SOS, please.




My intention is to capture only the variables in the file, which I managed to do up to the "||" string. Clearly, the program is not parsing beyond the "||" string in the input file. I will appreciate assistance to fix the grammar. SOS, please.

推荐答案

Decmac0904 wrote:
Decmac0904 wrote:

I will appreciate assistance to fix the grammar.

I will appreciate assistance to fix the grammar.



Where is it?

欢呼声,
AR



Where is it?

cheers,
AR


这篇关于帮助提升语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆