Problem p01708 (C++)

Buggy submission (status: Runtime Error):
#include <cassert>
#include <complex>
#include <iomanip>
#include <iostream>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

typedef complex<double> vec;
typedef pair<vec, vec> line;
double ip(vec u, vec v) { return real(u * conj(v)); }
double cross(vec u, vec v) { return imag(conj(u) * v); }
vec projection(line l, vec p) {
  vec s = l.first, t = l.second;
  double k = ip(t - s, p - s) / ip(t - s, t - s);
  return (1.0 - k) * s + k * t;
}

vec reflection(line l, vec p) { return 2.0 * projection(l, p) - p; }

vec intersection(line l0, line l1) {
  vec s0, t0, s1, t1;
  s0 = l0.first, t0 = l0.second;
  s1 = l1.first, t1 = l1.second;
  double k = cross(t1 - s1, s1 - s0) / cross(t1 - s1, t0 - s0);
  return s0 + (t0 - s0) * k;
}

string s;
int c, N;

struct V {
  vector<vec> ps;
  V() {}
};

V f(V v1, V v2) {
  if (v1.ps.size() + v2.ps.size() == 2) {
    V ret;
    ret.ps.push_back(v1.ps[0]);
    ret.ps.push_back(v2.ps[0]);
    return ret;
  }
  if (v1.ps.size() + v2.ps.size() == 3) {
    if (v1.ps.size() == 2)
      swap(v1, v2);
    vec v = v1.ps[0];
    line l = make_pair(v2.ps[0], v2.ps[1]);
    v = reflection(l, v);
    V ret;
    ret.ps.push_back(v);
    return ret;
  }
  if (v1.ps.size() + v2.ps.size() == 4) {
    line l1 = make_pair(v1.ps[0], v1.ps[1]);
    line l2 = make_pair(v2.ps[0], v2.ps[1]);
    vec v = intersection(l1, l2);
    V ret;
    ret.ps.push_back(v);
    return ret;
  }
}

V expr();
double num();

V expr() {
  if (s[c] == '(') {
    c++;
    if (isdigit(s[c]) || s[c] == '-') {
      double x = num();
      assert(s[c] == ',');
      c++;
      double y = num();
      assert(s[c] == ')');
      c++;
      V v;
      v.ps.push_back(vec(x, y));
      return v;
    }
    V v1 = expr();
    while (c < N && s[c] == '@') {
      c++;
      V v2 = expr();
      assert(s[c] == ')');
      v1 = f(v1, v2);
    }
    assert(s[c] == ')');
    c++;
    return v1;
  }
}

double num() {
  double ret = 0;
  bool m = false;
  if (s[c] == '-') {
    m = true;
    c++;
  }
  while (isdigit(s[c])) {
    ret = ret * 10 + s[c] - '0';
    c++;
  }
  if (m) {
    ret *= -1;
  }
  return ret;
}

int main() {
  while (cin >> s, s != "#") {
    c = 0;
    N = s.size();
    V v1 = expr();
    while (c < N && s[c] == '@') {
      c++;
      V v2 = expr();
      v1 = f(v1, v2);
    }
    vec p = v1.ps[0];
    cout << fixed << setprecision(15) << p.real() << " " << p.imag() << endl;
  }
}

Fixed submission:
#include <cassert>
#include <complex>
#include <iomanip>
#include <iostream>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

typedef complex<double> vec;
typedef pair<vec, vec> line;
double ip(vec u, vec v) { return real(u * conj(v)); }
double cross(vec u, vec v) { return imag(conj(u) * v); }
vec projection(line l, vec p) {
  vec s = l.first, t = l.second;
  double k = ip(t - s, p - s) / ip(t - s, t - s);
  return (1.0 - k) * s + k * t;
}

vec reflection(line l, vec p) { return 2.0 * projection(l, p) - p; }

vec intersection(line l0, line l1) {
  vec s0, t0, s1, t1;
  s0 = l0.first, t0 = l0.second;
  s1 = l1.first, t1 = l1.second;
  double k = cross(t1 - s1, s1 - s0) / cross(t1 - s1, t0 - s0);
  return s0 + (t0 - s0) * k;
}

string s;
int c, N;

struct V {
  vector<vec> ps;
  V() {}
};

V f(V v1, V v2) {
  if (v1.ps.size() + v2.ps.size() == 2) {
    V ret;
    ret.ps.push_back(v1.ps[0]);
    ret.ps.push_back(v2.ps[0]);
    return ret;
  }
  if (v1.ps.size() + v2.ps.size() == 3) {
    if (v1.ps.size() == 2)
      swap(v1, v2);
    vec v = v1.ps[0];
    line l = make_pair(v2.ps[0], v2.ps[1]);
    v = reflection(l, v);
    V ret;
    ret.ps.push_back(v);
    return ret;
  }
  if (v1.ps.size() + v2.ps.size() == 4) {
    line l1 = make_pair(v1.ps[0], v1.ps[1]);
    line l2 = make_pair(v2.ps[0], v2.ps[1]);
    vec v = intersection(l1, l2);
    V ret;
    ret.ps.push_back(v);
    return ret;
  }
}

V expr();
double num();

V expr() {
  if (s[c] == '(') {
    c++;
    if (isdigit(s[c]) || s[c] == '-') {
      double x = num();
      assert(s[c] == ',');
      c++;
      double y = num();
      assert(s[c] == ')');
      c++;
      V v;
      v.ps.push_back(vec(x, y));
      return v;
    }
    V v1 = expr();
    while (c < N && s[c] == '@') {
      c++;
      V v2 = expr();
      // assert(s[c] == ')');
      v1 = f(v1, v2);
    }
    assert(s[c] == ')');
    c++;
    return v1;
  }
}

double num() {
  double ret = 0;
  bool m = false;
  if (s[c] == '-') {
    m = true;
    c++;
  }
  while (isdigit(s[c])) {
    ret = ret * 10 + s[c] - '0';
    c++;
  }
  if (m) {
    ret *= -1;
  }
  return ret;
}

int main() {
  while (cin >> s, s != "#") {
    c = 0;
    N = s.size();
    V v1 = expr();
    while (c < N && s[c] == '@') {
      c++;
      V v2 = expr();
      v1 = f(v1, v2);
    }
    vec p = v1.ps[0];
    cout << fixed << setprecision(15) << p.real() << " " << p.imag() << endl;
  }
}