So I have this recursive descent parser that works fine recognizing and using values through command line arguments but I am not sure how to port this to reading from a .dat file, using the proper char pointer, printing the string, and working for multiple strings.
Parser using command line args:
#include <iostream>
#include <fstream>
using namespace std;
bool A(void);
bool E(void);
bool T(void);
bool F(void);
bool P(void);
bool I(void);
bool L(void);
char *c;
int main(int argc, char *argv[]){
c = argc == 2 ? argv[1] : (char *)"";
if (A() && *c == '\0') {
cout << "The string \"" << argv[1] << "\" is in the language." << endl;
}
else {
cout << "The string \"" << argv[1] << "\" is not in the language." << endl;
}
return 0;
}
bool A(void){
if( I() )
{
if ( *c == '=' ){
++c;
if ( E() )
return true;
}
}
return false;
}
bool E(void){
if( T() ){
if ( *c == '+' || *c == '-' ){
++c;
return E();
}
return true;
}
return false;
}
bool F(void){
if( P() ){
if( *c == '^'){
++c;
return F();
}
return true;
}
return false;
}
bool I(void){
if ( *c >= 'a' && *c <= 'z'){
++c;
return true;
}
return false;
}
bool L(void){
if ( *c >= '0' && *c <= '9' ){
++c;
return true;
}
return false;
}
bool P(void){
if ( I() ){
return true;
}
else
if ( L() ){
return true;
}
else
if ( *c == '(' ){
++c;
if ( E() ){
if ( *c == ')' ){
++c;
return true;
}
}
}
return false;
}
bool T(void){
if( F() ){
if ( *c == '*' || *c == '/' ){
++c;
return T();
}
return true;
}
return false;
}
I don't know what I can replace argv[1] with to print the string. To get the proper char pointer could I just do this?
ifstream fin("input.dat");
while (fin >> *c)
when I try that I get segmentation fault.
You are asking the stream to store a value into what is represented by the value that c
points to. Instead of that, consider:
char ch;
char *c = &ch;
ifstream fin("input.dat");
while (fin >> ch) {
// whatever
}
This would not segfault immediately. However, bad things would happen on the "next" iteration, as you change the value of c
inside the parsing functions.
You need to restructure the program and abstract the intention of reading the next character from the method of reading the next character (by incrementing a pointer, or reading from a stream, or whatever).
Or you could also read the file into one big memory buffer and then proceed as if that buffer was a string passed from the command line.
Assuming your file is a text file with one entry to parse per line you could do this:
ifstream fin("input.dat")
if (fin.is_open())
{
std::string line;
while (fin.good())
{
getline(fin, line);
c = line.c_str();
... go and parse c
}
}
Update : apparently c
is non-const, so using c_str()
won't work just like that. You have two options:
c_str()
in there. Number 1 is probably the better way.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.