Go: package main

import (
	"bufio"
	"fmt"
	"os"
)

var sc = bufio.NewScanner(os.Stdin)

func nextString() string {
	sc.Scan()
	return sc.Text()
}

func main() {
	sc.Buffer(make([]byte, 0), 1000000009)

	for {
		var s string
		s = nextString()
		if s == "." {
			break
		}
		var st []byte
		is_valid := true

		for _, value := range s {
			if value == '(' {
				st = append(st, byte(value))
			}
			if value == '[' {
				st = append(st, byte(value))
			}
			if value == ')' {
				if len(st) == 0 || st[len(st)-1] != '(' {
					is_valid = false
					break
				} else {
					st = st[:len(st)-1]
				}
			}
			if value == ']' {
				if len(st) == 0 || st[len(st)-1] != '[' {
					is_valid = false
					break
				} else {
					st = st[:len(st)-1]
				}
			}
		}
		if len(st) != 0 {
			is_valid = false
		}
		if is_valid {
			fmt.Println("yes")
		} else {
			fmt.Println("no")
		}
	}
}

C++: #include <iostream>
#include <string>
using namespace std;

int main () {

  string input;

  while( true ) {

    if ( cin.eof() ) break;

    getline( cin, input );

    string s = " ";

    for ( long long int i = 0; i < input.size(); i++ ) {

      if ( input[i] == '(' ) {
	s += "(";
      }else if ( input[i] == '[' ) {
	s += "[";
      }else if ( input[i] == ')' ) {
	if ( s[ s.size() - 1 ] != '(' ) {
	  cout << "no" << endl;
	  break;
	}else {
	  s.erase( s.size() - 1 );
	}
      }else if ( input[i] == ']' ) {
	if ( s[ s.size() - 1 ] != '[' ) {
	  cout << "no" << endl;
	  break;
	}else {
	  s.erase( s.size() - 1 );
	}
      }

      if ( i == input.size() - 1 ) {
	if ( s == " " ) {
	  cout << "yes" << endl;
	}else {
	  cout << "no" << endl;
	}
      }

    }

  }

  return 0;

}

C++: #include<iostream>
#include<string>
#include<stack>

int main(){

	std::string str;
	while (true){
		std::getline(std::cin, str);
		std::stack<char>s;

		if (str == ".")break;

		bool flg = true;
		for (int i = 0; i < str.size(); i++){
			if (str[i] == '(' || str[i] == '[')s.push(str[i]);
			if (str[i] == ')' || str[i] == ']'){
				if (s.empty()){
					flg = false;
					break;
				}

				char a = s.top();
				s.pop();
				
				if (a == '('&&str[i] == ')');
				else if (a == '['&&str[i] == ']');
				else {
					flg = false;
					break;
				}
			}
		}
		if (s.empty() && flg)std::cout << "yes" << std::endl;
		else std::cout << "no" << std::endl;
	}
	return 0;
}

C++: #include <iostream>
#include <stack>
using namespace std;

int main(){
  string s;
  while(getline(cin,s)){
    stack<char> st;
    if(s[0]=='.' && s.size()==1)break;
    bool ch=false;
    int i;
    for(i=0;i<s.size();i++){
      if(s[i]=='[' || s[i]=='(')st.push(s[i]);
      else if(s[i]==']'){
        if(st.empty() || st.top()!='[')ch=true;
        else if(!st.empty()) st.pop();
      }else if(s[i]==')'){
        if(st.empty() || st.top()!='(')ch=true;
        else if(!st.empty()) st.pop();
      }
    }
    if(ch)cout << "no" << endl;
    else cout << "yes" << endl;
  }
  return 0;
}

C++: #include <iostream>
#include <cmath>
#include <vector>
#include <stack>
#include <deque>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
using ll = long long;
const double pi = acos(-1);
#define FOR(i,a,b) for (ll i=(a),__last_##i=(b);i<__last_##i;i++)
#define RFOR(i,a,b) for (ll i=(b)-1,__last_##i=(a);i>=__last_##i;i--)
#define REP(i,n) FOR(i,0,n)
#define RREP(i,n) RFOR(i,0,n)
#define __GET_MACRO3(_1, _2, _3, NAME, ...) NAME
#define rep(...) __GET_MACRO3(__VA_ARGS__, FOR, REP)(__VA_ARGS__)
#define rrep(...) __GET_MACRO3(__VA_ARGS__, RFOR, RREP)(__VA_ARGS__)
#define vi vector<int>
template<typename T> istream &operator>>(istream &is, vector<T> &v){ for (auto &x : v) is >> x; return is; }
template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    REP(i,v.size()){if(i)os<<" ";os<<v[i];}return os;}
template<typename T> ostream& operator<<(ostream& os, const vector<vector<T>>& v) {
    REP(i,v.size()){if(i)os<<endl;os<<v[i];}return os;}

