递归解析器帮助 我应该写这个C++ 01和on。例如:01010101,但不是0,1,10011110。有人能帮我弄清楚我需要做什么来解决这个问题吗。对不起,伙计们,代码工作不正常。我按ctrl+k并发布了代码,但一切都不到位
我想做的是,当一些人输入1时,它会打印无效。如果输入0,则打印无效;如果输入10,则打印无效;如果输入01,则打印有效;如果输入0101,则打印有效。所以0总是先到,然后是1。另一个示例:0101010101打印有效 谢谢赛斯:)。我删除了链接 [来自seth.arnold:我删除了注释掉的代码,并缩进代码以遵循某种逻辑模式。如果愿意,可以用代码替换它,将每行缩进四个空格以正确格式化。]递归解析器帮助 我应该写这个C++ 01和on。例如:01010101,但不是0,1,10011110。有人能帮我弄清楚我需要做什么来解决这个问题吗。对不起,伙计们,代码工作不正常。我按ctrl+k并发布了代码,但一切都不到位,c++,C++,我想做的是,当一些人输入1时,它会打印无效。如果输入0,则打印无效;如果输入10,则打印无效;如果输入01,则打印有效;如果输入0101,则打印有效。所以0总是先到,然后是1。另一个示例:0101010101打印有效 谢谢赛斯:)。我删除了链接 [来自seth.arnold:我删除了注释掉的代码,并缩进代码以遵循某种逻辑模式。如果愿意,可以用代码替换它,将每行缩进四个空格以正确格式化。] #include <iostream> #include<stdlib.h> //
#include <iostream>
#include<stdlib.h> // for the exit(1) function
using namespace std;
char text[300];
char ToBeChecked;
char lexical(); //identify the characters
void SProd();
void BProd();
int main(){
cout<<"Enter some strings only 1 and 0 (max. 300 characters"<<endl;
cin>>text;
ToBeChecked = lexical(); //identify the character; find the first letter and give it to ToBeChecked
SProd();
if(ToBeChecked == '\0')
cout<<"Valid"<<endl;
else
cout<<"Invalid"<<endl;
cin.get();
return 0;
}
char lexical(){
static int index = -1; //a memory box named index with a value of -1; is static so it won't change.
//is -1 because -1 to 1 is 0; everything move on to next one
index++; //update index
return text[index]; //return the value of index
}
void SProd(){
if(ToBeChecked != '0' ) {
cout<<"Invalid"<<endl;
exit(1);
}
else{
BProd();
ToBeChecked = lexical();
}
}
void BProd(){
if(ToBeChecked != '1')
{
cout<<"Invalid"<<endl;
exit(1);
}
else
SProd();
ToBeChecked = lexical();
}
#包括
#包含//用于退出(1)功能
使用名称空间std;
字符文本[300];
炭化;
char词法()//识别字符
void SProd();
void BProd();
int main(){
Cuth用C++第6-7章看Bjorn Stroustroup的书编程原理和实践。
你必须写语法,你需要知道如何:
区分规则和标记
将一条规则置于另一条规则之后(排序)
表达替代模式(替代)
表达重复的模式
(重复)
识别要开始的语法规则
与
例如,您必须拥有一个令牌类:
class Token {
public:
char kind; // what kind of token
double value; // for numbers: a value
Token(char ch) // make a Token from a char
:kind(ch), value(0) { }
Token(char ch, double val) // make a Token from a char and a double
:kind(ch), value(val) { }
};
然后,令牌流类:
class Token_stream {
public:
Token_stream(); // make a Token_stream that reads from cin
Token get(); // get a Token (get() is defined elsewhere)
void putback(Token t); // put a Token back
private:
bool full; // is there a Token in the buffer?
Token buffer; // here is where we keep a Token put back using putback()
};
标识令牌流的默认构造函数:
Token_stream::Token_stream()
:full(false), buffer(0) // no Token in buffer
{
}
然后创建一个putback()函数,如果您感兴趣,则需要该函数将从iostream读取的字符放回,并调用专门提取该特定字符的函数:
void Token_stream::putback(Token t)
{
if (full) throw std::runtime_error("putback() into a full buffer");
buffer = t; // copy t to buffer
full = true; // buffer is now full
}
然后,在Token::get()中,您必须制定对您来说重要的规则以及要包含、省略或抛出错误的规则:
Token Token_stream::get()
{
if (full) { // do we already have a Token ready?
// remove token from buffer
full=false;
return buffer;
}
char ch;
cin >> ch; // note that >> skips whitespace (space, newline, tab, etc.)
switch (ch) {
case '=': // for "print"
case 'x': // for "quit"
case '(': case ')': case '{': case '}': case '+': case '-': case '*': case '/': case '!':
return Token(ch); // let each character represent itself
break;
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '9':
{
cin.putback(ch); // put digit back into the input stream
double val;
cin >> val; // read a floating-point number
return Token('8',val); // let '8' represent "a number"
}
break;
default:
throw std::runtime_error("Bad token");
}
}
在这个版本的Token_stream::get()中,我们对数字、数学运算符和括号感兴趣。因此,您必须更改该case语句以获取“1”或“0”,并忽略其他所有内容,或者抛出,这取决于您,我不知道您到底需要做什么
然后创建一个语法函数,如果你想在另一个前面处理一个字符,你必须建立一个调用另一个字符的函数的层次结构。但是如果你只需要按顺序读取,你只能有一个函数。无论如何,我包括3个使用计算器的函数,例如你有+,-,*,/,(,),{,}.正如您所看到的,这个示例需要确定它是什么,以便在调用另一个函数之前调用正确的函数,例如-订阅之前的乘法
primary()函数用于处理数字和括号:
// deal with numbers and parentheses
double primary()
{
Token t = ts.get();
switch (t.kind) {
case '(': // handle '(' expression ')'
{
double d = expression();
t = ts.get();
if (t.kind != ')') throw std::runtime_error("')' expected");
return d;
break;
}
case '{':
{
double d = expression();
t=ts.get();
if (t.kind != '}') throw std::runtime_error("'}' expected");
return d;
break;
}
case '8': // we use '8' to represent a number
return t.value; // return the number's value
break;
default:
throw std::runtime_error("primary expected");
}
}
term()函数处理乘法和除法:
// deal with *, /, and %
double term()
{
double left = primary();
Token t = ts.get(); // get the next token from token stream
while(true) {
switch (t.kind) {
case '*':
left *= primary();
t = ts.get();
break;
case '/':
{
double d = primary();
if (d == 0) throw std::runtime_error("divide by zero");
left /= d;
t = ts.get();
break;
}
default:
ts.putback(t); // put t back into the token stream
return left;
}
}
}
expression()处理加法和减法运算:
double expression()
{
double left = term(); // read and evaluate a Term
Token t = ts.get(); // get the next token from token stream
while(true) {
switch(t.kind) {
case '+':
left += term(); // evaluate Term and add
t = ts.get();
break;
case '-':
left -= term(); // evaluate Term and subtract
t = ts.get();
break;
default:
ts.putback(t); // put t back into the token stream
return left; // finally: no more + or -: return the answer
}
}
}
最后是我们的调用函数:
int callDrill_01(void)
try
{
std::cout << "Welcome to simple calculator." << std::endl;
std::cout << "Please enter expressions using floating-point numbers." << std::endl;
std::cout << "The arithmetic operators available are: + - * / ( ) { } = e(x)it." << std::endl;
double val = 0;
while (cin) {
Token t = ts.get();
if (t.kind == 'x') break; // 'q' for quit
if (t.kind == '=') { // ';' for "print now"
cout << "=" << val << '\n';
}else{
ts.putback(t);
}
val = expression();
}
keep_window_open();
}
catch (exception& e) {
cerr << "error: " << e.what() << '\n';
keep_window_open();
return 1;
}
catch (...) {
cerr << "Oops: unknown exception!\n";
keep_window_open();
return 2;
}
int callDrill_01(无效)
尝试
{
STD::CUT< P>在Bjorn Stroustroup的书中,用C++第6-7章编程原理和实践来查看。
你必须写语法,你需要知道如何:
区分规则和标记
将一条规则置于另一条规则之后(排序)
表达替代模式(替代)
表达重复的模式
(重复)
识别要开始的语法规则
与
例如,您必须拥有一个令牌类:
class Token {
public:
char kind; // what kind of token
double value; // for numbers: a value
Token(char ch) // make a Token from a char
:kind(ch), value(0) { }
Token(char ch, double val) // make a Token from a char and a double
:kind(ch), value(val) { }
};
然后,令牌流类:
class Token_stream {
public:
Token_stream(); // make a Token_stream that reads from cin
Token get(); // get a Token (get() is defined elsewhere)
void putback(Token t); // put a Token back
private:
bool full; // is there a Token in the buffer?
Token buffer; // here is where we keep a Token put back using putback()
};
标识令牌流的默认构造函数:
Token_stream::Token_stream()
:full(false), buffer(0) // no Token in buffer
{
}
然后创建一个putback()函数,如果您感兴趣,则需要该函数将从iostream读取的字符放回,并调用专门提取该特定字符的函数:
void Token_stream::putback(Token t)
{
if (full) throw std::runtime_error("putback() into a full buffer");
buffer = t; // copy t to buffer
full = true; // buffer is now full
}
然后,在Token::get()中,您必须制定对您来说重要的规则以及要包含、省略或抛出错误的规则:
Token Token_stream::get()
{
if (full) { // do we already have a Token ready?
// remove token from buffer
full=false;
return buffer;
}
char ch;
cin >> ch; // note that >> skips whitespace (space, newline, tab, etc.)
switch (ch) {
case '=': // for "print"
case 'x': // for "quit"
case '(': case ')': case '{': case '}': case '+': case '-': case '*': case '/': case '!':
return Token(ch); // let each character represent itself
break;
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '9':
{
cin.putback(ch); // put digit back into the input stream
double val;
cin >> val; // read a floating-point number
return Token('8',val); // let '8' represent "a number"
}
break;
default:
throw std::runtime_error("Bad token");
}
}
在这个版本的Token_stream::get()中,我们对数字、数学运算符和括号感兴趣。因此,您必须更改该case语句以获取“1”或“0”,并忽略其他所有内容,或者抛出,这取决于您,我不知道您到底需要做什么
然后创建一个语法函数,如果你想在另一个前面处理一个字符,你必须建立一个调用另一个字符的函数的层次结构。但是如果你只需要按顺序读取,你只能有一个函数。无论如何,我包括3个使用计算器的函数,例如你有+,-,*,/,(,),{,}.正如您所看到的,这个示例需要确定它是什么,以便在调用另一个函数之前调用正确的函数,例如-订阅之前的乘法
primary()函数用于处理数字和括号:
// deal with numbers and parentheses
double primary()
{
Token t = ts.get();
switch (t.kind) {
case '(': // handle '(' expression ')'
{
double d = expression();
t = ts.get();
if (t.kind != ')') throw std::runtime_error("')' expected");
return d;
break;
}
case '{':
{
double d = expression();
t=ts.get();
if (t.kind != '}') throw std::runtime_error("'}' expected");
return d;
break;
}
case '8': // we use '8' to represent a number
return t.value; // return the number's value
break;
default:
throw std::runtime_error("primary expected");
}
}
term()函数处理乘法和除法:
// deal with *, /, and %
double term()
{
double left = primary();
Token t = ts.get(); // get the next token from token stream
while(true) {
switch (t.kind) {
case '*':
left *= primary();
t = ts.get();
break;
case '/':
{
double d = primary();
if (d == 0) throw std::runtime_error("divide by zero");
left /= d;
t = ts.get();
break;
}
default:
ts.putback(t); // put t back into the token stream
return left;
}
}
}
expression()处理加法和减法运算:
double expression()
{
double left = term(); // read and evaluate a Term
Token t = ts.get(); // get the next token from token stream
while(true) {
switch(t.kind) {
case '+':
left += term(); // evaluate Term and add
t = ts.get();
break;
case '-':
left -= term(); // evaluate Term and subtract
t = ts.get();
break;
default:
ts.putback(t); // put t back into the token stream
return left; // finally: no more + or -: return the answer
}
}
}
最后是我们的调用函数:
int callDrill_01(void)
try
{
std::cout << "Welcome to simple calculator." << std::endl;
std::cout << "Please enter expressions using floating-point numbers." << std::endl;
std::cout << "The arithmetic operators available are: + - * / ( ) { } = e(x)it." << std::endl;
double val = 0;
while (cin) {
Token t = ts.get();
if (t.kind == 'x') break; // 'q' for quit
if (t.kind == '=') { // ';' for "print now"
cout << "=" << val << '\n';
}else{
ts.putback(t);
}
val = expression();
}
keep_window_open();
}
catch (exception& e) {
cerr << "error: " << e.what() << '\n';
keep_window_open();
return 1;
}
catch (...) {
cerr << "Oops: unknown exception!\n";
keep_window_open();
return 2;
}
int callDrill_01(无效)
尝试
{
std::cout#包括
//#包含//用于退出(1)功能
使用名称空间std;
字符文本[300];
炭化;
char lexical();//识别字符
void SProd();
void BProd();
int main(){
不能包含
//#包含//用于退出(1)功能
使用名称空间std;
字符文本[300];
炭化;
char lexical();//识别字符
void SProd();
void BProd();
int main(){
cout“有人能帮我找出我需要做什么来解决问题吗”什么是“问题”?您还应该告诉我们您是如何试图解决这个问题的。例如,在EBNF中发布您的语法简明,并思考不同的EBNF结构如何映射到诸如循环/ifs之类的编程结构。奇怪的是,您在检查字符不是什么,而不是检查字符是什么。如果我读得正确,您的解析器将接受333333
作为有效输入