>>366
parse_charとparse_unitは文字列の一部を解析する関数で、
解析を開始する位置の文字へのポインタを第一引数として受け取って、
解析し終わった位置の次の文字へのポインタ、または
解析に失敗したときはNULLを返す。
parse_charは決まった文字cを解析する。だから、*str==cのときのみ成功し、
次の文字へのポインタを返す。!strや!cのとき無条件に失敗するのは、後で役に立つ。
parse_unitはアラビア数字の一桁に相当するものを解析し、結果を*outに入れる。
例えば、MMMXXIXなら「MMM」(3), 「」(0), 「XX」(2), 「IX」(9)の4桁からなっていると考える。
この関数は、注目している桁の基本となるローマ数字(one)と、その5倍(five)、10倍(ten)を表す
ローマ数字(適切な文字がないときは'\0')を引数としてとる。
例えば、10の位に注目しているなら、one='X', five='L', ten='C'で呼び出される。
ところで、parse_charを入れ子にして呼び出すと、特定の文字の並びを解析できる。例えば
parse_char(parse_char(str, 'a'), 'b')と呼び出すと、strが"ab"ではじまるときのみ解析が成功し、
さらに次の文字(strの三文字め)を指すポインタを返す(なぜこうなるか考えてみよ)。途中で解析が
失敗すると、parse_charからNULLが返り、それを受け取った次のparse_charも即座に失敗し、これが繰り返されるので、
全体が失敗してNULLが返ることに注意。さて、これを利用して、例えば
ret = parse_char(parse_char(src, one), ten)とすれば「one, ten」というローマ数字の並びを解析でき、
これはつまり注目している桁が「9」だということを意味する。同様に8から1までもテストして、結果に応じて
*outに値を代入して返る。全てのテストが失敗したときは、この桁には数字がなかったと考えて、*outに0を代入して返る。
mainでは、大きい桁から順にparse_unitを呼び、それぞれの桁を10倍しながら足し合わせて、結果を得る。
最終的に文字列が全て消費されていないときは、どこかで失敗しているのでエラーメッセージを表示。
そうでなければ成功しているはずなので結果を表示して終了。