2008年9月21日日曜日

式評価とポーランド記法化


screen 0,700,600
;mes 12 + 24 * limit ( 68 ,36+48*sin(85), 120+64 ) * 59 +( 63>=23)
buf="12 + 24 * limit ( 68+89 ,36+48*sin(85), 120+64 ) * 59 +( 63>=23)"
;buf="24 * limit ( 68+89 ,48*aa(85+77,99*2), 120+64 )"
mes buf
len=strlen(buf)
sdim buf2,len

repeat
data=peek(buf,c)
if (data=' '||data=9)=0{
poke buf2,c2,data
c2+
}

c+
if c=len:c=0:c2=0:break
loop//--------------------------

mes buf2

len=strlen(buf2)
sdim buf,len
buf=buf2
sdim buf2,len

repeat
data=peek(buf,c)
if data='+'||data='-'||data='*'||data='/'||data='\\'||data='|'||data='&'||data='^'||data='='||data='>'||data='<'||data='!'{
poke buf2,c,'C'
}else : if data='('{
poke buf2,c,'B'
}else : if data=')'{
poke buf2,c,'D'
}else : if data=','{
poke buf2,c,'K'
}else : poke buf2,c,'A'
c+
if c=len:c=0:break
loop//--------------------------

mes buf2

len=strlen(buf2)

repeat
data=peek(buf2,c)
if data='A'{
c2=c
func=0
repeat
data=peek(buf2,c2)
if data!='A'{
if data='B':func=1
break
}
c2+
if c2=len:break
loop
c2=0

if func{
repeat
data=peek(buf2,c)
if data ! 'A':break
poke buf2,c,'F'
c+
if c=len:c=0:break
loop
}
}

c+
if c>=len:c=0:break
loop//--------------------------
mes "シンボル化"
mes buf2

len=strlen(buf2)
sdim buf3,len
sdim ad,len,len
sdim cd,len,len

repeat
data=peek(buf2,c)
if data='A'{
poke buf3,c3,'A'
c3+
repeat
if peek(buf2,c+c2)!'A':break
data2=peek(buf,c+c2)
poke ad(ac),c2,data2
c2+
loop
c2-
c=c+c2
c2=0
ac+
}else :if data='C'{
poke buf3,c3,'C'
c3+
repeat
if peek(buf2,c+c2)!'C':break
data2=peek(buf,c+c2)
poke cd(cc),c2,data2
c2+
loop
c2-
c=c+c2
c2=0
cc+
}else : if data='F'{
poke buf3,c3,'F'
c3+
repeat
if peek(buf2,c+c2)!'F':break
data2=peek(buf,c+c2)
poke cd(cc),c2,data2
c2+
loop
c2-
c=c+c2
c2=0
cc+
}else {
poke buf3,c3,data
c3+
}
c+
if c>=len:c=0:break
loop//--------------------------
c3=0
cc=0
ac=0

buf2=buf3
mes "シンボル簡易化"
mes buf2

len=strlen(buf2)
dim bk,len
dim ck,len


repeat//--------------------------
data=peek(buf2,c)
if data='B':lv+

if data='C'||data='F'{
ck(cc)=lv
cc+
}
if data='B'||data='D'||data='K'{
bk(bc)=lv
bc+
}
if data='D':lv-
c+
if c>=len:c=0:break
loop
bc=0
cc=0


dim cy,len
dim ch,len
repeat//--------------------------
data=peek(buf2,c)
if data='C'{
data2=cd(cc)
h=0
if data2="*":cy(cc)=5:ch(cc)=2:h=1
if data2="/":cy(cc)=5:ch(cc)=2:h=1
if data2="\\":cy(cc)=5:ch(cc)=2:h=1
if data2="+":cy(cc)=4:ch(cc)=2:h=1
if data2="-":cy(cc)=4:ch(cc)=2:h=1
if data2="<<":cy(cc)=3:ch(cc)=2:h=1
if data2=">>":cy(cc)=3:ch(cc)=2:h=1
if data2="=":cy(cc)=2:ch(cc)=2:h=1
if data2="==":cy(cc)=2:ch(cc)=2:h=1
if data2="!":cy(cc)=2:ch(cc)=2:h=1
if data2="!=":cy(cc)=2:ch(cc)=2:h=1
if data2=">":cy(cc)=2:ch(cc)=2:h=1
if data2="<":cy(cc)=2:ch(cc)=2:h=1
if data2=">=":cy(cc)=2:ch(cc)=2:h=1
if data2="<=":cy(cc)=2:ch(cc)=2:h=1
if data2="&":cy(cc)=1:ch(cc)=2:h=1
if data2="&&":cy(cc)=1:ch(cc)=2:h=1
if data2="|":cy(cc)=1:ch(cc)=2:h=1
if data2="||":cy(cc)=1:ch(cc)=2:h=1
if data2="^":cy(cc)=1:ch(cc)=2:h=1
if h=0:dialog "式の記述が無効です。 不明な演算子 \" "+data2+" \""
cc+
}
if data='F'{
cy(cc)=6
cc+
}
c+
if c>=len:c=0:break
loop
h=0
fhm=0
cc=0
dim cf,len
repeat//--------------------------
data=peek(buf2,c)
if data='B'||data='D'||data='K'{
bc+
}
if data='F'{
k=bk(bc)
c2=2
repeat
data2=peek(buf2,c+c2)
if data2='B'||data2='D'||data2='K'{
bc2+


}
if k=bk(bc+bc2){
if data2='A':d=1
if data2='K':fh+
if data2='D':break
}
c2+
if c+c2>=len:c2=0:break
loop
bc2=0
c2=0
fh+
if d=0:fh=0
d=0
if fhm<fh:fhm=fh
ch(cc)=fh
cf(cc)=1
fh=0
cc+
poke buf2,c,'C'
}
if data='C'{
cf(cc)=0
cc+
}
c+
if c>=len:c=0:break
loop
cc=0
bc=0
mes buf2

