#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { number, plus, times, end } token;
int token_value;

const char *nextc;

void next_token()
{
  char c;
  while ((c = *nextc) == ' ') nextc++;
  switch (c) {
  case '\0': token = end;            break;
  case '+':  token = plus;  nextc++; break;
  case '*':  token = times; nextc++; break;
  case '0': case '1': case '2': case '3': case '4':
  case '5': case '6': case '7': case '8': case '9':
    token = number; token_value = 0;
    do 
      token_value = token_value * 10 + c - '0';
    while ((c = *(++nextc)) >= '0' && c <= '9');
    break;
  default:
    fprintf(stderr, "unexpected character '%c'\n", c);
    exit(1);
    break;
  }
}

const char *tokstr()
{
  static char n[10];
  switch (token) {
  case plus: return "+";
  case times: return "*";
  case number: sprintf(n, "%d", token_value); return n;
  default: return "end";
  }
}

void syntax_error()
{
  fprintf(stderr, "syntax error at \"%s\"\n", tokstr());
  exit(1);	 
}

int product() {
  if (token != number) syntax_error();
  int product = token_value;
  next_token();
  while (token == times) {
    next_token();
    if (token != number) syntax_error();
    product *= token_value;
    next_token();
  }
  return product;
}

int sum() {
  if (token != number) syntax_error();
  int sum = product();
  while (token == plus) {
    next_token();
    sum += product();
  }
  return sum;
}

int main(int argc, const char *argv[])
{
  if (strcmp(argv[1], "--tokens") == 0) {
    
    nextc = &argv[2][0];
    do {
      next_token();
      puts(tokstr());
    } while (token != end);
    
  } else {
    
    nextc = &argv[1][0];
    next_token();
    printf("%d\n", sum());  
    if (token != end) syntax_error();
    
  }
  
  return 0;
}
