Question
C++, Parsing Page Ranges, Please fix my code!! Hello there, I made a program for an expression tree type and a parser for page set
C++, Parsing Page Ranges, Please fix my code!!
Hello there, I made a program for an expression tree type and a parser for page set expressions.
Requirements are:
A comma-separated list with at least one item
where each item is either a single page number or a range of pages
where a range of pages is two page numbers, separated by either a dash or the word to, and optionally followed by the words odd or even. (Printing only odd/even pages is useful for duplexing.)
For example, it should do things like:
> 1,2,4,5 1,2,4,5 > 1 to 10 1,2,3,4,5,6,7,8,9,10 > 1,3 - 5,8 1, 3, 4, 5, 8 > 1 - 10 odd 1,3,5,7,9
However, my program doesnt do
> 1 to 10.
> 1 - 10.
> 1 - 10 odd
but, it does
> 1, 2, 3, 1 - 10, 3 to 9 odd
the "to" and "-" command does not work when its used in the first sequence.
My instructor said,
"The problem is in your exprss function, when you do if (numbs(*start) && opps(*(start+1)) && numbs(*(start+2)) && is_qualifier(*(start+3))) { you haven't checked to make sure that finish >= start+3. I.e., there might not be four elements in the input sequence, in which case you'll read off the end."
But I still can't figure out how to fix my code.
If you think you can help me out with this, please copy the code below and fix the code.
======================================================
#include
using std::cin; using std::cout; using std::vector; using std::string; using it = vector
struct pset { virtual void evaluate() = 0; };
struct pset_num : public pset { pset_num (int value) { v = value; }
void evaluate() { cout << v << ", "; }
int v; };
struct pset_range : public pset { pset_range(int start, int end) { s = start; e = end; }
void evaluate() { for (int i = s; i <= e; i++) { cout << i << ", "; } }
int s; int e; };
struct pset_r_odd : public pset { pset_r_odd(int start, int end) { s = start; e = end; }
void evaluate() { for (int i = s; i <= e; i++) { if (i % 2 == 1) cout << i << ", "; } }
int s; int e; };
struct pset_r_even : public pset { pset_r_even(int start, int end) { s = start; e = end; }
void evaluate() { for (int i = s; i <= e; i++) { if (i % 2 == 0) cout << i << ", "; } }
int s; int e; };
//checks to see if a string is a number bool is_num(string s) { return (s.at(0) >= '0' && s.at(0) <= '9'); }
//checks to see if a string is an operator "to" or "-" in this case bool is_op(string s) { return (s == "to" || s == "-"); }
//checks to see if the string is a qualifier. "even" or "odd" in this case bool is_qualifier(string s) { return (s == "even" || s == "odd"); }
//function declarations bool is_expr(it start, it finish); void parse_pset(it start, it finish); vector
//This is the global cariable where the regular expressions will get stored //in the main loop, this expressions will be "evaluated" and printed out to //the console vector
int main() { string input;
while (true) { //where the tokens will be stored after lexical analysis vector
cout << "> "; std::getline(cin, input);
//storing the input as tokens tokens = lex(input);
//printing out the tokens to the user
for (int i = 0; i < tokens.size(); i++) cout << "\"" << tokens[i] << "\", ";
cout << std::endl;
//checking to see if all the tokens in "tokens" vector are parseable bool valid = is_expr(tokens.begin(), tokens.end() -1);
if (valid) { cout << "Valid!" << std::endl; parse_pset(tokens.begin(), tokens.end() -1); for (pset* exp : ranges) { exp->evaluate(); } ranges.clear();
} else { cout << "Invalid input" << std::endl; } tokens.clear(); cout << std::endl;
} }
/* This function is a state machine that takes in an input string and divides the string into tokens : space, numbers, words, operators. */ vector
int state = SPACE; vector
for (char c : s) { if (state == SPACE) {
for (char c : s) { if (state == SPACE) { if (c == ' ' || c == ',') continue; else if (c >= '0' && c <= '9') state = NUM; else if (c >= 'a' && c <'z') state = WORD; else if (c == '-') state = OP;
word.push_back(c); }
else { //Not in SPACE int newstate = state; if (c == ' ' || c == ',') newstate = SPACE; else if (c >= '0' && c <= '9') newstate = NUM; else if (c >= 'a' && c <= 'z') newstate = WORD; else if (c == '-') newstate = OP;
if (newstate == SPACE) { words.push_back(word); word.clear(); state = SPACE; continue; }
if (newstate == state && state !=OP) word.push_back(c); else if (newstate != state || state == OP) { words.push_back(word); word.clear(); word.push_back(c); }
state = newstate;
}
}
if (!word.empty()) words.push_back(word);
return words; }
void parse_pset(it start, it finish) {
if (start > finish) //if input is empty return; else if (start == finish) { //if input is just one token. It has to be a number if(is_num(*start)) ranges.push_back(new pset_num{ stoi(*start) }); } else {
//if the tokens follow the grammar
if (*(start+3) == "odd") { ranges.push_back(new pset_r_odd{stoi(*start), stoi(*(start+2))});
//"recursive" call in order to keep looking through the input vector parse_pset(start+4, finish); } else if (*(start+3) == "even") { ranges.push_back(new pset_r_even{stoi(*start), stoi(*(start+2))});
parse_pset(start+4, finish); } }
//if the tokens follow the grammar
else if (is_num(*start) && is_op(*(start+1)) && is_num(*(start+2))) { ranges.push_back(new pset_range{stoi(*start),stoi(*(start+2))});
parse_pset(start+3, finish); }
//if the tokens follow the grammar
parse_pset(start+1, finish); } }
return; }
/* This function goes through the token vector and makes sure all the tokens make valid expressions. */ bool is_expr(it start, it finish) { if (start > finish) return true; else if (start == finish) { if(is_num(*start)) return true; else return false; } else { if (is_num(*start) && is_op(*(start+1)) && is_num(*(start+2)) && is_qualifier(*(start+3))) { return is_expr(start+4, finish); } else if (is_num(*start) && is_op(*(start+1)) && is_num(*(start+2))) { return is_expr(start+3, finish); } else if (is_num(*start)) { return is_expr(start+1, finish); }
}
}
return false; }
======================================
trolls will be reported...
Thank you in advance!
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started