const int MOD = 1e9 + 7;
const int INF = 1 << 30;


class UnionFind{
private:
        vector<int> par,rank,sizes;
        int tree;

public:
        explicit UnionFind(const int n) : tree(n){
            par.resize(n+1);
            rank.resize(n+1);
            sizes.resize(n+1);
            rep(i,n){
                par[i] = i;
                sizes[i] = 1;
            }
        }

        ~UnionFind() = default;

        int root(int x){
            if(par[x] == x) return x;
            else return par[x] = root(par[x]);
        }

        int find(int x){ return root(x);}

        void unite(int x, int y) {
            x = root(x);
            y = root(y);
            if (x == y) return;

            if (rank[x] < rank[y]) swap(x, y);
            par[y] = x;
            tree--;
            sizes[x] += sizes[y];
            if (rank[x] == rank[y]) rank[x]++;
        }

        bool same(int x, int y){
            return root(x) == root(y);
        }

        int size(int x){
            return sizes[x];
        }

        int sumTree(){
            return tree;
        }
};

template <typename T>
class segmentTree{
private:
    int n;
    vector<T> arr;
public:

    explicit segmentTree(vector<T> v){
        ll sz = v.size();
        //while()

        arr.resize(2*n - 1);

    }

    T &operator[](int n){ return arr[n];}


};

template <int mod>
class ModInt{
private:
    ll _num;

public:
    ModInt(){_num = 0;}
    explicit ModInt(ll value){_num = value%mod;}

    ModInt operator+(ModInt &x){ return ModInt(_num + x._num);}
    ModInt operator-(ModInt &x){ return ModInt(_num - x._num);}
    ModInt operator*(ModInt &x){ return ModInt(_num * x._num);}
    friend ostream &operator<<(ostream &os, const ModInt &x){os<<x._num; return os;}
    friend istream &operator>>(istream &is, ModInt &x){is>>x._num; return is;}
};
using mint = ModInt<MOD>;


class topos{

};

int gcd(int a,int b){
    return b ? gcd(b,a%b) : a;
}

ll power(ll m, ll n, ll mod){
    ll res = 1;
    while(n > 0){
        if(n & 1) res = ((res%mod) * (m%mod))%mod;
        m = (m * m)%mod;
        n >>= 1;
    }
    return res;
}


int main() {
    while(true){
        string s;
        getline(cin,s);

        if(s == ".") break;

        stack<int> st;

        rep(i,s.size()){
            int prev = 0;
            switch(s[i]){
                case '[':
                    prev = 1;
                    break;

                case ']':
                    prev = -1;
                    break;

                case '(':
                    prev = 2;
                    break;

                case ')':
                    prev = -2;
                    break;

                default:
                    break;
            }

            if(prev == 0) continue;
            if(!st.empty()) {
                int s = st.top();
                if (s + prev == 0 and s > prev) st.pop();
                else st.push(prev);
            }else{
                st.push(prev);
            }

        }

        if(st.empty()) cout << "yes" << endl;
        else cout << "no" << endl;

    }

}

C++: #include<iostream>
#include<stack>
#include<string>
using namespace std;

int main(){
  string s;
  stack<char> c;
  c.push('\0');
  while(getline(cin,s)){
    if(s == ".")break;
    while(c.size() != 1)c.pop();
    for(int i = 0;i < s.length();i++){
      if(s[i] == '(' || s[i] == '[') c.push(s[i]);		
      else if(s[i] == ')' && c.top() == '(')c.pop();
      else if(s[i] == ']' && c.top() =='[') c.pop();
    }
    if(c.size() == 1) cout<<"yes"<<endl;
    else cout<<"no"<<endl;
  }
  return 0;
}