https://rentry.org/PPP2_p191

// Code derived from Stroustrup's PPP2 book
// § 6.4 Grammars
//  -and beginning on p 191

//------------------------------------------------------------------------------
/*
                                                 Parsing the expression 2 + 3
                                                    (read from bottom up):

                                                          Expression
                                                               ^
  A simple expression grammar                                  |
                                                      ---------+--------
                                                      |        |       |
Expression:                                       Expression   |       |
    Term                                              ^        |       |
    Expression "+" Term  // addition                  |        |       |
    Expression "–" Term  // subtraction               |        |       |
                                                      |        |       |
Term:                                               Term       |     Term
    Primary                                           ^        |       ^
    Term "*" Primary     // multiplication            |        |       |
    Term "/" Primary     // division                  |        |       |
    Term "%" Primary     // remainder (modulo)        |        |       |
                                                      |        |       |
Primary:                                           Primary     |    Primary
    Number                                            ^        |       ^
    "(" Expression ")"   // grouping                  |        |       |
                                                      |        |       |
Number:                                               |        |       |
    floating-point-literal                            |        |       |

                                                      2        +       3

*/
//------------------------------------------------------------------------------

#include <iostream>

using std::cin;
using std::cout;

class Token {  // a simple user-defined type
 public:
  Token(char ch) : kind{ch} {}

  Token(char ch, double val) : kind{ch}, value{val} {}

  char   kind  = '0';
  double value = 0.0;
};

//------------------------------------------------------------------------------

Token get_token() {
  char ch;
  cin >> ch;  // note that >> skips whitespace (space, newline, tab, etc.)

  switch (ch) {
    case ';':
    case '+':            // addition-only for this example
      return Token{ch};  // let each character represent itself

    case '2':           // 2 or 3 only for this example
    case '3': {         //
      cin.putback(ch);  // put digit back into the input stream
      double val;
      cin >> val;  // read a floating-point number
      return Token{'8', val};
    }

    default:
      return Token{'K'};  // 'K' is invalid
  }
}

//------------------------------------------------------------------------------

double expression();  // addition only
double term();        // pass-thru
double primary();     // number only

//------------------------------------------------------------------------------

// Note: this is a greatly-simplified (but working) example, to demonstrate the
// grammar call-chain involved in parsing the basic expression of four tokens:
//     2 + 3 ;
//
// -the idea is to simplify function internals enough for easy comprehensibility

int main() {
  cout << "enter:  2+3;  \n";

  cout << expression() << '\n';
}

double expression() {
  double left = term();  // read and evaluate a Term

  Token t = get_token();  // get the next token from cin

  switch (t.kind) {  // see which kind of token that is
    case '+':
      return left + expression();  // read and evaluate an Expression,
                                   // then do an add
    default:
      return left;  // return the value of the Term
  }
}

double term() {
  double left = primary();  // read and evaluate a Primary

  return left;
}

double primary() {  // just return the number, for this example
  Token t = get_token();

  switch (t.kind) {
    case '8':          // we use '8' to represent a number
      return t.value;  // return the number's value
    default:
      return 0.0;
  }
}

build & run:

g++ -std=c++20 -O2 -Wall -pedantic ./ch_06/main_p191.cpp && ./a.out

PrevUpNext

Edit
Pub: 15 Mar 2023 11:45 UTC
Edit: 15 Mar 2023 20:38 UTC
Views: 43