gpt4 book ai didi

c++ - 递归解析器帮助

转载 作者:行者123 更新时间:2023-11-28 01:07:56 25 4
gpt4 key购买 nike

我应该编写这个接受 01 及以后的 C++。例如:01010101 但不是 0,1,10,011,110。有人可以帮我弄清楚我需要做什么来解决这个问题。抱歉,代码无法正常工作。我按了 ctrl+k 并发布了代码,但一切都没有到位。

我试图做的是,当有人输入 1 时,它打印出无效。如果他们输入 0 则打印无效,如果输入 10 则打印无效,如果他们输入 01 则打印有效,如果输入 0101 则打印有效。所以 0 总是必须先出现并且总是跟在 1 之后。另一个例子:0101010101 打印有效

谢谢赛斯 :)。我删除了链接

[来自 seth.arnold:我删除了注释掉的代码并缩进代码以遵循某种逻辑模式。如果您愿意,请随意将其替换为您的代码,每行缩进四个空格以正确设置格式。]

#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();
}

最佳答案

查看 Bjorn Stroustrou 的书 Programming Principles and Practice using c++ 第 6-7 章。

你将不得不编写语法,你需要知道如何:

  1. 区分规则和标记
  2. 一个接一个地放置规则(排序)
  3. 表达替代模式(alternation)
  4. 表达重复模式(重复)
  5. 认识语法规则开始与

例如 - 你必须有一个 token 类:

    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) { }
};

然后是 token 流类:

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 流的默认构造函数:

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”,并忽略其他所有内容,或者抛出,这取决于您,我不知道您到底需要做什么。

然后创建一个语法函数,您将必须建立函数的层次结构,如果您想要或示例 1 个字符在另一个字符之前进行处理,则可以相互调用。但是如果你只需要顺序读取,你只能有1个功能。无论如何,我包含了 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;
}

这应该让您了解如何创建递归解析器。你的头可能在旋转。我建议你找到我提到的那本书并阅读那些章节。将来对你有帮助。

关于c++ - 递归解析器帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5137981/

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