53歳限界プログラマの憂鬱

SU/CAR-ST-APplication-cellsから派生したプログラマのブログ

来訪ありがとうございます
シストレツールを自作してました
自分用の記事が多いのであまり役には立たないブログでした

f:id:sucar:20150414193802p:plain

自作システム詳細目次

awk sed を駆使してm4マクロを自動生成

2020/6/22改定版)

自作システムのストラテジー記述でマクロが使えるようにしている(m4マクロ)

で・・・

マクロを記述するのが結構面倒

そこで、マクロのテンプレートファイルを準備して

./m4_XX2.m4

define(`ExXXp',`_xx_')dnl
dnl pXX pXX(N) pXX(d,u) pXX(d,u,N) pXX(d,u,N,s),pXX(d,u,N,s,name)
define(`pXX',`ifelse(`$#', `0',`_P_	dmy	dmy	ExXX		ExXXp(0)	dmy$0
',`$#', `1',`_P_	dmy	dmy	ExXX$1	ExXXp($1)	dmy$0
',`$#', `2',`_P_	$1	$2	ExXX		ExXXp(0)	dmy$0
',`$#',	`3',`_P_	$1	$2	ExXX$3	ExXXp($3)	dmy$0
',`$#',	`4',`_P_	$1	$2	ExXX$3$4	ExXXp($3)	dmy$0
',			`_P_	$1	$2	$5		ExXXp($3)	dmy$0
')')dnl
dnl pXXd=pXX pXXd(d) pXXd(d,N)  pXXd(d,N,s)
define(`pXXd',`ifelse(`$#', `0',`_P_	dmy	dmy	ExXX		ExXXp(0)	dmy$0
',`$#', `1',`_P_	_min_	$1	ExXX		ExXXp(0)	dmy$0
'          ,`_P_	_min_	$1	ExXX$2$3	ExXXp($2)	dmy$0
')')dnl
dnl pXXu=pXX pXXu(u) pXXu(u,N) pXXu(u,N,s)
define(`pXXu',`ifelse(`$#', `0',`_P_	dmy	dmy	ExXX		ExXXp(0)	dmy$0
',`$#', `1',`_P_	$1	_max_	ExXX		ExXXp(0)	dmy$0
'          ,`_P_	$1	_max_	ExXX$2$3	ExXXp($2)	dmy$0
')')dnl

dnl sXX sXX(N) sXX(d,u) sXX(d,u,N) sXX(d,u,N,s),sXX(d,u,N,s,name)
define(`sXX',`ifelse(`$#', `0',`_S_	dmy	dmy	ExsXX		ExXXp(0)	dmy$0
',`$#', `1',`_S_	dmy	dmy	ExsXX$1	ExXXp($1)	dmy$0
',`$#', `2',`_S_	$1	$2	ExsXX		ExXXp(0)	dmy$0
',`$#',	`3',`_S_	$1	$2	ExsXX$3	ExXXp($3)	dmy$0
',`$#',	`4',`_S_	$1	$2	ExsXX$3$4	ExXXp($3)	dmy$0
'		   ,`_S_	$1	$2	$5		ExXXp($3)	dmy$0
')')dnl
dnl sXXd=sXX sXXd(d) sXXd(d,N)  sXXd(d,N,s)
define(`sXXd',`ifelse(`$#', `0',`_S_	dmy	dmy	ExsXX		ExXXp(0)	dmy$0
',`$#', `1',`_S_	_min_	$1	ExsXX		ExXXp(0)	dmy$0
'          ,`_S_	_min_	$1	ExsXX$2$3	ExXXp($2)	dmy$0
')')dnl
dnl sXXu=sXX sXXu(u) sXXu(u,N) sXXu(u,N,s)
define(`sXXu',`ifelse(`$#', `0',`_S_	dmy	dmy	ExsXX		ExXXp(0)	dmy$0
',`$#', `1',`_S_	$1	_max_	ExsXX		ExXXp(0)	dmy$0
'          ,`_S_	$1	_max_	ExsXX$2$3	ExXXp($2)	dmy$0
')')dnl

これの

  • XXをパラメタ名に
  • _xx_をパラメタの式表現に
  • _min_をデフォルト時のminの値に
  • _max_をデフォルト時のmaxの値に

置換すれば、マクロが自動生成される仕組み

置換にはsedを使うが、sedスクリプトawkで生成する(ややこしい)

../awk/mkm4_2.awk

$1!=NULL && $2!=NULL {
	if ($3=="") MIN="-80" 
	else MIN=$3+""
	if ($4=="") MAX="80" 
	else MAX=$4+""
	printf("cat ./m4_XX2.m4 |sed -e 's/XX/%s/g;s:_xx_:%s:g;s/_min_/%s/g;s/_max_/%s/g' >./m4/m4_%s.m4\n",$1,$2,MIN,MAX,$1)
}

 こんなawkスクリプトを準備して

./mkm4

echo cd `dirname $0`
cd `dirname $0`
pwd

cat <<EOF |sed -e 's/\[N/\[\$1/g;s/{N/{\$1/g' |awk -f ../awk/mkm4_2.awk | bash

A	-(hei25[N]-owa[N])/owa[N]*100
A125A	-(hei125[N]-owa[N])/owa[N]*100
A75A	-(hei75[N]-owa[N])/owa[N]*100
B	-(hei5[N]-owa[N])/owa[N]*100
E	dxhei5[N]/owa[N]*100
F	hei5_25[N]/owa[N]*100
R	(owa[N]-hjm[N])/hjm[N]*100
RT	(tak[N]-hjm[N])/hjm[N]*100
RY	(yas[N]-hjm[N])/hjm[N]*100
Z	(owa[N]-hjm[N+1])/hjm[N+1]*100
ZT	(tak[N]-hjm[N+1])/hjm[N+1]*100
ZY	(yas[N]-hjm[N+1])/hjm[N+1]*100
DPD	da[N]/da[N+1]	0	1000000
OW	owa[N]	1	1000000
THG	(tak[N]-owa[N])/owa[N]*100
D	da[N]	0	1000000000000
C0C	owa[N]-owa[N]	-10000	10000
H75I	Heihei75{N}-Heihei75{N+1}
H75_2I	Heihei75{N}-(Heihei75{N+1}+Heihei75{N+2})/2
M5M	m5[N]	-5	5
M25M	m25[N]	-5	5
M	5*m25[N]+m5[N]	-25	25
EOF
echo m4f...
cat ./m4/* | m4 -F ./esgrs/esgrs.m4f

 というshell scriptを走らせるとマクロを自動生成する(ややこしい)

here documents を活用して、パラメタをズラズラ直接記述すれば、パラメタ追加が簡単

便利になったけど、ややこしい・・・・