帯山中学校2年生の時に全国中学軟式野球大会で優勝。当時の3年生に松崎秀昭（元南海）と御船英之（元ダイエー、広島、近鉄）がいる。九州学院高校では1年生の秋から主戦で登板、1983年秋季九州大会県予選決勝で鎮西高に進学していた松崎と投げ合うが敗退。翌1984年、2年春のRKK旗大会では3試合連続完封で優勝に導く。同年夏の甲子園県予選準々決勝では、強豪済々黌高を相手に9回2死までノーヒットノーラン。しかし準決勝で熊本工の二宮正己に抑えられ敗れる。1985年の3年時は肘の故障で投げられず、主に四番打者・一塁手として出場した。夏の県予選では熊本西高に決勝で敗れ甲子園出場を逸する。尚、学校では部活をしている生徒に珍しく、特進クラスの英語コースに3年間所属していた。卒業後は明治大学に進学。東京六大学野球リーグでは1986年秋季リーグで優勝を経験するが、自身の活躍の場はなかった。3年生の1988年春季リーグから投手として起用され、4年生の1989年春季リーグで大きく飛躍、148km/hを超すストレートでプロの注目を浴びる。リーグ通算14試合に登板、7勝4敗、防御率3.62。卒業後は野球部のない一般企業、安田信託銀行への就職が内定していたが、これは父親が京都大学法学部卒業でもあり、厳格な家庭で育った為、野球は大学までと決めていたから。しかし1989年のドラフト会議にて横浜大洋ホエールズが2位で指名。同じく横浜大洋ホエールズに4位で今久留主成幸、日本ハムファイターズに4位で舟山恭史が指名を受け、同大学から3人がプロから指名を受けた。当然交渉は難航したが、翌1990年の1月にようやく入団が発表された。その際の契約では将来はビジネスに携わりたいとの希望で、野球引退後に親会社勤務（マルハ）の契約を結んでいた。契約内容は大洋漁業本社（マルハ）に就職で、その子会社、横浜大洋球団に出向というものであった。本人が当時の球団社長と交渉し、その旨の「覚書」を作成した。尚、この時の経験が現在のビジネスに大きな影響を与えている。（但し広島移籍時に、当時の横浜球団の社長と会談。広島に行く場合は、上記契約を解除すると言われ、契約を破棄する）。入団後、1年目中盤から一軍に登板。先発を主にしていたが3年目からリリーフに転向。1992年シーズン序盤の登板過多により肩を故障、それから思うように投げることが出来ずに苦しんだ。1993年シーズン開幕2日前に永野吉成とのトレードで千葉ロッテマリーンズに移籍。1996年オフに自由契約となる。その後、同年秋に広島東洋カープと契約。1997年の6月後半から自己最多の37試合に登板し7年ぶりの勝利を挙げるなど活躍をする。しかし翌1998年自由契約となり、同年秋に大学の先輩である星野仙一監督の中日ドラゴンズにテスト入団。1999年オフ、小池秀郎、佐野重樹、善村一仁とのトレードで門倉健、古池拓一とともに5球団目となる大阪近鉄バファローズへ移籍。2000年限りで現役引退。現役11年間で5球団も移籍し、当時では珍しい日本型「ジャーニーマン」である。引退時に、メジャー球団よりスプリングキャンプ招待の話があったが固辞。マイナー契約であったが肘の手術込みで２年の複数年契約の内容だった。引退後、政治家関連の仕事を経て、東京都内の商社勤務等。その後独立。現在はスポーツマネジメント業務を主に行う。分野は野球がメインで、日本のプロ野球の選手、コーチ、そしてメジャーリーグ（マイナー）の選手をクライアントに持つ。（2013年度にクライアントが帰国し、現在メジャー選手はいない）これまでに数多くの契約交渉や、FA移籍案件のコンサルティングを行ってきている。
この方式では、次の有名な例のように、同じ入力を同じ構文規則で複数の解釈ができてしまう曖昧性が避けられない。 /* stmt2って一体どっちのIFが不成立のときに実行したいの？ */ IF expr1 IF expr2 stmt1; ELSE stmt2;Yaccではyaccコマンド実行時に解釈が複数生じる曖昧なケースを発見した場合に「還元／還元衝突警告」または「シフト／還元衝突警告」を出す。これによって、文法を作成中なら文法を、そうでなければ構文規則を改良するきっかけが得られる。まず「還元／還元衝突警告」が出た場合であるが、パーサが正しい処理をできない構文要素が生じてしまうので、文法、または構文規則のYacc定義を直した方がよい。ある非終端記号から別の非終端記号に至る呼び出しパスが複数あれば、それは間違いなので直す。しかし元の言語が複雜すぎてうまく直せない場合は、片方を実体は同じでも別の名前を付けるトークン由来で構成するようにし、Lex側がどちらのトークンをYaccパーサに出すかは状態に応じて変えるようにコーディングしておく方法がある：状態がトークン列だけから一意に決められるならLex単独で処理できる。しかし、Yaccが実行時にあるルールのマッチを検出したときにはじめて状態を変えたいという複雜なケースでは、次のようにする。LexとYaccで共通の状態変数を設けておき、Yaccの{ }内に記述するアクションで、区別したい何かのフェーズなどの状態に応じて状態変数値を変えてやる。そうすればLexの生成したレキシカルアナライザは、実行時にまさに読んでいる入力トークン列による状態変数値に応じて、ある入側トークンを別々のトークンに動的に変換し分けてYaccの生成したパーサに渡す、という方法である。非常にダイナミックな技である。次に「シフト／還元衝突」であるが、このときYaccは標準で、（特に演算子優先規則で指定されていないかぎり）シフトを選ぶようにできている。たとえば上記の例ではexpr2不成立のときにstmt2を実行するようにパーサのテーブルが作られる。このように距離の近い記号の関係を優先するよう動作するのは、多くのプログラミング言語のコンパイラに向いているといわれているが、後述のように注意が必要である。構文上期待外のトークンがくるとアクションが見つからないので、パーサは、状態を戻して、errorという特定トークンのアクションがその状態に定義されているかどうか調べ、あれば実行する。最大3回まで戻しても見つからないときには入力テキストが途中でもそこでパースを打ち切ってしまう。これを利用してたとえば命令リストにerrorトークンのみの右辺をOR（|）結合しておけば、ある命令に属するオペランドに期待外トークンがあっても、そこで警告を出して次の命令以降のパースを続行してくれる、使いやすいコンパイラを作ることができる。ただ最大3回固定なので、深さの差3以内の上位にerrorを処理する構文を書いておかなければ利用できない。またはy.tab.cファイルの変数yyerrstatusの初期値を10などと増やしてやる必要がある。Yacc実行時に報告されるシフト／還元衝突は、シフトが選ばれるだけで十分と確信できるケース以外は、実は本来0件にしておくべきである。なぜならパーサ実行時にシフトが選ばれて動作することにより、入力されたトークン列によっては行き止まりになる。すなわち期待外のトークンとされ、上記のエラー処理に飛んでしまうからである。Yaccは衝突に対応する枝分かれをすべてバックトラックでたどって解空間を全探索するようにはできていないのである。このため、衝突を残しておくとパーサを当然通ると思った入力が通らず苦労することになる。