このディレクトリの索引

# 出典 :: #535 # [1] C++ # [2] 問題文(含コード&リンク): # (1) 演算子+,-,*,/と整数と浮動小数点数からなる計算式の文字列から # 計算木を作成せよ。計算木は次のようなc_tree構造体を使うとする。 # # struct c_tree # { # int type; # union { int n_value; double d_value; }; # c_tree *left, *right; # }; # typeは、'+', '-', '*', '/', 'n', 'd'のいずれか。 # # (2) 優先順位に注意してc_tree構造体からなる計算木から # 計算式の文字列を作成せよ。 文字列から式の生成(_文字列,_式) :- atom_chars(_文字列,Chars), 語彙の切り出し(Chars,_語彙ならび,OpsX,_), 結合度評価(OpsX,_語彙ならび,_式). 語彙の切り出し(L,X,OpsX,R) :- 語彙の切り出しの一(L1,Y,[],OpsX,R), 数値へ変換(Y,X),!. 語彙の切り出しの一([],[],OpsX,OpsX,[]) :- !. 語彙の切り出しの一([')'|L1],[],OpsX,OpsX,L1) :- !. 語彙の切り出しの一(['('|L1],[L2|R2],OpsY,OpsX,R) :- 括弧構造の解析(L1,L2,OpsY,OpsX1,R1), 語彙の切り出しの一(R1,R2,OpsX1,OpsX,R). 語彙の切り出しの一(L1,[C|R2],OpsY,OpsX,R) :- is_op(A,B,C), member([A,B,C],OpsY), atom_chars(C,Chars), append(Chars,R1,L1), 語彙の切り出しの一(R1,R2,OpsY,OpsX,R). 語彙の切り出しの一([A|R1],R2,OpsY,OpsX,R) :- member(A,[' ','\t','\n']), 語彙の切り出しの一(R1,R2,OpsY,OpsX,R),!. 語彙の切り出しの一(L1,[C|R2],OpsY,OpsX,R) :- is_op(A,B,C), not(member([A,B,C],OpsY)), atom_chars(C,Chars), append(Chars,R1,L1), 語彙の切り出しの一(R1,R2,[[A,B,C]|OpsY],OpsX,R). 語彙の切り出しの一(L1,[W|R2],OpsY,OpsX,R) :- 語彙の切り出しの二(L1,G,L2), 数値へ変換(G,W), 語彙の切り出しの一(L2,R2,OpsY,OpsX,R). 語彙の切り出しの二([],[],[]) :- !. 語彙の切り出しの二([')'|R],[],[')'|R]) :- !. 語彙の切り出しの二([' '|R],[],R) :- !. 語彙の切り出しの二(['\t'|R],[],R) :- !. 語彙の切り出しの二(L1,[],L1) :- is_op(A,B,C), atom_chars(C,Chars), append(Chars,R,L1),!. 語彙の切り出しの二([A|R1],[A|R2],R) :- 語彙の切り出しの二(R1,R2,R). 括弧構造の解析([')'|R],[],OpsX,OpsX,R). 括弧構造の解析(L,L1,OpsY,OpsX,R) :- 語彙の切り出しの一(L,L1,OpsY,OpsX,R). 結合度評価(_式に現れるop,_語彙ならび,_項) :- sort(_式に現れるop,_整列したop), reverse(_整列したop,_結合度順op), 結合度評価の一(_結合度順op,_語彙ならび,_項). 結合度評価の一(_,[A],A) :- atomic(A),!. 結合度評価の一([[_結合度,yfx,Op]|R1],_語彙ならび,P) :- append(L1,[Op|L2],_語彙ならび), 結合度評価の一([[_結合度,yfx,Op]|R1],L1,X1), 結合度評価の一([[_結合度,yfx,Op]|R1],L2,X2), functor(P,Op,2), arg(1,P,X1), arg(2,P,X2),!. 結合度評価の一([_|R1],_語彙ならび,P) :- 結合度評価の一(R1,_語彙ならび,P). 数値へ変換(L,_数値,R) :- 整数生成(L,_数値,R,),!. 数値へ変換(L,_数値,R) :- 浮動小数点数生成(L,_数値,R),!. 整数生成([A|R],N,R) :- atom_chars(A,L), length(L,Len), 整数生成の一(L,_,N),!. 整数生成の一([],1,0) :- !. 整数生成の一([A|R1],U,X) :- 文字整数変換(A,N), 整数生成の一(R1,U2,Y), U is U2 * 10, X is N * U2 + Y,!. 文字整数変換('0',0). 文字整数変換('1',1). 文字整数変換('2',2). 文字整数変換('3',3). 文字整数変換('4',4). 文字整数変換('5',5). 文字整数変換('6',6). 文字整数変換('7',7). 文字整数変換('8',8). 文字整数変換('9',9). 浮動小数点数生成([A,(+),C|R],F,R) :- sub_atom(A,_,1,0,e), concat_atom([A,(+),C],D), atom_chars(D,L), 浮動小数点数生成の一(L,_F),!. 浮動小数点数生成([A,(-),C|R],F,R) :- sub_atom(A,_,1,0,e), concat_atom([A,(+),C],D), atom_chars(D,L), 浮動小数点数生成の一(L,_,F),!. 浮動小数点数生成([A|R],F,R) :- atom_chars(A,L), 浮動小数点数生成の一(L,_,F). 浮動小数点数生成の一(L,'e+',F) :- append(L1,['e','+'|L2],L), append(L11,['.'|L12],L1), length(L12,Len1), 浮動小数点数の一(L1,'.',F1), F is F1 * (10 ^ Len1). 浮動小数点数生成の一(L,'e-',L11,L12,L2) :- append(L1,['e','+'|L2],L), append(L11,['.'|L12],L1), length(L12,Len1), 浮動小数点数の一(L1,'.',F1), F is F1 / (10 ^ Len1). 浮動小数点数生成の一(L,'.',F) :- append(L1,['.'|L2],L), length(L2,Len), append(L1,L2,L3), 整数生成の一(L3,_,N), F is N / ( 10 ^ Len),!. is_op(400,yfx,(+)). is_op(400,yfx,(-)). is_op(500,yfx,(*)). is_op(500,yfx,(*)).