このディレクトリの索引
http://pc12.2ch.net/test/read.cgi/tech/1260532772/309
#  [1] 授業単元: プログラミング演習  
#  [2] 問題文(含コード&リンク): http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10297.txt 
# ●基本課題 2a(数式の読み込みと表示)
# 
# 課題 2a と 2b では,算術式を読み,表示し,値を求めるプログラムを作る.
# 
# 限られた時間内で数式処理の本質部分を効率よく学ぶために,
# 入力できる算術式の構文を,次の BNF で定めるものに限る.
# 
# 	定数   ::= 0 | 1 | … | 9
# 	変数   ::= a | b | … | z | A | B | … | Z
# 	算術式 ::= 定数
# 	         | 変数
# 	         | (算術式+算術式)
# 	         | (算術式*算術式)
# 
# つまり,1桁の定数や1文字の変数の和や積からなる式が入力である.
# 
# 入力された算術式を読み込み,2分木データとして格納し,そのデータをもとに
# 入力と同じ算術式を表示する,という処理(下図)を繰り返すプログラムを作れ.
# 

算術式解析(_文,_残りの文,_初期節番号,_終了節番号,_式) :-
    atom_chars(_文,Chars),
    算術式(_初期節番号,_終了節番号,Chars,R,_式),
    atom_chars(_残りの文,R),!.

定数(A) :- member(A,['0','1','2','3','4','5','6','7','8','9']),!.
変数(A) :- member(A,[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]),!.
変数(A) :- member(A,['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']),!.
算術式(N1,N2,[A|R],R,B) :-
    定数(A),
    atom_to_term(A,B,_),
    assertz(算術式構文木(N1,[],[],B)),
    N2 is N1 + 1,!.
算術式(N1,N2,[A|R],R,A) :-
    変数(A),
    assertz(算術式構文木(N1,[],[],A)),
    N2 is N1 + 1,!.
算術式(N1,N2,L,R,'+'(S1,S2)) :-
    append(['('|L1],[')'|R],L),append(L2,['+'|L3],L1),
    N3 is N1 + 1,
    算術式(N3,N4,L2,_,S1),算術式(N4,N2,L3,_,S2),
    assertz(算術式構文木(N1,N3,N4,'+')),!.
算術式(N1,N2,L,R,'*'(S1,S2)) :-
    append(['('|L1],[')'|R],L),append(L2,['*'|L3],L1),
    N3 is N1 + 1,
    算術式(N3,N4,L2,_,S1),算術式(N4,N2,L3,_,S2),
    assertz(算術式構文木(N1,N3,N4,'*')),!.