o benchmark fuer code{a,b},gesamt (skript von viper angepasst) ("./script/bench.sh")
o modifiziertes lvatestskript (mit faerbungsskript von thp) ("./script/modlvatest_codea.sh")
o skript zum testen eines testfalles ("./script/onetest")
--- /dev/null
+scripts/traces/
Dies ist eine gemeinschaftliche Sammlung von Testfaellen fuer die Uebungsbeispiele
-der LVA "Uebersetzerbau (SS10)".
+der LVA "Uebersetzerbau (SS10)" an der TU Wien.
Kurzes HOWTO (fuer die g0):
$ git clone git://github.com/lewurm/testub10.git ~/test
$ /usr/ftp/pub/ubvl/test/scanner/test
$ /usr/ftp/pub/ubvl/test/parser/test
$ /usr/ftp/pub/ubvl/test/ag/test
+$ /usr/ftp/pub/ubvl/test/codea/test
+$ /usr/ftp/pub/ubvl/test/codeb/test
+$ /usr/ftp/pub/ubvl/test/gesamt/test
+Weiters wurde das bekannte Benchmarkskript von viper fuer codea, codeb und
+gesamt angepasst und eingebaut das sich in
+$ ~/test/scripts/test.sh
+befindet und mit {code{a,b},gesamt} als parameter aufgerufen wird.
-Namenskonventionen fuer das Skript:
+Namenskonventionen fuer das Skript (Zitat LVA Leitung):
Die Dateien mit der Eingabe heissen *.0, *.1, *.2 oder *.3, wobei die
Ziffer hinten den Exit-Code angibt. Eine Datei, die einen
Syntax-Fehler enthaelt, werden Sie also z.B. foo.2 nennen. Beim
auf .0 enden) auch noch eine Ausgabe, die ueberprueft werden muss; die
erwartete Ausgabe fuer die Datei bar.0 nennen Sie bar.out.
-Namenskonventionen fuer uns:
-Jeder Testfall hat als Praefix "<nick>_", sodass keine Namenskonflikte entstehen.
+Weitere Namenskonventionen fuer uns:
+o Jeder Testfall hat als Praefix "<nick>_", sodass keine Namenskonflikte entstehen.
+o Ab codea sollte auch fuer jeden erfolgreichen Testfall eine .instr Datei
+ angelegt werden die einen Referenzwert der Instruktionen enthaelt.
Wie kannst du beitragen?
+
mit git:
* forke das Repository auf github, committe deine Aenderungen und mach einen "Pull Request"
* clone das Repository, committe deine Aenderungen, erzeuge Patches mit "git format-patch" und maile sie oder poste sie im Informatikforum
und natuerlich ist jeder herzlichst dazu eingeladen im Forum ueber Testfaelle zu diskutieren :)
Infforum-Thread: http://tinyurl.com/testub10
-Mailadresse(n): lewurm_AT_gmail_DOT_com (weitere Freiwillig sind willkommen, einfach eintragen)
+Mailadresse(n): lewurm_AT_gmail_DOT_com (weitere Freiwillige sind willkommen, einfach eintragen)
+
+
+
+Allgemeine Tipps:
+
+praktische Ergaenzungen am Makefile fuer codea:
+
+> #bricht beim ersten fehlerhaften Testfall ab
+> #usage: make atest
+> atest:
+> ~/test/scripts/modlvatest_codea.sh 2>&1
+>
+> #offizielles Testskript der LVA
+> #usage: make lvatest
+> lvatest:
+> /usr/ftp/pub/ublu/test/codea/test 2>&1
+>
+> #Benchmarkskript. Testet nur *.0 Testfaelle
+> #usage: make bench
+> bench:
+> ~/test/scripts/bench.sh codea
+
+
+Ausserdem befindet sich ein Skript zum Testen *eines* Testfalles (auch nur fuer
+*.0 Testfaelle gedacht) hier:
+$ ~/test/scripts/onetest ~/test/codea/namen.0
--- /dev/null
+original README by viper:
+http://www.informatik-forum.at/showthread.php?73238-code-benchmarks
+=================================
+The Mysterious Mr. Ubvl presents:
+
+a test case instruction counter
+
+Run:
+
+./test.sh <assignment>
+
+e.g. ./test.sh codea
+
+and all available tests will be benchmarked. The individual traces per test
+case (containing only instructions near the generated code's labels) are
+written to traces/, traces/result.txt contains the aggregated results.
+
+Use something like
+
+ sort results.txt > r$USER.txt
+ diff r<u...>.txt r<u...>.txt
+
+to compare results with your colleagues.
--- /dev/null
+#!/bin/bash
+cd `dirname "$_"`
+CURDIR="$PWD"
+
+if [ "$1" == "" ]; then
+ echo "Verwendung: $0 <abgabe>"
+ echo "z.B. $0 codea"
+ exit 1
+fi
+
+TESTMAIN="$CURDIR/testmain.c"
+DUMPINSTR="$CURDIR/dumpinstr.sh"
+TRACEDIR="$CURDIR/traces"
+RESULT="$TRACEDIR/result.txt"
+CALLCONV="$CURDIR/callingconvention.o"
+
+ABG=~/abgabe/$1
+TEST=~/test/$1
+
+if [ ! -d $ABG ]; then
+ echo "Abgabeverzeichnis $ABG nicht gefunden!"
+fi
+
+if [ ! -d $TEST ]; then
+ echo "Testverzeichnis $TEST nicht gefunden!"
+fi
+
+cd $ABG
+make clean; make
+
+TMPNAME=tmp$$
+
+if [ ! -d $TRACEDIR ]; then
+ echo "creating $TRACEDIR"
+ mkdir $TRACEDIR
+fi
+
+rm -f $RESULT
+
+let gni=0
+let gti=0
+for i in $TEST/*.0; do
+ bi=`basename $i`
+ bi=${bi%.0}
+
+ # generate .s file and ignore output on stderr
+ ./$1 < $i > $TMPNAME.s 2> /dev/null
+ # create executable
+ gcc -DCALL=\"${i%.0}.call\" -o $TMPNAME $TMPNAME.s $TESTMAIN $CALLCONV
+
+ # count instructions
+ $DUMPINSTR $TMPNAME call >/dev/null
+ if [ $? != 0 ]; then
+ echo "$bi FEHLGESCHLAGEN"
+ continue
+ fi
+
+ # extract the exported symbols from the .s file
+ #LABEL=`grep '.globl' $TMPNAME.s | sed 's/^.*\\.globl *\\([a-zA-Z0-9_]\\+\\).*$/\1/g'`
+
+ # this won't work, we need all actual labels
+ LABEL=`grep '[a-zA-Z0-9_.$]\\+:' $TMPNAME.s | sed 's/^\\(.*[^a-zA-Z0-9_.$]\\)\\?\\([a-zA-Z0-9_.$]\\+\\):.*$/\2/g'`
+
+ MATCHES=0
+ for j in $LABEL; do
+ MATCHES="$MATCHES\\|$j"
+ done
+
+ # filter trace
+ grep "<\\($MATCHES\\)\\(+[0-9]*\\)\\?>:" $TMPNAME.trace > $TRACEDIR/$bi.trace
+
+ ni=`cat $TRACEDIR/$bi.trace | wc -l`
+ if [ -f $TEST/${bi}.instr ]; then
+ ti=`cat $TEST/$bi.instr`
+ else
+ echo "err: fuer den testfall \"$bi\" existiert noch keine referenzdatei"
+ ti=0
+ fi
+ echo "$bi: $ni (referenz: $ti)"
+ echo "$bi $ni" >> $RESULT
+
+ let gni=gni+$ni
+ let gti=gti+$ti
+
+ # remove waste
+ rm -f $TMPNAME $TMPNAME.s $TMPNAME.trace
+done
+
+echo ""
+echo "Statistik:"
+echo "=========="
+echo " $gni Instruktionen"
+echo " $gni Referenzinstruktionen"
--- /dev/null
+#!/usr/bin/python
+# http://www.informatik-forum.at/showthread.php?73283-SCRIPT-Einf%E4rben-von-Assembler-Code
+# Einfaerben von amd64 Assembler-Code
+# thp/a\thpinfo.com; 2009-05-22
+
+import sys
+import re
+
+# Farbcodes siehe http://www.pixelbeat.org/docs/terminal_colours/
+colorify = (
+ # Return-Register: violett
+ (r'()(%rax)()', '35'),
+ # Argument-Register: gruen
+ (r'()(%rdi|%rsi|%rdx|%rcx|%r8|%r9)()', '32'),
+ # Temporary Register: gelb
+ (r'()(%r10|%r11|%xmm\d{1,2})()', '33'),
+ # Callee-saved Register: rot
+ (r'()(%rbx|%r15|%r14|%r13|%r12)()', '31'),
+ # Stack- u. Frame-Pointer: grau
+ (r'()(%rsp|%rbp)()', '1;30'),
+ # Zahlenwerte: tuerkis
+ (r'()(\$[-]?\d+)()', '36'),
+ # Disposition von M/R-Berechnungen: tuerkis
+ (r'()([-]?\d+)(\([^)]*\))', '36'),
+ # Scale von M/R-Berechnungen: tuerkis
+ (r'(,[ ]?)(1|2|4|8)(\))', '36'),
+)
+
+for line in sys.stdin:
+ for match, color in colorify:
+ line = re.sub(match, '\\1\033['+color+'m\\2\033[0m\\3', line)
+ sys.stdout.write(line)
--- /dev/null
+#!/bin/sh
+
+if [ $# -lt 2 ]; then
+ echo "usage: $0 <executable> <method> <args>"
+ echo "will produce <executable>.trace"
+fi
+
+EXECFILE=$1
+EXECMETHOD=$2
+
+shift 2
+
+cat <<END > $EXECFILE.tmp
+
+set step-mode on
+
+file $EXECFILE
+break $EXECMETHOD
+
+run $*
+
+while 1==1
+
+if \$pc != \$pc
+printf "==== ?\\n"
+end
+
+printf "\\n====BEGIN $EXECMETHOD\\n"
+
+printf "==== "
+x/i \$pc
+
+up
+set \$nfp = \$fp
+down
+
+while \$fp != \$nfp
+stepi
+printf "==== "
+x/i \$pc
+end
+
+printf "\\n====END $EXECMETHOD\\n"
+
+continue
+
+end
+
+quit
+
+END
+
+gdb < $EXECFILE.tmp > $EXECFILE.trace 2>/dev/null
+
+mv $EXECFILE.trace $EXECFILE.output
+
+awk -- '\
+/^====BEGIN/ {ll = ("begin " $2);} \
+/^==== / {print ll; ll = (" " substr($0, 5));} \
+/^====END/ {print "end", $2;}
+' $EXECFILE.output > $EXECFILE.trace
+
+echo instructions: `grep "^ " $EXECFILE.trace | wc -l`
+echo trace output: $EXECFILE.trace
+
+rm $EXECFILE.tmp $EXECFILE.output
--- /dev/null
+#! /bin/bash
+
+beispiel=codea
+PROGRAM=./$beispiel
+
+errnum=0
+prgnum=0
+
+#LOC=.
+LOC=/usr/ftp/pub/ubvl/test/$beispiel
+LOC2=~/test/$beispiel
+
+/usr/ftp/pub/ublu/test/accounttest || exit 1
+allow_null_glob_expansion=1
+
+if [ ! -d ~/abgabe/$beispiel ]; then
+ echo "Fehler: Verzeichnis ~/abgabe/$beispiel existiert nicht."
+ exit 1
+else
+ cd ~/abgabe/$beispiel
+ echo 'Teste "make clean"'
+ make clean
+ /usr/ftp/pub/ubvl/test/cleantest
+ echo 'Teste "make"'
+ make
+fi
+
+if test ! -x $PROGRAM
+then
+ echo "Fehler: Kein Programm $PROGRAM"
+ exit 1
+fi
+let prgnum=0
+for i in $LOC/*.0 $LOC2/*.0
+do
+ if [ -f $i ]; then
+ let prgnum=prgnum+1
+ let errorfound=0
+ echo "==========> Eingabe von $i:"
+ cat $i
+ echo
+ RESFILE=test${beispiel}out$$
+ $PROGRAM <$i >$RESFILE
+ retval=$?
+ echo -n "Übersetzung: "
+ if test $retval -eq 0
+ then
+ echo "Status korrekt"
+ else
+ echo "[Errot] Status=$retval. Erwartet: 0"
+ let errorfound=1
+ fi
+ echo
+ echo "Ausgabe:"
+ if [ -f ~/test/scripts/clr.py ]; then
+ cat $RESFILE | ~/test/scripts/clr.py
+ else
+ cat $RESFILE
+ fi
+ mv -f $RESFILE $RESFILE.s
+ CALLFILE=${i%.*}.call
+ echo
+ if [ ! -f $CALLFILE ]; then
+ echo "Fehler: Datei $CALLFILE existiert nicht, kann Code nicht ausführen..."
+ exit 1
+ else
+ echo "Übersetze und linke das Testprogramm:"
+ if cc -g -I. -DCALL=\"$CALLFILE\" $LOC/testmain.c $LOC/callingconvention.o $RESFILE.s; then
+ echo
+ echo "Rufe folgendes Codefragment auf:"
+ cat $CALLFILE
+ echo
+ ./a.out
+ retval=$?
+ # test callee saved registers
+ if [ "$retval" -ge 12 ] && [ "$retval" -le 15 ]; then
+ echo "[Error] Callee-saved register %r$retval modified."
+ let errorfound=1
+ elif [ "$retval" -eq 11 ]; then
+ echo "[Error] Callee-saved register %rbx modified."
+ let errorfound=1
+ elif [ "$retval" -eq 16 ]; then
+ echo "[Error] Callee-saved register %rbp modified."
+ let errorfound=1
+ elif [ "$retval" -eq 30 ]; then
+ echo "[Error] Stack pointer %rsp modified."
+ let errorfound=1
+ else
+ # test signals
+ test $retval -gt 127
+ retsig=$?
+ test ${i##*.} = xin
+ expsig=$?
+ if test $retsig -eq $expsig; then
+ if test $retval -eq 1; then
+ echo "[Error] Das Ergebnis des Aufrufs ist falsch."
+ let errorfound=1
+ elif test $retval -eq 0; then
+ echo "Das Ergebnis des Ausdrucks ist korrekt."
+ else
+ echo "[Error] Erzeugter Code verhaelt sich bzgl. Signalerzeugung anders als erwartet."
+ let errorfound=1
+ fi
+ else
+ echo "[Error] Erzeugter Code verhaelt sich bezueglich Signalerzeugung anders als erwartet."
+ let errorfound=1
+ echo "Rueckgabewert = $retval";
+ fi
+ fi
+ echo
+ else
+ echo "[Error] Erzeugter Code konnte nicht assembliert und gelinkt werden."
+ let errorfound=1
+ fi
+ fi
+ let errnum=errnum+errorfound
+ if [ 1 -eq $errorfound ]; then
+ rm *.s
+ rm *.out
+ exit 3;
+ fi
+ rm -f a.out $RESFILE $RESFILE.s
+ fi
+done
+
+for i in $LOC/*.[123] $LOC2/*.[123]
+do
+ if [ -f $i ]; then
+ let prgnum=prgnum+1
+ echo "==========> Eingabe von $i:"
+ cat $i
+ echo
+ echo "Ausgabe:"
+ $PROGRAM <$i
+ retval=$?
+ if test $retval -eq ${i#*.}
+ then
+ echo "Status: korrekt"
+ else
+ echo "[Error] Status: $retval. Erwartet: ${i#*.}"
+ let errnum=errnum+1
+ fi
+ echo
+fi
+done
+let corrnum=prgnum-errnum
+echo "Statistics: "
+echo "==========="
+echo " $prgnum Tests total"
+echo " $corrnum Tests passed"
+echo " $errnum Tests failed"
--- /dev/null
+#!/bin/bash
+
+i=$1
+beispiel=codea
+PROGRAM=./$beispiel
+
+#LOC=.
+LOC=/usr/ftp/pub/ubvl/test/$beispiel
+
+allow_null_glob_expansion=1
+
+if [ ! -d ~/abgabe/$beispiel ]; then
+ echo "Fehler: Verzeichnis ~/abgabe/$beispiel existiert nicht."
+ exit 1
+else
+ cd ~/abgabe/$beispiel
+ echo 'Teste "make"'
+ make
+fi
+
+if test ! -x $PROGRAM
+then
+ echo "Fehler: Kein Programm $PROGRAM"
+ exit 1
+fi
+let prgnum=0
+#for i in $LOC/*.0 $LOC2/*.0
+if [ -f $i ]; then
+ let prgnum=prgnum+1
+ let errorfound=0
+ echo "==========> Eingabe von $i:"
+ cat $i
+ echo
+ RESFILE=test${beispiel}out$$
+ $PROGRAM <$i >$RESFILE
+ retval=$?
+ echo -n "Übersetzung: "
+ if test $retval -eq 0
+ then
+ echo "Status korrekt"
+ else
+ echo "[Errot] Status=$retval. Erwartet: 0"
+ let errorfound=1
+ fi
+ echo
+ echo "Ausgabe:"
+ if [ -f ~/test/scripts/clr.py ]; then
+ cat $RESFILE | ~/test/scripts/clr.py
+ else
+ cat $RESFILE
+ fi
+ mv -f $RESFILE $RESFILE.s
+ CALLFILE=${i%.*}.call
+ echo
+ if [ ! -f $CALLFILE ]; then
+ echo "Fehler: Datei $CALLFILE existiert nicht, kann Code nicht ausführen..."
+ exit 1
+ else
+ echo "Übersetze und linke das Testprogramm:"
+ if cc -g -I. -DCALL=\"$CALLFILE\" $LOC/testmain.c $LOC/callingconvention.o $RESFILE.s; then
+ echo
+ echo "Rufe folgendes Codefragment auf:"
+ cat $CALLFILE
+ echo
+ ./a.out
+ retval=$?
+ # test callee saved registers
+ if [ "$retval" -ge 12 ] && [ "$retval" -le 15 ]; then
+ echo "[Error] Callee-saved register %r$retval modified."
+ let errorfound=1
+ elif [ "$retval" -eq 11 ]; then
+ echo "[Error] Callee-saved register %rbx modified."
+ let errorfound=1
+ elif [ "$retval" -eq 16 ]; then
+ echo "[Error] Callee-saved register %rbp modified."
+ let errorfound=1
+ elif [ "$retval" -eq 30 ]; then
+ echo "[Error] Stack pointer %rsp modified."
+ let errorfound=1
+ else
+ # test signals
+ test $retval -gt 127
+ retsig=$?
+ test ${i##*.} = xin
+ expsig=$?
+ if test $retsig -eq $expsig; then
+ if test $retval -eq 1; then
+ echo "[Error] Das Ergebnis des Aufrufs ist falsch."
+ let errorfound=1
+ elif test $retval -eq 0; then
+ echo "Das Ergebnis des Ausdrucks ist korrekt."
+ else
+ echo "[Error] Erzeugter Code verhaelt sich bzgl. Signalerzeugung anders als erwartet."
+ let errorfound=1
+ fi
+ else
+ echo "[Error] Erzeugter Code verhaelt sich bezueglich Signalerzeugung anders als erwartet."
+ let errorfound=1
+ echo "Rueckgabewert = $retval";
+ fi
+ fi
+ echo
+ else
+ echo "[Error] Erzeugter Code konnte nicht assembliert und gelinkt werden."
+ let errorfound=1
+ fi
+ fi
+ let errnum=errnum+errorfound
+ if [ 1 -eq $errorfound ]; then
+ rm *.s
+ rm *.out
+ exit 3;
+ fi
+ rm -f a.out $RESFILE $RESFILE.s
+fi
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+extern long callchecking();
+
+#define RET return
+
+int call(void)
+{
+#include CALL
+}
+
+long labs(long);
+
+#ifdef DEFINE_G
+long g(long x, long y)
+{
+ return h(x*2, y*3)+1;
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+ long r;
+ r=callchecking();
+ if(r==0 || r==1)
+ return !r;
+ return r;
+}
+