diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 26cdb82d8f..76e66a2a09 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -210,3 +210,102 @@ jobs: After="${{github.event.after}}" fi bash _scripts/test.sh -a /tmp/antlr4-complete.jar -t ${{matrix.language}} -f diff $Before $After + + static-checks: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest] + language: [ CSharp ] + steps: + - name: Info + shell: bash + run: | + arch + uname -a + if [ -f /proc/cpuinfo ]; then cat /proc/cpuinfo; fi + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install Dotnet + uses: actions/setup-dotnet@v3.2.0 + with: + dotnet-version: '7.0.x' + - name: Test Dotnet + run: | + dotnet --version + dotnet --info + dotnet --list-runtimes + dotnet --list-sdks + - name: Install Java + uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'zulu' + - name: Test Java + run: | + dotnet --version + java --version + javac --version + - name: Install Dart + if: ${{ matrix.language == 'Dart' }} + uses: dart-lang/setup-dart@v1 + - name: Test Dart + if: ${{ matrix.language == 'Dart' }} + run: | + dart --version + - name: Install Go + if: ${{ matrix.language == 'Go' }} + uses: actions/setup-go@v4 + with: + go-version: '^1.18.0' + - name: Test Go + if: ${{ matrix.language == 'Go' }} + run: | + go version + - name: Install Python + uses: actions/setup-python@v4.6.1 + with: + python-version: '3.10' + - name: Test Python + run: | + python --version + - name: Upgrade Pip. + run: | + python -m ensurepip --upgrade + - name: Test Pip. + run: | + pip --version + - name: Install Antlr tool + run: | + pip install antlr4-tools + - name: Install JavaScript + if: ${{ matrix.language == 'JavaScript' }} + uses: actions/setup-node@v3.6.0 + with: + node-version: '16.13.0' + - name: Test JavaScript + if: ${{ matrix.language == 'JavaScript' }} + run: | + node --version + - name: Install Trash + shell: bash + run: | + dotnet tool restore + - name: Test Trash install + shell: bash + run: | + dotnet trgen -- --help + - name: Test + shell: bash + run: | + if [ "${{github.event_name}}" == "pull_request" ]; then + Before="${{github.event.pull_request.base.sha}}" + After="${{github.event.pull_request.head.sha}}" + else + Before="${{github.event.before}}" + After="${{github.event.after}}" + fi + bash _scripts/test-static-checks.sh -t ${{matrix.language}} -f diff $Before $After diff --git a/_scripts/test-static-checks.sh b/_scripts/test-static-checks.sh new file mode 100644 index 0000000000..6e2d1d7acb --- /dev/null +++ b/_scripts/test-static-checks.sh @@ -0,0 +1,358 @@ +#!/usr/bin/bash + +myrealpath () +{ + f=$@; + if [ -d "$f" ]; then + base=""; + dir="$f"; + else + base="/$(basename "$f")"; + dir=$(dirname "$f"); + fi; + dir=$(cd "$dir" && /bin/pwd); + echo "$dir$base" +} + +# true or false +quiet=true + +# Get full path of this script. +full_path_script=$(myrealpath $0) +full_path_templates=$(dirname $full_path_script)/templates + +# Sanity checks for required environment. +unameOut="$(uname -s)" +case "${unameOut}" in + Linux*) machine=Linux;; + Darwin*) machine=Mac;; + CYGWIN*) machine=Cygwin;; + MINGW*) machine=MinGw;; + *) machine="UNKNOWN:${unameOut}" +esac +if [[ "$machine" != "Linux" && "$machine" != "Mac" && "$machine" != "MinGw" ]] +then + echo "This script runs only in a Linux environment. Skipping." + exit 0 +fi + +thetime() +{ + local hh + local DIFF + DIFF=$1 + hh="$(($DIFF / 3600 ))" + mm="$((($DIFF % 3600) / 60))" + ss="$(($DIFF % 60))" + printf "%02d:%02d:%02d" $hh $mm $ss +} + +function getopts-extra () { + OPTARG=() + declare i=0 + # if the next argument is not an option, then append it to array OPTARG + while [[ ${OPTIND} -le $# && ${!OPTIND:0:1} != '-' ]]; do + OPTARG[i]=${!OPTIND} + let i++ OPTIND++ + done +} + +# filter="all" or "diff" or "agnostic" +filter="all" +# order="grammar" or "target" +order="grammar" +failed=() +succeeded=() +skipped="" +grammars=() +targets=() +tests=() + +# Get "root" of the repo clone. +cwd=`pwd` +prefix=`pwd` +pushd $prefix > /dev/null 2>&1 +while true +do + if [ -f `pwd`/_scripts/test.sh ] + then + break + elif [ `pwd` == "/" ] + then + break + fi + cd .. +done +if [ ! -f `pwd`/_scripts/test.sh ] +then + echo "Not in repo." + exit 1 +fi +prefix=`pwd` +popd > /dev/null 2>&1 + +rm -rf `find . -name 'Generated*' -type d` + +# Parse args, and update computation to perform. +order="grammars" +additional=() +antlr4jar=/tmp/antlr4-complete.jar +while getopts 'agthf' opt; do + case "$opt" in + a) + getopts-extra "$@" + antlr4jar="${OPTARG[0]}" + echo Antlr4jar is $antlr4jar + ;; + g) + getopts-extra "$@" + for a in "${OPTARG[@]}" + do + grammars+=( "$a" ) + done + ;; + t) + getopts-extra "$@" + for a in "${OPTARG[@]}" + do + targets+=( "$a" ) + done + ;; + o) + order="$OPTARG" + ;; + f) + getopts-extra "$@" + filter="${OPTARG[0]}" + for a in "${OPTARG[@]:1}" + do + additional+=( "$a" ) + done + ;; + ?|h) + cat - < /dev/null | sed 's#\(.*\)[/][^/]*$#\1#' | sort -u | grep -v _scripts` + for g in $directories + do + pushd $g > /dev/null + while true + do + if [ -f `pwd`/desc.xml ] + then + break + elif [ `pwd` == "$prefix" ] + then + break + fi + cd .. + done + g=`pwd` + g=${g##*$prefix} + g=${g##/} + if [ "$g" == "" ] + then + g="." + fi + popd > /dev/null + echo Adding diff $g + grammars+=( $g ) + done + grammars=( $(for g in "${grammars[@]}"; do echo "${g}"; done | sort -u) ) + fi + elif [ "${#additional[@]}" -eq 2 ] + then + grammars=() + # Test grammars for the enclosing directories. + directories=`git diff --name-only ${additional[0]} ${additional[1]} . 2> /dev/null | sed 's#\(.*\)[/][^/]*$#\1#' | sort -u | grep -v _scripts` + for g in $directories + do + pushd $g > /dev/null + while true + do + if [ -f `pwd`/desc.xml ] + then + break + elif [ `pwd` == "$prefix" ] + then + break + fi + cd .. + done + g=`pwd` + g=${g##*$prefix} + g=${g##/} + if [ "$g" == "" ] + then + g="." + fi + popd > /dev/null + echo Adding diff $g + grammars+=( $g ) + done + else + echo ouch + exit 1 + fi +elif [ "$filter" == "all" ] +then + grammars=() + # Test grammars for the enclosing directories. + directories=`find . -name desc.xml | sed 's#/desc.xml##' | sort -u` + for g in $directories + do + pushd $g > /dev/null 2>&1 + g=`pwd` + g=${g##*$prefix/} + popd > /dev/null 2>&1 + echo Adding $g + grammars+=( $g ) + done + grammars=( $(for g in "${grammars[@]}"; do echo "${g}"; done | sort -u) ) +elif [ "$filter" != "all" ] +then + echo Unknown filter $filter + exit 1 +fi + +echo "Number of grammars before sorting and making unique: ${#grammars[@]}" +grammars=($(echo "${grammars[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) +echo "Number of grammars after sorting and making unique: ${#grammars[@]}" + +if [ "${#grammars[@]}" -eq 0 ] +then + echo There are no grammars in current directory to test. + exit 0 +else + echo Grammars to do are: ${grammars[@]} +fi + +if [ "$targets" == "" ] +then + targets=( CSharp Cpp Dart Go Java JavaScript PHP Python3 TypeScript ) +fi + +echo grammars = ${grammars[@]} +echo targets = ${targets[@]} +echo order = $order +echo filter = $filter + +# Compute cross product +for g in ${grammars[@]} +do + for t in ${targets[@]} + do + tests+=( "$g,$t" ) + done +done + +# Sort the list of tuples if needed. +if [[ "$order" == "grammars" ]]; then sorted="1"; else sorted="2"; fi +#tests=`echo $tests | fmt -w 1 | sort -t ',' -k "$sorted"` + +echo Tests now ${tests[@]} + +# Perform tests in order. +for test in ${tests[@]} +do + all=( $(echo $test | tr "," "\n") ) + testname=${all[0]} + target=${all[1]} + pushd "$prefix/$testname" > /dev/null + + echo "" + echo "$testname,$target:" + + if [ ! -f desc.xml ] + then + echo No desc.xml for $testname + popd > /dev/null + continue + fi + desc_targets=`dotnet trxml2 -- desc.xml | grep '/desc/targets'` + if [ "${PIPESTATUS[0]}" -ne 0 ] + then + echo "The desc.xml for $testname is malformed. Skipping." + popd > /dev/null + continue + fi + desc_targets="${desc_targets##*=}" + desc_targets=`echo "$desc_targets" | tr ',' ' ' | tr ';' ' '` + + yes=false; + for t in $desc_targets + do + if [ "$t" == "+all" ]; then yes=true; fi + if [ "$t" == "-$target" ]; then yes=false; fi + if [ "$t" == "$target" ]; then yes=true; fi + done + + if [ "$yes" == "false" ] + then + echo "Intentionally skipping grammar $testname target $target." + popd > /dev/null + continue + fi + + if [ "$filter" == "agnostic" ] + then + # Test whether the grammars have actions. + count=`dotnet trparse -- -t antlr4 *.g4 2> /dev/null | dotnet trxgrep ' //(actionBlock | argActionBlock)' | dotnet trtext -c` + if [ "$count" == "0" ] + then + echo "no actions => skipping $testname." + popd > /dev/null + continue + fi + fi + + curl https://raw.githubusercontent.com/kaby76/g4-checks/d0e97c52787c9f47d6c3dd94f26159531fee7ee0/find-useless.sh 2> /dev/null | bash 1>&2 + + popd > /dev/null +done + +if [[ "$failed" == "" ]] +then + exit 0 +else + exit 1 +fi diff --git a/_scripts/test.sh b/_scripts/test.sh index 9f001998c3..23e1abdd0a 100644 --- a/_scripts/test.sh +++ b/_scripts/test.sh @@ -353,7 +353,7 @@ do for d in `echo Generated-$target-* Generated-$target` do - if [ ! -d $d ]; then continue; fi + if [ ! -d $d ]; then continue; fi if [ ! -f $d/build.sh ]; then echo " no build.sh"; continue; fi # Build driver code. @@ -400,6 +400,7 @@ do echo " Succeeded." succeeded+=( "$testname,$target" ) fi + popd > /dev/null done popd > /dev/null diff --git a/abb/abbParser.g4 b/abb/abbParser.g4 index fa7031f25e..730781d869 100644 --- a/abb/abbParser.g4 +++ b/abb/abbParser.g4 @@ -103,4 +103,4 @@ primitive | STRINGLITERAL | (PLUS | MINUS)? FLOATLITERAL | (PLUS | MINUS)? INTLITERAL - ; \ No newline at end of file + ; diff --git a/abb/examples/robdata.sys.errors b/abb/examples/robdata.sys.errors new file mode 100644 index 0000000000..e69de29bb2