--- /dev/null
+CC = gcc
+CFLAGS = -g
+.PHPNY: clean
+hoc1: hoc.o
+ $(CC) $(CFLAGS) -o $@ $^
+clean:
+ rm -f hoc1 hoc.tab.c *.o
+ make clean -sC test
+check:
+ @make -sC test
--- /dev/null
+%{
+#define YYSTYPE double /* data type of yacc stack */
+#include <stdio.h>
+#include <ctype.h>
+%}
+
+%token NUMBER
+%left '+' '-' /* left associative, same precedence */
+%left '*' '/' '%' /* left associative, higher precedence */
+%left UNARYMINUS UNARYPLUS
+%%
+list: /* nothing */
+ | list '\n'
+ | list expr '\n' { printf("\t%.8g\n", $2); }
+;
+expr: NUMBER { $$ = $1; }
+ | expr '+' expr { $$ = $1 + $3; }
+ | expr '-' expr { $$ = $1 - $3; }
+ | expr '*' expr { $$ = $1 * $3; }
+ | expr '/' expr { $$ = $1 / $3; }
+ | expr '%' expr { $$ = (int)$1 % (int)$3; }
+ | '(' expr ')'{ $$ = $2; }
+ | '-' expr %prec UNARYMINUS { $$ = -$2; }
+ | '+' expr %prec UNARYPLUS { $$ = $2; }
+;
+%% /* end of grammer */
+
+char *progname; /* for error messages */
+int lineno = 1;
+
+int main(int argc, char *argv[]) {
+ progname = argv[0];
+ yyparse();
+}
+
+int yylex(){
+ int c;
+ while((c = getchar()) == ' ' || c == '\t') {
+ ;
+ }
+ if(c == EOF) {
+ return 0;
+ }
+ /* number */
+ if(c == '.' || isdigit(c)) {
+ ungetc(c, stdin);
+ scanf("%lf", &yylval);
+ return NUMBER;
+ }
+ if(c == '\n') {
+ lineno++;
+ }
+ return c;
+}
+
+/* called for yacc syntax error */
+int yyerror(char *s) {
+ warning(s, (char *)0);
+}
+
+/* print warning message */
+int warning(char *s, char *t) {
+ fprintf(stderr, "%s: %s", progname, s);
+ if(t) {
+ fprintf(stderr, " %s", t);
+ }
+ fprintf(stderr, " near line %d\n", lineno);
+}
--- /dev/null
+######################################################################
+# テストテンプレートのディレクトリー
+######################################################################
+# テストグループのMakefileとしてコピーされるファイル
+GROUP_MAKEFILE = Group.mk
+
+######################################################################
+# テストグループのディレクトリー
+######################################################################
+# グループディレクトリー
+GROUP_DIR = $(shell pwd)
+
+# グループ名。ディレクトリ名から取得
+GROUP = $(notdir $(GROUP_DIR))
+
+# テスト名。カレントディレクトリー内の、名前が大文字または.以外で始まるディレクトリー
+TESTS = $(notdir $(shell find -maxdepth 1 -name "[^A-Z.]*" -type d))
+
+# テストグループとテストの両方で使う変数を定義したファイル
+DEF_FILE = Define.mk
+
+# テストのMakefileにインクルードするファイル
+TEST_MAKEFILE = Test.mk
+
+# テストグループログファイル
+GROUP_LOG_FILE = $(shell echo $(GROUP) | tr '[a-z]' '[A-Z]').log
+
+# 成功したテストの数。テストグループログファイルから取得
+SUCCESS_TEST = $(shell grep "^[^A-Z.].*: Test Success" $(GROUP_LOG_FILE) | wc -l)
+
+# 失敗したテストの数。テストグループログファイルから取得
+FAIL_TEST = $(shell grep "^[^A-Z.].*: Test Failure" $(GROUP_LOG_FILE) | wc -l)
+
+# すべてのテストの数。
+ALL_TEST = $(shell expr $(SUCCESS_TEST) + $(FAIL_TEST))
+
+######################################################################
+# テストのディレクトリー
+######################################################################
+# テスト名。カレントディレクトリー名から取得
+TEST = $(notdir $(shell pwd))
+
+# テストコマンドファイル
+CMD_FILE = cmd
+
+# テスト説明ファイル
+DESC_FILE = desc.txt
+
+# テスト想定結果ファイル
+TEST0_FILE = 0.txt
+
+# テスト結果ファイル
+TEST1_FILE = 1.txt
+
+# テストの、想定結果と結果の差分ファイル
+DIFF_FILE = diff.txt
+
+# テストエラーファイル
+ERR_FILE = err.txt
+
+# テストログファイル
+LOG_FILE = test.log
+
+# 現在の日時
+DATE = `date +"%F %T"`
+
+# テスト実行コマンド。CMD_FILEを実行する。
+# ファイルの内容と、テスト結果を表す標準出力を、ターゲットファイルに保存。
+# エラー発生時は、エラー出力をターゲットファイルとERR_FILEに保存。
+# ターゲットファイルは、TEST0_FILEまたはTEST1_FILE
+CMD = \
+ chmod u+x $(CMD_FILE); \
+ cat $(CMD_FILE) >$@; \
+ ./$(CMD_FILE) >>$@ 2>$(ERR_FILE); \
+ if test -s $(ERR_FILE); then cat $(ERR_FILE) >>$@; else rm -f $(ERR_FILE); fi
--- /dev/null
+# autotest.mk > template > Group.mk
+# テストグループのMakefile
+#
+# オペレーター
+# make : すべてのテストを実施し、ログファイルを作成
+# make check : ↓
+# make create : TESTNAMEで指定されたテストを新規に作成
+# make set : すべてのテストの、想定結果を出力
+# make checkeach: すべてのテストを実施
+# make report : ログファイルから、テストの結果をレポート
+# make clean : すべてのテストで、"make" で生成されたファイルをクリア
+# make cleanall: すべてのテストで、"make" と "make set" で生成されたファイルをクリア
+
+include Define.mk
+
+.PHONY: check create set checkeach report clean cleanall
+
+check: checkeach report
+
+create:
+ifndef TEST
+ @echo "no test created. set TEST."
+else
+ @mkdir $(TEST)
+ @for ifile in $(DEF_FILE) $(TEST_MAKEFILE); do echo "include ../$$ifile" >>$(TEST)/Makefile; done
+endif
+
+set:
+ @for target in $(TESTS); do $(MAKE) set -C $$target; done
+
+checkeach:
+ @rm -f $(GROUP_LOG_FILE)
+ @for target in $(TESTS); do $(MAKE) check -C $$target; done
+
+$(GROUP_LOG_FILE):
+ @for target in $(TESTS); do cat <$$target/$(LOG_FILE) >>$@ || echo $$target ": no log." >>$@; done
+
+report: $(GROUP_LOG_FILE)
+ @echo "$(GROUP): $(SUCCESS_TEST) / $(ALL_TEST) tests passed. Details in `pwd`/$(GROUP_LOG_FILE)"; \
+ if test $(FAIL_TEST) -eq 0; then echo "$(GROUP): All tests are succeded."; fi
+
+clean:
+ @for target in $(TESTS); do $(MAKE) clean -C $$target; done
+ @rm -f $(GROUP_LOG_FILE)
+
+cleanall:
+ @for target in $(TESTS); do $(MAKE) cleanall -C $$target; done
+ @rm -f $(GROUP_LOG_FILE)
--- /dev/null
+# autotest.mk > test_template > test.mk
+# 自動テスト用のMakefile
+#
+# 要: Define.mk
+#
+# オペレーター
+# make : CMDで設定されたコマンドを実行した出力結果を1.txtに出力し、0.txtと比較し、レポート
+# make check : ↓
+# make prepare : CMDで設定されたコマンドを実行した出力結果を0.txt(テストの想定結果)に出力
+# make clean : 「make」で生成されたファイルをクリア
+# make cleanall: 「make」と「make prepare」で生成されたファイルをクリア
+
+.PHONY: check set reset clean cleanall
+
+check: clean $(LOG_FILE)
+
+set: $(TEST0_FILE)
+
+reset: cleanall $(TEST0_FILE)
+
+clean:
+ @rm -f $(TEST1_FILE) $(DIFF_FILE) $(LOG_FILE) $(ERR_FILE)
+
+cleanall: clean
+ @rm -f $(TEST0_FILE)
+
+$(TEST0_FILE) $(TEST1_FILE):
+ @if test ! -s $(CMD_FILE); then echo "set command file: $(CMD_FILE)."; else $(CMD); fi
+
+$(DIFF_FILE): $(TEST1_FILE)
+ @-diff -c $(TEST0_FILE) $(TEST1_FILE) >$@ 2>&1
+
+$(LOG_FILE): $(DIFF_FILE)
+ @if test -s $(DESC_FILE); then cat $(DESC_FILE) >>$@; fi;
+ @if test ! -s $^; then echo "$(TEST): Test Success $(DATE)" >>$@; else echo "$(TEST): Test Failure $(DATE)" >>$@; fi;
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
+1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
+1.23456789 + 0.123456789
+1000000 + .1
+10000000 + .1
+1.2345678901e100 + 1.2345678901e91
++1
+ 55
+ 1.3580247
+ 1000000.1
+ 10000000
+ 1.2345679e+100
+ 1
--- /dev/null
+include ../Define.mk
+include ../Test.mk
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
--- /dev/null
+hoc1 - 足し算のテスト
--- /dev/null
+1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
+1.23456789 + 0.123456789
+1000000 + .1
+10000000 + .1
+1.2345678901e100 + 1.2345678901e91
++1
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
+4 / 2
+2 / 1
+2 / 2
+2 / 3
+10000 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10
+3.141592 / 2.718281828
+1000 / 0.0001
+1.23e2 / 321
+1.2345678901e100 / 1.2345678901e99
+/1
+ 2
+ 2
+ 1
+ 0.66666667
+ 0.0027557319
+ 1.1557271
+ 10000000
+ 0.38317757
+ 10
+../../hoc1: syntax error near line 10
--- /dev/null
+include ../Define.mk
+include ../Test.mk
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
--- /dev/null
+hoc1 - 引き算のテスト
--- /dev/null
+4 / 2
+2 / 1
+2 / 2
+2 / 3
+10000 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10
+3.141592 / 2.718281828
+1000 / 0.0001
+1.23e2 / 321
+1.2345678901e100 / 1.2345678901e99
+/1
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
+6 / 2
+2 / 1
+2 / 2
+2 / 3
+10000 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10
+3.141592 / 2.718281828
+1000 / 0.0001
+1.23e2 / 321
+1.2345678901e100 / 1.2345678901e99
+/1
+ 3
+ 2
+ 1
+ 0.66666667
+ 0.0027557319
+ 1.1557271
+ 10000000
+ 0.38317757
+ 10
+../../hoc1: syntax error near line 10
--- /dev/null
+include ../Define.mk
+include ../Test.mk
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
--- /dev/null
+hoc1 - 引き算のテスト
--- /dev/null
+4 / 2
+2 / 1
+2 / 2
+2 / 3
+10000 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10
+3.141592 / 2.718281828
+1000 / 0.0001
+1.23e2 / 321
+1.2345678901e100 / 1.2345678901e99
+/1
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
+(1 + 2) * (3 + 4)
+1 + 2 * 3 + 4
+(1 + 2) / (3 + 4)
+1 + 2 / 3 + 4
+ 21
+ 11
+ 0.42857143
+ 5.6666667
--- /dev/null
+include ../Define.mk
+include ../Test.mk
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
--- /dev/null
+hoc1 - 四則混合のテスト
--- /dev/null
+(1 + 2) * (3 + 4)
+1 + 2 * 3 + 4
+(1 + 2) / (3 + 4)
+1 + 2 / 3 + 4
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
+2 * 3
+3 * 2
+2 * 1
+2 * 0
+1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
+1.23456789 * 0.123456789
+1000000 * .1
+1.23e3 * 6.02e23
+*1
+2 * 5
+ 6
+ 6
+ 2
+ 0
+ 3628800
+ 0.15241579
+ 100000
+ 7.4046e+26
+../../hoc1: syntax error near line 9
--- /dev/null
+include ../Define.mk
+include ../Test.mk
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
--- /dev/null
+hoc1 - かけ算のテスト
--- /dev/null
+2 * 3
+3 * 2
+2 * 1
+2 * 0
+1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10
+1.23456789 * 0.123456789
+1000000 * .1
+1.23e3 * 6.02e23
+*1
+2 * 5
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
+2 - 1
+2 - 2
+2 - 3
+100 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10
+3.141592 - 2.718281828
+1000-0.0001
+1.23e2 - 321
+1.2345678901e100 - 1.2345678901e99
+-1
+ 1
+ 0
+ -1
+ 45
+ 0.42331017
+ 999.9999
+ -198
+ 1.1111111e+100
+ -1
--- /dev/null
+include ../Define.mk
+include ../Test.mk
--- /dev/null
+cat in.txt && ../../hoc1 < in.txt
--- /dev/null
+hoc1 - 引き算のテスト
--- /dev/null
+2 - 1
+2 - 2
+2 - 3
+100 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10
+3.141592 - 2.718281828
+1000-0.0001
+1.23e2 - 321
+1.2345678901e100 - 1.2345678901e99
+-1