sdim buf3,len
dim c_st,len
dim ca,len
c_sa=0
c3=0
repeat//--------------------------
data=peek(buf2,c)
if data='C'{
data2=peek(buf2,c+1)
repeat
if c_sa!0&&(ck(c_st(c_sa))>ck(cc)||((ck(c_st(c_sa))=ck(cc)&&cy(c_st(c_sa))>=cy(cc)))){
ca(c4)=c_st(c_sa)
poke buf3,c3,'C'
c3+
c4+
c_sa-
}else : break
loop
if data2='A'{
poke buf3,c3,'A'
c3+
c+
data2=peek(buf2,c+1)
}
if data2='B'{
c_sa+
c_st(c_sa)=cc
}
if data2='C'{
if (ck(cc+1))>ck(cc)||(ck(cc+1)=ck(cc)&&cy(cc+1)>=cy(cc)){
c_sa+
c_st(c_sa)=cc
}else{
ca(c4)=cc
poke buf3,c3,'C'
c3+
c4+
}
}
if data2='K'||data2='D'||data2=0{
ca(c4)=cc
poke buf3,c3,'C'
c3+
c4+
}

cc+
}

if data='K'||data='D'||data=0{
lv=bk(bc)
if data=0:lv=0
repeat
if c_sa!0&&lv=ck(c_st(c_sa)){
ca(c4)=c_st(c_sa)
poke buf3,c3,'C'
c3+
c4+
c_sa-
}else :break
loop
}

if data='B'||data='K'||data='D'{
bc+
}

if data='A'{
poke buf3,c3,'A'
c3+
}
c+
if c>=len+1:c=0:break
loop
bc=0
c2=0
c3=0
c4=0
cc=0
mes "\n逆ポーランド記法化(シンボル)"
mes buf3
/*いらない↓*/
sdim buf4,512
len=strlen(buf3)
repeat//--------------------------
data=peek(buf3,c)
if data='A'{
buf4+=ad(ac)+" "
ac+
}
if data='C'{
buf4+=cd(ca(cc))
if cf(ca(cc)):buf4+="()"
buf4+=" "
cc+
}
c+
if c>=len+1:c=0:break
loop
mes "\n逆ポーランド記法化(人間が認識できるようにするだけなので内部処理的にはいらない 上と同じ)"
mes buf4
/*いらない↑*/
cc=0
ac=-1
dim a_st,len//各数値がどのスタックにあるか
sdim st_st,fhm//引数に渡す値の配列
sdim buf5,512
st2=0//引数の順番
ac=-1
c2=0

repeat//--------------------------
data=peek(buf3,c)
if data='A'{

ac+
}
if data='C'{
retn=ch(ca(cc))
st_itiml=0
st_itims=0
st2=0

syu=0
repeat retn//引数に渡す値を配列に収納

st_iti=a_st(ac-c2)
if st_iti=0{

st_st(st2)=ad(ac-c2)
st2+
c2+

}else{

st_st(st2)="st"+a_st(ac-c2)
st2+
c2+
if st_itims>st_iti || st_itims=0:st_itims=st_iti
if st_itiml<st_iti:st_itiml=st_iti
;dialog st_itims
}
repeat
if (ac-c2)<0:syu=1:break
st_iti2=a_st(ac-c2)

if st_iti2=0:break
if st_iti!=st_iti2:break
c2+
loop
if syu=1:break

loop

if st_itims=0{
st+
}else{
st=st_itims
}

repeat c2
a_st(ac-cnt)=st
loop

buf5+="st"+st+" = "
if cf(ca(cc)){
buf5+=cd(ca(cc))+"( "
repeat retn
if retn!1&&cnt!0 :buf5+=", "
f=retn-cnt
buf5+=st_st(retn-cnt-1)
loop
buf5+=" )"
}else{
buf5+=st_st(1)+" "+cd(ca(cc))+" "+st_st(0)

}
buf5+="\n"
c2=0
st2=0
cc+
}

c+
if c>=len:c=0:break
loop
buf5+="ans = st1"

mes "\n\n変換前の数式"
mes buf
mes "\n変換後の数式\n"
mes buf5

0 件のコメント: