- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经重新设计并扩展了我之前询问的语法,如下所示:
// 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/
我有一个字符串,我想多次使用它来输出 configure --help .所以我尝试在 configure.ac 中做这样的事情: AC_ARG_ENABLE([foobar],
我无法使其正确匹配。它只打印“[help]”,但我希望它匹配括号内的字符。 想要: [help] help 代码: Pattern p = Pattern.compile("\\[(\
我刚刚将vim74下载并安装到我的linux机器上。我只是为用户安装在本地。当我进入vim并执行:help时,我得到了错误。 我尝试添加: let $VIM='home/myuser/vim74' l
当我打开一个 Xcode 项目时,快速帮助功能工作得很好,但是当打开一个不在打开的项目中的文件(例如 abc.swift )时,文档不会出现。 下面是一个例子: 最佳答案 安装版本Command Li
我有一个 python click CLI。当我将 --help 传递给任何命令时,它会打印一条我喜欢的帮助消息。我发现现在很多用户都在输入 mycli help foo 而不是 mycli foo
我一直在使用 less 进行前端开发,但最近几天我遇到了这个错误。 我正在使用 PhpStorm 的观察器将 less 文件编译为 css 文件。但是当我编辑 less 文件时,编译器将这一行添加到
当我在 python 解释器中键入 help('string') 时,我得到了有关字符串类的信息。在那里,upper() 被表示为一个函数。然而,我只能将其称为 "hi".upper() 而不是 up
我希望 help 选项的作用与 --help 相同。 旁注:我创建了一个程序,其命令行行为与 svn 或 hg 相同。我设法用子解析器做到了这一点。但是我想让事情保持一致。这就是为什么我希望 help
我是 Maven 的新手。你知道我做错了什么吗(见下文)? mvn -e clean:help. + Error stacktraces are turned on. [INFO] Scannin
help format-list输出格式列表的帮助。 format-list | help输出帮助(get-help)。 最佳答案 该|或“管道”运算符将一个操作的输出重定向到另一个。因此,在这种情况
尝试从脚本检索帮助会出现以下错误: Get-Help : Cannot find Help for topic ".\Process-Test.ps1". At line:1 char:9 + get
我从常规的discord.py更改为重写版本,并且我曾经有一个自定义的!help命令。 现在,每当我发布 !help 时,它都会显示此内容以及编码的帮助消息: No Category: help S
我开发跨平台桌面应用程序,最近我发现了在小部件上使用帮助文本的乐趣。然后用户在标题栏上有一个问号按钮,单击该按钮后,他可以单击窗口中的任何小部件并查看有关它的帮助文本。非常好。 因为我认为所有程序都应
Xcode 4.5.2 Mountain Lion,Mac 应用 我严格遵守文档。帮助文件夹及其子文件夹已添加到项目/Resources 文件夹并显示为蓝色。 如有必要,文件夹引用由 xcode 添加
emulator documentation说: -audio-in Use the specified audio-input backend. 它还说 -help- Print
最近在学习argparse模块,代码下方出现Argument错误 import argparse import sys class ExecuteShell(object): def crea
我正在阅读有关 Maven 的教程,应该提到我对此一无所知。我已经成功地完成了第一章和第二章,这是关于它的设置的。但是在第 3 章“Maven Pom”中我遇到了问题。在最后一段中,它说在你想要的任何
我注意到 Windows 有这个问题,但我运行的是 Ubuntu 13.10(带有 Bash),所以我不知道出了什么问题。 尝试设置我的副本集,我运行以下命令: sudo bash # Accout
很抱歉,我在 python 程序中遇到了一个尴尬的问题。首先我是这里的新手,我是一名中国学生。请原谅我糟糕的英语。我会尽力把问题表达清楚。 错误代码在这里: def __find__(
好的,我试图环顾四周并弄清楚如何做到这一点,但无法弄清楚。这就是我想要做的。 # Run script normally .\myscript.ps1 "blah" "yo" 这些应该做同样的事情 G
我是一名优秀的程序员,十分优秀!