diff --git a/2ano2/Compiladores/.gitignore b/2ano2/Compiladores/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/2ano2/Compiladores/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/2ano2/Compiladores/Compiladores.iml b/2ano2/Compiladores/Compiladores.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/2ano2/Compiladores/Compiladores.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/2ano2/Compiladores/antlr4-bin/antlr4 b/2ano2/Compiladores/antlr4-bin/antlr4 new file mode 100755 index 0000000..03a910d --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4 @@ -0,0 +1,60 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2017-2021 + +scriptName="$0" +target="java" +options="" + +function help() +{ + echo "Usage: $scriptName [-h | -help | -cpp | -python | -java] ..." + echo "" + echo " Compiles an antlr4 grammar to a target language." + echo "" + echo " Target language:" + echo " -java: java (default)" + echo " -cpp: c++" + echo " -python: python3" + #exit 1 +} + +case $1 in + -h | -help) + help + echo "" + shift + ;; + -cpp | -c++) + target="cpp" + options="-Dlanguage=Cpp" + shift + ;; + -python | -python3) + target="python3" + options="-Dlanguage=Python3" + shift + ;; + -java) + shift + ;; +esac + +if [ $# -eq 0 ]; then + options="" +fi + +if [ -z "$ANTLR4_PATH" ]; then + java -ea org.antlr.v4.Tool $options $* +else + TMP_VERSION=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | tail -1 | sed 's/.*\///g' | sed 's/-com.*//g') + ANTLR4File=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + TMP_VERSION=$(ls -f $ANTLR4_PATH/ST-*.jar | tail -1 | sed 's/.*\///g' | sed 's/\.jar//g') + STFile=$(ls -f $ANTLR4_PATH/ST-*.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + + #echo "java -ea -cp .:$ANTLR4File:$STFile org.antlr.v4.Tool $options $*" + java -ea -cp .:"$ANTLR4File":"$STFile" org.antlr.v4.Tool $options $* +fi + +exit $? + diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-build b/2ano2/Compiladores/antlr4-bin/antlr4-build new file mode 100755 index 0000000..26b21fe --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-build @@ -0,0 +1,97 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2017-2024 + +IFS=$'\n' + +scriptName="$0" +target="java" + +function help() +{ + echo "Usage: $scriptName [-h | -help | -cpp | -python | -java] [grammar]" + echo "" + echo " Finds all existing *.g4 grammars in current directory or in subdirectories and," + echo " if no grammar argument exists, and if successful and if applicable, compiles the" + echo " generated target language code." + echo "" + echo " target language:" + echo " -java: java (default)" + echo " -cpp: c++" + echo " -python: python3" + echo "" + echo " grammar argument is the name of the grammar (if present, extension .g4 is ignored)." + + exit 1 +} + +function process() +{ + g="$1" + echo "Processing $g" + if [ -e ${g}.g4 ]; then + grammar=${g}.g4 + elif [ -e ${g}Parser.g4 ]; then + grammar=${g}Parser.g4 + else + echo "ERROR: internal error!" + exit -1 + fi + case $target in + java) + (cd `dirname $g`; if ( grep Visitor *java &> /dev/null ); then opt="-visitor"; else opt=""; fi; antlr4 $opt `basename $g`*.g4) && javac ./`dirname $g`/*.java + ;; + cpp) + (cd `dirname $g`; make) + ;; + python) + parserFile=${g}Parser.py + if [[ ! -e ${parserFile} || ${grammar} -nt ${parserFile} ]]; then + (cd `dirname $g`; if ( grep Visitor *py &> /dev/null ); then opt="-visitor"; else opt=""; fi; antlr4 -python $opt `basename $g`*.g4) + fi + ;; + esac +} + +case $1 in + "") + ;; + -h | -help) + help + ;; + -java) + shift + ;; + -cpp | -c++) + shift + target="cpp" + ;; + -python | -python3) + shift + target="python" + ;; + -*) + echo "ERROR: invalid argument!" + echo "" + help + exit 1 + ;; +esac + +if ! [ -z $1 ]; then + target_grammar=${1/.g4/} + if ! [ -f ${target_grammar}.g4 ]; then + if ! [ -f ${target_grammar}Parser.g4 ]; then + echo "ERROR: grammar file \"${target_grammar}.g4\" does not exist!" + exit 2 + fi + fi + process $target_grammar + exit 0 +fi + +for g in `find . -name \*.g4 | sed 's/Parser.g4$\|Lexer.g4$\|.g4$//1' | uniq | sort`; do + process $g +done + +exit 0 diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-clean b/2ano2/Compiladores/antlr4-bin/antlr4-clean new file mode 100755 index 0000000..c3792d3 --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-clean @@ -0,0 +1,112 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2017-2024 + +IFS=$'\n' + +scriptName="$0" +target="java" +sourceExt="java" +sourceExt2="" +objExt="class" + +function help() +{ + echo "Usage: $scriptName [-h | -help | -cpp | -python | -java] [grammar]" + echo "" + echo " Cleans automatically generated antlr4 files considering target language." + echo "" + echo " target language:" + echo " -java: java (default)" + echo " -cpp: c++" + echo " -python: python3" + echo "" + echo " grammar argument is the name of the grammar (if present, extension .g4 is ignored)." + exit 1 +} + +function process() +{ + if [ -e ${1} ]; then + g="$1" + elif [ -e ${1}.g4 ]; then + g=${1}.g4 + elif [ -e ${1}Parser.g4 ]; then + g=${1}.g4 + else + echo "ERROR: internal error!" + exit -1 + fi + echo "Processing $g" + if [[ -e $g && -f $g ]]; then + echo "Removing $g files:" + name=${g%.g4} + rm -fv $name.tokens $name.interp ${name}Lexer.interp ${name}BaseListener.$sourceExt ${name}Listener.$sourceExt ${name}BaseVisitor.$sourceExt ${name}Visitor.$sourceExt ${name}Lexer.tokens ${name}Lexer.$sourceExt ${name}Parser.$sourceExt + if [ ! -z "$objExt" ]; then + rm -fv ${name}BaseListener.$sourceExt2 ${name}Listener.$sourceExt2 ${name}BaseVisitor.$sourceExt2 ${name}Visitor.$sourceExt2 ${name}Lexer.$sourceExt2 ${name}Parser.$sourceExt2 + fi + if [[ "$name" = *Parser || "$name" = *Lexer ]]; then + rm -fv $name.$sourceExt + fi + if [[ "$target" = "cpp" && -e ${name}Main ]]; then + rm -fv ${name}Main + fi + if [[ "$target" = "python" ]]; then + cacheDir=`dirname $g`/__pycache__ + [[ -e $cacheDir ]] && rm -rfv `dirname $g`/__pycache__ + fi + fi +} + +case $1 in + "") + ;; + -h | -help) + help + ;; + -cpp | -c++) + target="cpp" + sourceExt="cpp" + sourceExt2="h" + objExt="o" + shift + ;; + -python | -python3) + target="python" + sourceExt="py" + objExt="" + shift + ;; + -java) + shift + ;; + -*) + echo "ERROR: invalid argument!" + echo "" + help + ;; +esac + +if [ ! -z "$objExt" ]; then + # clean objExt files: + echo "Removing *.$objExt files:" + find . -name \*.$objExt -printf "removing %p\n" -exec rm -f {} \; +fi + +if ! [ -z $1 ]; then + target_grammar=${1/.g4/} + if ! [ -f ${target_grammar}.g4 ]; then + if ! [ -f ${target_grammar}Parser.g4 ]; then + echo "ERROR: grammar file \"${target_grammar}.g4\" does not exist!" + exit 2 + fi + fi + process $target_grammar + exit 0 +fi + +# clean antlr4 generated .java files: +for g in `find . -name \*.g4`; do + process $g +done + diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-jar-run b/2ano2/Compiladores/antlr4-bin/antlr4-jar-run new file mode 100755 index 0000000..9025d8d --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-jar-run @@ -0,0 +1,35 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2020 + +if (( $# == 0 )); then + echo "USAGE: antlr4-jar-run " + exit 1 +fi + +jarFile=$1 +shift +if ! [ -e ${jarFile} ]; then + echo "ERROR: jar file ${jarFile} not found!" + exit 2 +fi +mainClass=$(unzip -q -c $jarFile META-INF/MANIFEST.MF | grep Main-Class | cut -d":" -f2 | sed 's/[ \n\r]//g') + +if [ -z ${mainClass} ]; then + echo "ERROR: jar file ${jarFile} without main class!" + exit 3 +fi + +if [ -z "$ANTLR4_PATH" ]; then + cp="-cp ${jarFile}" +else + TMP_VERSION=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | tail -1 | sed 's/.*\///g' | sed 's/-com.*//g') + ANTLR4File=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + TMP_VERSION=$(ls -f $ANTLR4_PATH/ST-*.jar | tail -1 | sed 's/.*\///g' | sed 's/\.jar//g') + STFile=$(ls -f $ANTLR4_PATH/ST-*.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + cp="-cp ${jarFile}:$ANTLR4File:$STFile" +fi + +java -ea $cp $mainClass $* + +exit $? diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-java b/2ano2/Compiladores/antlr4-bin/antlr4-java new file mode 100755 index 0000000..3107a36 --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-java @@ -0,0 +1,17 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2020 + +if [ -z "$ANTLR4_PATH" ]; then + cp="" +else + TMP_VERSION=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | tail -1 | sed 's/.*\///g' | sed 's/-com.*//g') + ANTLR4File=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + TMP_VERSION=$(ls -f $ANTLR4_PATH/ST-*.jar | tail -1 | sed 's/.*\///g' | sed 's/\.jar//g') + STFile=$(ls -f $ANTLR4_PATH/ST-*.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + cp="-cp .:$ANTLR4File:$STFile" +fi + +java -ea $cp $* + +exit $? diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-javac b/2ano2/Compiladores/antlr4-bin/antlr4-javac new file mode 100755 index 0000000..c146d20 --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-javac @@ -0,0 +1,17 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2020 + +if [ -z "$ANTLR4_PATH" ]; then + cp="" +else + TMP_VERSION=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | tail -1 | sed 's/.*\///g' | sed 's/-com.*//g') + ANTLR4File=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + TMP_VERSION=$(ls -f $ANTLR4_PATH/ST-*.jar | tail -1 | sed 's/.*\///g' | sed 's/\.jar//g') + STFile=$(ls -f $ANTLR4_PATH/ST-*.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + cp="-cp .:$ANTLR4File:$STFile" +fi + +javac $cp $* + +exit $? diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-listener b/2ano2/Compiladores/antlr4-bin/antlr4-listener new file mode 100755 index 0000000..098de9a --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-listener @@ -0,0 +1,250 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2017-2021 + +scriptName=antlr4-listener +target=java +sourceExt="java" + +function help() +{ + echo -e "Usage: $scriptName [-h | -help] [-cpp [inline] | -python | -java] [-f | -force]\n [] " + echo "" + echo " Creates a listener class named in the target language for ." + echo " Argument may be omitted iff there is only one grammar in the directory" + echo " (and eventual subdirectories)." + echo "" + echo " Target language:" + echo " -java: java (default)" + echo " -cpp: c++" + echo " -cpp inline: c++ with inline implementation (implementation in *.h class definition)" + echo " -python: python3" + echo "" + echo " options:" + echo " -h" + echo " -help" + echo " help page" + echo " -f" + echo " -force" + echo " force creation of listener file" + echo " -i " + echo " -indent " + echo " number of indentation spaces (default: 3)" + echo " -l" + echo " -log" + echo " add method log stdout print" + exit 1 +} + +function logJava() +{ + local indent=$1 + if [[ $logActive == "true" ]]; then + cat - | sed "s/\(void \)\(enter[a-zA-Z0-9_]\+\|exit[a-zA-Z0-9_]\+\)\((.*$\)/\1\2\3\n${indent}${indent}System.out.println(\"[\2]\");/g" + else + cat - + fi +} + +function logCpp() +{ + local indent=$1 + if [[ $logActive == "true" ]]; then + cat - | sed "s/\(enter[a-zA-Z0-9_]\+\|exit[a-zA-Z0-9_]\+\)\((.*$\)/\1\2\n${indent}printf(\"[%s]\\\n\", \"\1\");/g" + else + cat - + fi +} + +function logPython() +{ + local indent=$1 + if [[ $logActive == "true" ]]; then + cat - | sed "s/\(enter[a-zA-Z0-9_]\+\|exit[a-zA-Z0-9_]\+\)\((.*:$\)/\1\2\n${indent}${indent}print(\"[\1]\")/g" + else + cat - + fi +} + +indentSpaces="3" +forceCreation="false" +logActive="false" + +# process options: +while [[ $1 == -* ]]; do + case $1 in + -h | -help) + help + ;; + -cpp | -c++) + target="cpp" + sourceExt="cpp" + if [[ $# > 1 && $2 == "inline" ]]; then + shift + inline="true" + else + inline="false" + fi + ;; + -python | -python3) + target="python" + sourceExt="py" + ;; + -java) + target="java" + sourceExt="java" + ;; + -f | -force) + forceCreation="true" + ;; + -i | -indent) + shift + if (( $# == 0 )); then + echo -e "ERROR: missing indentation value!" + exit 1 + fi + indentSpaces="$1" + if ! [[ "$indentSpaces" =~ ^[0-9]+$ ]]; then + echo "ERROR: invalid indentation number" + exit 1 + fi + ;; + -l | -log) + logActive="true" + ;; + -*) + echo "ERROR: invalid argument!" + exit 1 + ;; + esac + shift +done + +if [ $# -eq 0 ]; then + echo "ERROR: Missing argument!" + echo "" + help +fi + +indentval=${indentSpaces}; indent=$(printf "%${indentval}s") + +if (! command -v cpp >/dev/null 2>&1); then + echo "ERROR: cpp command missing (install gcc)" + exit 1 +fi + +grammar="" +grammarFile="" +if [ $# -eq 2 ]; then + gr=${1%.g4} + grammar=${gr%Parser} + if [[ ! -e "${grammar}.g4" && ! -e "${grammar}Parser.g4" ]]; then + echo "ERROR: Grammar file not found!" + exit 1 + fi + shift +else + count=`find . -name \*.g4 | sed 's/Parser.g4$\|Lexer.g4$\|.g4$//1' | uniq | wc -l` + if ((count == 0)); then + echo "ERROR: Grammar file not found!" + exit 1 + elif ((count > 1)); then + echo "ERROR: Too many grammar files!" + find . -name \*.g4 -printf " %p\n" + exit 1 + fi + g4=`find . -name \*.g4 | sed 's/Parser.g4$\|Lexer.g4$\|.g4$//1' | uniq` + p=`dirname $g4 | sed 's/^\.\///1'` + if [[ "$p" == "." ]]; then + p="" + else + p=$p. + fi + + if [ ! -e $g4.g4 ]; then + g4=${g4}Parser + fi + + grammar=`cat "$g4"*.g4 | cpp 2>/dev/null | grep -wv ^# | sed 's/{/ { /g' | sed 's/}/ } /g' | tr '\n' ' ' | tr ' ' '\n' | grep -wv parser | grep -wv options | grep -v ^\;$ | grep -v ^$ | gawk 'BEGIN {incode=0;} /{/ {incode++;} /}/ {incode--;} {if (incode == 0) print $0;}' | grep -v \} | grep -v @.* | head -2 | tail -1 | sed 's/[:;].*$//g' | grep -v ^$ | sed 's/Parser$//'` + + if [ -z "$grammar" ]; then + echo "ERROR: grammar name missing!" + exit 1 + fi +fi + +grammarFile="${grammar}.g4" +if [[ ! -e "$grammarFile" ]]; then + grammarFile="${grammar}Parser.g4" + if [[ ! -e "$grammarFile" ]]; then + echo "ERROR: Grammar file not found!" + exit 1 + fi +fi + +if [ ! $# -eq 1 ]; then + echo "ERROR: Missing argument!" + echo "" + help +fi + +listener=$(echo $1 | sed "s/\.${sourceExt}$//1" | sed 's/\.*//g') +if [[ $forceCreation == "false" ]]; then + if [ -e ${listener}.$sourceExt ]; then + echo "ERROR: Listener file \"${listener}.$sourceExt\" already exists!" + exit 2 + fi +fi + +if [[ ${listener} == ${grammar}Listener || ${listener} == ${grammar}BaseListener || + ${listener} == ${grammar}Visitor || ${listener} == ${grammar}BaseVisitor || + ${listener} == ${grammar}Parser || ${listener} == ${grammar}Lexer ]]; then + echo "ERROR: Invalid listener name (\"${listener}\")!" + exit 1 +fi + +echo "Grammar: $grammar" +echo "Listener: $listener" +echo "Target language: $target" + +if [[ -e "${grammar}Lexer.g4" ]]; then + antlr4 -$target "${grammar}Lexer.g4" +fi +antlr4 -$target "$grammarFile" +if [[ -e "${grammar}Parser.g4" ]]; then + grammar=${grammar}Parser +fi + +case $target in + java) + cpp "${grammar}BaseListener.java" | grep -v "^#.*$" | grep -v "^[ \t]*$" | sed 's/^\/\npublic/g' | sed "s/${grammar}BaseListener.*/${listener} extends ${grammar}BaseListener {/1" | sed "s/^ /\n${indent}/g" | sed "s/{ }/{\n${indent}}/g" | sed "s/; }/;\n${indent}}/g" | logJava "${indent}" > "${listener}.java" + ;; + cpp) + if [[ $inline == "false" ]]; then + echo -e "#pragma once\n" > "${listener}.h" + echo -e "#include \"${grammar}BaseListener.h\"\n" >> "${listener}.h" + cat "${grammar}BaseListener.h" | grep -v "^#.*$" | cpp | grep -v "^#.*$" | grep -v "^[ \t]*$" | grep -v "visit" | sed "s/${grammar}BaseListener.*/${listener} : public ${grammar}BaseListener {/1" | sed "s/^ /${indent}/g" | sed "s/^\(${indent}virtual\)/\n\1/g" | sed 's/* /*ctx/g' | sed 's/\(override\).*/\1;/g' >> "${listener}.h" + echo "#include \"${listener}.h\"" > "${listener}.cpp" + cat "${grammar}BaseListener.h" | grep -v "^#.*$" | cpp | grep -v "^#.*$" | grep -v "^[ \t]*$" | grep -v "visit" | grep -v "};" | grep -wv "class\|public" | sed "s/^ //g" | sed "s/^virtual /\n/g" | sed 's/* /*ctx/g' | sed 's/override //g' | sed "s/\(enter\|exit\)/${listener}::\1/g" | sed "s/{ }/{\n}/g" | logCpp "${indent}" >> "${listener}.cpp" + else + echo -e "#pragma once\n" > "${listener}.h" + echo -e "#include \"${grammar}BaseListener.h\"\n" >> "${listener}.h" + cat "${grammar}BaseListener.h" | grep -v "^#.*$" | cpp | grep -v "^#.*$" | grep -v "^[ \t]*$" | grep -v "visit" | sed "s/${grammar}BaseListener.*/${listener} : public ${grammar}BaseListener {/1" | sed "s/^ /${indent}/g" | sed "s/^\(${indent}virtual\)/\n\1/g" | sed 's/* /*ctx/g' | sed "s/{ }/{\n${indent}}/g" | logCpp "${indent}${indent}" >> "${listener}.h" + echo "#include \"${listener}.h\"" > "${listener}.cpp" + fi + ;; + python) + echo -e "from antlr4 import *" > "${listener}.py" + echo -e "from ${grammar}Parser import ${grammar}Parser" >> "${listener}.py" + echo -e "from ${grammar}Listener import ${grammar}Listener" >> "${listener}.py" + echo -e "" >> "${listener}.py" + echo -e "class $listener(${grammar}Listener):" >> "${listener}.py" + cat "${grammar}Listener.py" | grep "enter\|exit" | sed -e 's/^[ \t]*//g' | sed -e "s/^\(.*\)$/${indent}\1\n${indent}${indent}pass\n/g" | logPython "${indent}" >> "${listener}.py" + ;; + *) + echo "ERROR: $target listeners not yet implemented!" + ;; +esac +antlr4-clean -$target >& /dev/null + +exit 0 diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-main b/2ano2/Compiladores/antlr4-bin/antlr4-main new file mode 100755 index 0000000..03a22b7 --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-main @@ -0,0 +1,690 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2017-2021 + +scriptName="antlr4-main" +target="java" +sourceExt="java" + +function help() +{ + echo "Usage: $scriptName [options] [ ]" + echo "" + echo " Creates a main class in the target language to parse starting at rule ." + echo " Arguments may be omitted iff there is only one grammar in the directory" + echo " (and eventual subdirectories), and the first symbol in the grammar is the symbol." + echo "" + echo " Target language:" + echo "" + echo " options:" + echo " -h" + echo " -help" + echo " help page" + echo " -java: java as target language (default)" + echo " -cpp: c++ as target language" + echo " -python: python3 as target language" + echo " -l " + echo " -listener " + echo " main created with support for traversing the given listener class" + echo " multiple listeners are allowed (the order will be respected)" + echo " -v " + echo " -visitor " + echo " main created with support for visiting the given visitor class" + echo " multiple visitors are allowed (the order will be respected)" + echo " -i" + echo " -line-interactive" + echo " main created for a line interactive interpreter" + echo " -is " + echo " -separator-interactive " + echo " main created for a text separated interactive parser" + echo " -indent " + echo " number of indentation spaces (default: 3)" + echo " -f" + echo " -force" + echo " force creation of main file even if grammar, rule, listeners, and visitor don't exist," + echo " or if main file already exists" + echo "" + exit 1; +} + +#if (( $# == 0 )); then +#fi + +grammar="" +grammarfile="" +rule="" +fileName="" +listeners=() +visitors=() +treewalking=() # listeners and visitor in proper order +treewalkingtype=() # v: visitor, l: listener +delimiter="" +interactiveVar="" +interactiveDelimiter="" +interactiveNext="" +nextExtraText="" +interactive="false" +lineInteractive="false" +separatorInteractive="false" +indentSpaces="3" +forceCreation="false" + +version=`antlr4 | head -1 | sed 's/.\+Version //1' | sed 's/^4\.//g' | sed 's/\.[0-9]\+$//g'` + +while (( $# > 0 )); do + arg="$1" + case "$arg" in + -h | -help) + help + ;; + -cpp | -c++) + target="cpp" + sourceExt="cpp" + ;; + -python | -python3) + target="python" + sourceExt="py" + ;; + -java) + target="java" + sourceExt="java" + ;; + -v | -visitor) + shift + if (( $# == 0 )); then + echo -e "ERROR: missing visitor file name!" + exit 2 + fi + visitorFile=(`echo $1 | sed "s/.$sourceExt\$//1" | sed 's/\.$//g'`) + treewalking+=($visitorFile) + visitors+=($visitorFile) + visitorFile=${visitorFile}.$sourceExt + treewalkingtype+=("v") + if [[ $forceCreation == "false" ]]; then + if ! [ -e $visitorFile ]; then + echo "ERROR: visitor file $visitorFile not found" + exit 3 + fi + fi + ;; + -l | -listener) + shift + if (( $# == 0 )); then + echo -e "ERROR: missing listener file name!" + exit 4 + fi + listenerFile=(`echo $1 | sed "s/.$sourceExt\$//1" | sed 's/\.$//g'`) + treewalking+=($listenerFile) + listeners+=($listenerFile) + listenerFile=${listenerFile}.$sourceExt + treewalkingtype+=("l") + if [[ $forceCreation == "false" ]]; then + if ! [ -e $listenerFile ]; then + echo "ERROR: listener file $listenerFile not found" + exit 5 + fi + fi + ;; + -i | -line-interactive) + delimiter="" + interactive="true" + lineInteractive="true" + separatorInteractive="false" + interactiveVar="lineText" + interactiveDelimiter="" + interactiveNext="Line" + nextExtraText="" + ;; + -is | -separator-interactive) + shift + if (( $# == 0 )); then + echo -e "ERROR: missing interactive delimiter text!" + exit 6 + fi + delimiter=$1 + interactive="true" + lineInteractive="false" + separatorInteractive="true" + interactiveVar="text" + interactiveDelimiter=".useDelimiter(\"${delimiter}\")" + interactiveNext="" + nextExtraText="+\"${delimiter}\"" + ;; + -indent) + shift + if (( $# == 0 )); then + echo -e "ERROR: missing indentation value!" + exit 6 + fi + indentSpaces="$1" + if ! [[ "$indentSpaces" =~ ^[0-9]+$ ]]; then + echo "ERROR: invalid indentation number" + exit 6 + fi + ;; + -f | -force) + forceCreation="true" + ;; + -*) + echo "ERROR: invalid argument!" + exit 1 + ;; + *) + if [[ $grammar == "" ]]; then + grammar=(`echo $1 | sed 's/.g4$//1' | sed 's/Parser$//1'`) + grammarfile=${grammar}.g4 + if ! [ -e $grammarfile ]; then + grammarfile=${grammar}Parser.g4 + if [[ $forceCreation == "false" ]]; then + if ! [ -e $grammarfile ]; then + echo "ERROR: grammar file of $grammar not found" + exit 7 + fi + fi + fi + elif [[ $rule == "" ]]; then + rule=$1 + if [[ $forceCreation == "false" ]]; then + if (! (cat ${grammarfile} | cpp 2>/dev/null | grep -wv '^#' | grep -E -A10 "^[[:space:]]*\<$rule\>" | tr '\n' ' ' | grep -E "[[:space:]]*\<$rule\>[[:space:]]*:" > /dev/null)); then + echo "ERROR: rule $rule not found in grammar $grammar" + exit 8 + fi + fi + else + echo -e "ERROR: invalid argument \"$1\"!" + exit 9 + fi + ;; + esac + shift +done + +if [[ $grammar == "" ]]; then + if (command -v cpp >/dev/null 2>&1); then + count=`find . -name \*.g4 | sed 's/Parser.g4$\|Lexer.g4$\|.g4$//1' | uniq | wc -l` + if ((count == 0)); then + echo "ERROR: Grammar file not found! (try option -h)" + exit 10 + elif ((count > 1)); then + echo "ERROR: Too many grammar files!" + find . -name \*.g4 -printf " %p\n" + exit 10 + fi + g4=`find . -name \*.g4 | sed 's/Parser.g4$\|Lexer.g4$\|.g4$//1' | uniq` + + if [ ! -e $g4.g4 ]; then + g4=${g4}Parser + fi + + grammar=`cat "$g4"*.g4 | cpp 2>/dev/null | grep -wv ^# | sed 's/{/ { /g' | sed 's/}/ } /g' | tr '\n' ' ' | tr ' ' '\n' | grep -wv parser | grep -wv options | grep -v ^\;$ | grep -v ^$ | gawk 'BEGIN {incode=0;} /{/ {incode++;} /}/ {incode--;} {if (incode == 0) print $0;}' | grep -v \} | grep -v @.* | head -2 | tail -1 | sed 's/[:;].*$//g' | grep -v ^$ | sed 's/Parser$//'` + rule=`cat "$g4"*.g4 | cpp 2>/dev/null | grep -wv ^# | sed 's/{/ { /g' | sed 's/}/ } /g' | tr '\n' ' ' | tr ' ' '\n' | grep -wv parser | grep -wv options | grep -v ^\;$ | grep -v ^$ | gawk 'BEGIN {incode=0;} /{/ {incode++;} /}/ {incode--;} {if (incode == 0) print $0;}' | grep -v \} | grep -v @.* | head -3 | tail -1 | sed 's/[:;].*$//g' | grep -v ^$` + + if [ -e ${grammar}Parser.g4 ]; then + grammarfile="${grammar}Lexer.g4 ${grammar}Parser.g4" + else + grammarfile=${grammar}.g4 + fi + + #echo "Grammar: $grammar" + #echo "Main rule: $rule" + + if [ -z "$grammar" ]; then + echo "ERROR: grammar name missing! (try option -h)" + exit 10 + fi + if [ -z "$rule" ]; then + echo "ERROR: first grammar rule missing!" + exit 11 + fi + else + echo -e "ERROR: missing grammar name! (try option -h)" + exit 10 + fi +fi + +if [[ $rule == "" ]]; then + echo -e "ERROR: missing rule name!" + exit 11 +fi + +fileName=${grammar}Main.$sourceExt + +if [[ $forceCreation == "true" ]]; then + if [ -f $fileName ]; then + rm -fv ${fileName} + fi +fi + +if [ -f $fileName ]; then + echo "ERROR: file \"$fileName\" already exists!" + exit 12 +fi + +echo -e "Creating \"$fileName\" for:" +echo -e " grammar=\"$grammar\"" +echo -e " grammarfile=\"$grammarfile\"" +echo -e " rule=\"$rule\"" +echo -e " target language: $target" +if (( ${#treewalking[*]} > 0 )); then + echo -e " treewalking=\"${treewalking[*]}\"" +fi +if (( ${#listeners[*]} > 0 )); then + echo -e " listeners=\"${listeners[*]}\"" +fi +if (( ${#visitors[*]} > 0 )); then + echo -e " visitors=\"${visitors[*]}\"" +fi +if [[ $lineInteractive == "true" ]]; then + echo -e " line-interactive" +fi +if [[ $separatorInteractive == "true" ]]; then + echo -e " separator-interactive (separador=\"$delimiter\")" +fi + +case $target in + java) + if [[ $interactive == "true" ]]; then + echo "import java.util.Scanner;" >> $fileName + else + echo "import java.io.IOException;" >> $fileName + fi + echo "import org.antlr.v4.runtime.*;" >> $fileName + echo "import org.antlr.v4.runtime.tree.*;" >> $fileName + echo "" >> $fileName + echo "public class ${grammar}Main {" >> $fileName + indentval=${indentSpaces}; indent=$(printf "%${indentval}s") + echo "${indent}public static void main(String[] args) {" >> $fileName + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}try {" >> $fileName + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + if [[ $interactive == "true" ]]; then + echo "${indent}Scanner sc = new Scanner(System.in)${interactiveDelimiter};" >> $fileName + echo "${indent}String ${interactiveVar} = null;" >> $fileName + echo "${indent}int num${interactiveNext} = 1;" >> $fileName + echo "${indent}if (sc.hasNext${interactiveNext}())" >> $fileName + echo "${indent} ${interactiveVar} = sc.next${interactiveNext}()${nextExtraText};" >> $fileName + echo "${indent}${grammar}Parser parser = new ${grammar}Parser(null);" >> $fileName + echo "${indent}// replace error listener:" >> $fileName + echo "${indent}//parser.removeErrorListeners(); // remove ConsoleErrorListener" >> $fileName + echo "${indent}//parser.addErrorListener(new ErrorHandlingListener());" >> $fileName + if (( ${#treewalking[*]} > 0 )); then + if (( ${#listeners[*]} > 0 )); then + echo "${indent}ParseTreeWalker walker = new ParseTreeWalker();" >> $fileName + fi + for(( i=0;i<${#treewalking[*]};i++ )); do + if [[ ${treewalkingtype[i]} == "l" ]]; then + # listener + echo "${indent}${treewalking[i]} listener$i = new ${treewalking[i]}();" >> $fileName + else + # visitor + echo "${indent}${treewalking[i]} visitor$i = new ${treewalking[i]}();" >> $fileName + fi + done + fi + echo "${indent}while(${interactiveVar} != null) {" >> $fileName + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + fi + echo "${indent}// create a CharStream that reads from standard input:" >> $fileName + if (( $version < 7 )); then + echo -n "${indent}ANTLRInputStream input = new ANTLRInputStream(" >> $fileName + if [[ $interactive == "true" ]]; then + echo -n "${interactiveVar} + \"\\n\"" >> $fileName + else + echo -n "System.in" >> $fileName + fi + echo ");" >> $fileName + else + echo -n "${indent}CharStream input = " >> $fileName + if [[ $interactive == "true" ]]; then + echo "CharStreams.fromString(${interactiveVar} + \"\\n\");" >> $fileName + else + echo "CharStreams.fromStream(System.in);" >> $fileName + fi + fi + echo "${indent}// create a lexer that feeds off of input CharStream:" >> $fileName + echo "${indent}${grammar}Lexer lexer = new ${grammar}Lexer(input);" >> $fileName + if [[ $interactive == "true" ]]; then + echo "${indent}lexer.setLine(num${interactiveNext});" >> $fileName + echo "${indent}lexer.setCharPositionInLine(0);" >> $fileName + fi + echo "${indent}// create a buffer of tokens pulled from the lexer:" >> $fileName + echo "${indent}CommonTokenStream tokens = new CommonTokenStream(lexer);" >> $fileName + echo "${indent}// create a parser that feeds off the tokens buffer:" >> $fileName + if [[ $interactive == "true" ]]; then + echo "${indent}parser.setInputStream(tokens);" >> $fileName + else + echo "${indent}${grammar}Parser parser = new ${grammar}Parser(tokens);" >> $fileName + echo "${indent}// replace error listener:" >> $fileName + echo "${indent}//parser.removeErrorListeners(); // remove ConsoleErrorListener" >> $fileName + echo "${indent}//parser.addErrorListener(new ErrorHandlingListener());" >> $fileName + fi + echo "${indent}// begin parsing at $rule rule:" >> $fileName + echo "${indent}ParseTree tree = parser.$rule();" >> $fileName + echo "${indent}if (parser.getNumberOfSyntaxErrors() == 0) {" >> $fileName + echo "${indent} // print LISP-style tree:" >> $fileName + echo "${indent} // System.out.println(tree.toStringTree(parser));" >> $fileName + if (( ${#treewalking[*]} > 0 )); then + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + if [[ $interactive != "true" ]]; then + if (( ${#listeners[*]} > 0 )); then + echo "${indent}ParseTreeWalker walker = new ParseTreeWalker();" >> $fileName + fi + for(( i=0;i<${#treewalking[*]};i++ )); do + if [[ ${treewalkingtype[i]} == "l" ]]; then + # listener + echo "${indent}${treewalking[i]} listener$i = new ${treewalking[i]}();" >> $fileName + else + # visitor + echo "${indent}${treewalking[i]} visitor$i = new ${treewalking[i]}();" >> $fileName + fi + done + fi + for(( i=0;i<${#treewalking[*]};i++ )); do + if [[ ${treewalkingtype[i]} == "l" ]]; then + # listener + echo "${indent}walker.walk(listener$i, tree);" >> $fileName + else + # visitor + echo "${indent}visitor$i.visit(tree);" >> $fileName + fi + done + indentval=$(echo ${indentval}-${indentSpaces} | bc); indent=$(printf "%${indentval}s") + fi + echo "${indent}}" >> $fileName + if [[ $interactive == "true" ]]; then + echo "${indent}if (sc.hasNext${interactiveNext}())" >> $fileName + echo "${indent} ${interactiveVar} = sc.next${interactiveNext}()${nextExtraText};" >> $fileName + echo "${indent}else" >> $fileName + echo "${indent} ${interactiveVar} = null;" >> $fileName + echo "${indent}num${interactiveNext}++;" >> $fileName + indentval=$(echo ${indentval}-${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}}" >> $fileName + fi + indentval=$(echo ${indentval}-${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}}" >> $fileName + if [[ $interactive == "false" ]]; then + echo "${indent}catch(IOException e) {" >> $fileName + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}e.printStackTrace();" >> $fileName + echo "${indent}System.exit(1);" >> $fileName + indentval=$(echo ${indentval}-${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}}" >> $fileName + fi + echo "${indent}catch(RecognitionException e) {" >> $fileName + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}e.printStackTrace();" >> $fileName + echo "${indent}System.exit(1);" >> $fileName + indentval=$(echo ${indentval}-${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}}" >> $fileName + indentval=$(echo ${indentval}-${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}}" >> $fileName + echo "}" >> $fileName + ;; + cpp) + makefileName="Makefile" + if [[ $forceCreation == "false" ]]; then + if [ -f $makefileName ]; then + echo "ERROR: file \"$makefileName\" already exists!" + exit 12 + fi + elif [ -f $makefileName ]; then + rm -fv ${makefileName} + fi + + # creating Makefile: + + echo -e ".PHONY: all clean cleanall #install" >> $makefileName + echo -e "" >> $makefileName + echo -e "GRAMMAR=${grammarfile}" >> $makefileName + echo -en "TARGETS_CPP=${grammar}Lexer.cpp ${grammar}Parser.cpp" >> $makefileName + if (( ${#listeners[*]} > 0 )); then + echo -en " ${grammar}BaseListener.cpp ${grammar}Listener.cpp" >> $makefileName + for(( i=0;i<${#listeners[*]};i++ )); do + add="true" + for(( j=0;j> $makefileName + fi + done + fi + if (( ${#visitors[*]} > 0 )); then + echo -en " ${grammar}BaseVisitor.cpp ${grammar}Visitor.cpp" >> $makefileName + for(( i=0;i<${#visitors[*]};i++ )); do + add="true" + for(( j=0;j> $makefileName + fi + done + fi + echo -e "" >> $makefileName + echo -en "OBJS=\$(TARGETS_CPP:cpp=o) ${grammar}Main.o" >> $makefileName + echo -e "" >> $makefileName + echo -e "TARGET=${grammar}Main" >> $makefileName + echo -e "" >> $makefileName + echo -e "CFLAGS=-Wall -ggdb -pthread -std=gnu++17 -I/usr/local/include/antlr4-runtime" >> $makefileName + echo -e "LDFLAGS=-lantlr4-runtime" >> $makefileName + echo -e "" >> $makefileName + echo -e "all: \$(TARGET)" >> $makefileName + echo -e "" >> $makefileName + echo -e "\$(TARGETS_CPP): \$(GRAMMAR)" >> $makefileName + if [ -e ${grammar}Parser.g4 ]; then + echo -e "\tantlr4 -cpp ${grammar}Lexer.g4" >> $makefileName + echo -e "\tantlr4 -cpp -visitor ${grammar}Parser.g4" >> $makefileName + else + echo -e "\tantlr4 -cpp -visitor \$(GRAMMAR)" >> $makefileName + fi + echo -e "" >> $makefileName + echo -e "%.o: %.cpp" >> $makefileName + echo -e "\tg++ \$(CFLAGS) -c \$<" >> $makefileName + echo -e "" >> $makefileName + echo -e "\$(TARGET): \$(GRAMMAR) \$(TARGETS_CPP) \$(OBJS)" >> $makefileName + echo -e "\tg++ \$(CFLAGS) \$(OBJS) \$(LDFLAGS) -o \$(TARGET)" >> $makefileName + echo -e "" >> $makefileName + echo -e "#install: \$(TARGET)" >> $makefileName + echo -e "#\tcp -a \$(TARGET) ../../bin" >> $makefileName + echo -e "" >> $makefileName + echo -e "clean:" >> $makefileName + echo -e "\trm -fv \$(OBJS) core" >> $makefileName + echo -e "" >> $makefileName + echo -e "cleanall: clean" >> $makefileName + echo -e "\tantlr4-clean -cpp" >> $makefileName + echo -e "\trm -fv \$(TARGET)" >> $makefileName + + + # creating main: + + echo "#include " >> $fileName + echo "#include " >> $fileName + echo "#include \"${grammar}Lexer.h\"" >> $fileName + echo "#include \"${grammar}Parser.h\"" >> $fileName + + for(( i=0;i<${#treewalking[*]};i++ )); do + add="true" + for(( j=0;j> $fileName + fi + done + echo "" >> $fileName + + echo "using namespace std;" >> $fileName + echo "using namespace antlr4;" >> $fileName + echo "using namespace antlr4::tree;" >> $fileName + echo "" >> $fileName + + echo "int main(int argc, const char* argv[]) {" >> $fileName + indentval=${indentSpaces}; indent=$(printf "%${indentval}s") + if [[ $lineInteractive == "true" ]]; then + echo "${indent}std::istream *stream = &cin;" >> $fileName + #echo "std::ifstream fstream;" >> $fileName + #echo "fstream.open("filename");" >> $fileName + #echo "stream = &fstream;" >> $fileName + + echo "${indent}string line;" >> $fileName + echo "${indent}int lineNum = 1;" >> $fileName + echo "${indent}${grammar}Parser* parser = new ${grammar}Parser(NULL);" >> $fileName + echo "${indent}// replace error listener:" >> $fileName + echo "${indent}//parser->removeErrorListeners(); // remove ConsoleErrorListener" >> $fileName + echo "${indent}//parser->addErrorListener(new ErrorHandlingListener());" >> $fileName + if (( ${#treewalking[*]} > 0 )); then + if (( ${#listeners[*]} > 0 )); then + echo "${indent}ParseTreeWalker* walker = new ParseTreeWalker();" >> $fileName + fi + for(( i=0;i<${#treewalking[*]};i++ )); do + if [[ ${treewalkingtype[i]} == "l" ]]; then + # listener + echo "${indent}${treewalking[i]}* listener$i = new ${treewalking[i]}();" >> $fileName + else + # visitor + echo "${indent}${treewalking[i]}* visitor$i = new ${treewalking[i]}();" >> $fileName + fi + done + fi + echo "${indent}while(getline(*stream, line)) {" >> $fileName + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + else + echo "${indent}std::istream *stream;" >> $fileName + fi + echo "${indent}// create a ANTLRInputStream that reads from standard input:" >> $fileName + echo "${indent}ANTLRInputStream* input;" >> $fileName + if [[ $lineInteractive == "true" ]]; then + echo "${indent}std::stringstream sstream;" >> $fileName + echo "${indent}sstream << line << \"\\n\";" >> $fileName + echo "${indent}std::istream *linestream = &sstream;" >> $fileName + echo "${indent}input = new ANTLRInputStream(*linestream);" >> $fileName + else + echo "${indent}stream = &cin;" >> $fileName + echo "${indent}input = new ANTLRInputStream(*stream);" >> $fileName + fi + echo "${indent}// create a lexer that feeds off of input ANTLRInputStream:" >> $fileName + echo "${indent}${grammar}Lexer* lexer = new ${grammar}Lexer(input);" >> $fileName + if [[ $lineInteractive == "true" ]]; then + echo "${indent}lexer->setLine(lineNum);" >> $fileName + echo "${indent}lexer->setCharPositionInLine(0);" >> $fileName + fi + echo "${indent}// create a buffer of tokens pulled from the lexer:" >> $fileName + echo "${indent}CommonTokenStream* tokens = new CommonTokenStream(lexer);" >> $fileName + echo "${indent}// create a parser that feeds off the tokens buffer:" >> $fileName + if [[ $lineInteractive == "true" ]]; then + echo "${indent}parser->setInputStream(tokens);" >> $fileName + else + echo "${indent}${grammar}Parser* parser = new ${grammar}Parser(tokens);" >> $fileName + echo "${indent}// replace error listener:" >> $fileName + echo "${indent}//parser->removeErrorListeners(); // remove ConsoleErrorListener" >> $fileName + echo "${indent}//parser->addErrorListener(new ErrorHandlingListener());" >> $fileName + fi + echo "${indent}// begin parsing at $rule rule:" >> $fileName + echo "${indent}ParseTree* tree = parser->$rule();" >> $fileName + echo "${indent}if (parser->getNumberOfSyntaxErrors() == 0) {" >> $fileName + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}// print LISP-style tree:" >> $fileName + echo "${indent}// cout << tree->toStringTree(parser) << endl;" >> $fileName + if (( ${#treewalking[*]} > 0 )); then + if [[ $lineInteractive != "true" ]]; then + if (( ${#listeners[*]} > 0 )); then + echo "${indent}ParseTreeWalker* walker = new ParseTreeWalker();" >> $fileName + fi + for(( i=0;i<${#treewalking[*]};i++ )); do + if [[ ${treewalkingtype[i]} == "l" ]]; then + # listener + echo "${indent}${treewalking[i]}* listener$i = new ${treewalking[i]}();" >> $fileName + else + # visitor + echo "${indent}${treewalking[i]}* visitor$i = new ${treewalking[i]}();" >> $fileName + fi + done + fi + for(( i=0;i<${#treewalking[*]};i++ )); do + if [[ ${treewalkingtype[i]} == "l" ]]; then + # listener + echo "${indent}walker->walk(listener$i, tree);" >> $fileName + else + # visitor + echo "${indent}visitor$i->visit(tree);" >> $fileName + fi + done + fi + indentval=$(echo ${indentval}-${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}}" >> $fileName + if [[ $lineInteractive == "true" ]]; then + echo "${indent}lineNum++;" >> $fileName + indentval=$(echo ${indentval}-${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}}" >> $fileName + fi + echo "}" >> $fileName + ;; + python) + indentval=${indentSpaces}; indent=$(printf "%${indentval}s") + echo "import sys" > $fileName + echo "from antlr4 import *" >> $fileName + echo "from ${grammar}Lexer import ${grammar}Lexer" >> $fileName + echo "from ${grammar}Parser import ${grammar}Parser" >> $fileName + if (( ${#treewalking[*]} > 0 )); then + for(( i=0;i<${#treewalking[*]};i++ )); do + echo "from ${treewalking[i]} import ${treewalking[i]}" >> $fileName + done + fi + echo "" >> $fileName + echo "def main(argv):" >> $fileName + if (( ${#treewalking[*]} > 0 )); then + if (( ${#listeners[*]} > 0 )); then + echo "${indent}walker = ParseTreeWalker()" >> $fileName + fi + for(( i=0;i<${#treewalking[*]};i++ )); do + if [[ ${treewalkingtype[i]} == "l" ]]; then + # listener + echo "${indent}listener$i = ${treewalking[i]}()" >> $fileName + else + # visitor + echo "${indent}visitor$i = ${treewalking[i]}()" >> $fileName + fi + done + fi + if [[ $interactive == "true" ]]; then + echo "${indent}for line in sys.stdin:" >> $fileName + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + echo "${indent}input_stream = InputStream(line)" >> $fileName + else + echo "${indent}input_stream = StdinStream()" >> $fileName + fi + echo "${indent}lexer = ${grammar}Lexer(input_stream)" >> $fileName + echo "${indent}stream = CommonTokenStream(lexer)" >> $fileName + echo "${indent}parser = ${grammar}Parser(stream)" >> $fileName + echo "${indent}tree = parser.${rule}()" >> $fileName + if (( ${#treewalking[*]} > 0 )); then + echo "${indent}if parser.getNumberOfSyntaxErrors() == 0:" >> $fileName + indentval=$(echo ${indentval}+${indentSpaces} | bc); indent=$(printf "%${indentval}s") + for(( i=0;i<${#treewalking[*]};i++ )); do + if [[ ${treewalkingtype[i]} == "l" ]]; then + # listener + echo "${indent}walker.walk(listener$i, tree)" >> $fileName + else + # visitor + echo "${indent}visitor$i.visit(tree)" >> $fileName + fi + done + indentval=$(echo ${indentval}-${indentSpaces} | bc); indent=$(printf "%${indentval}s") + fi + echo "" >> $fileName + echo "if __name__ == '__main__':" >> $fileName + echo "${indent}main(sys.argv)" >> $fileName + ;; + *) + echo "ERROR: $target main not yet implemented!" + ;; +esac + +exit 0 diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-run b/2ano2/Compiladores/antlr4-bin/antlr4-run new file mode 100755 index 0000000..1cf58b9 --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-run @@ -0,0 +1,72 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2017-2020 + +IFS=$'\n' + +scriptName="$0" +target="java" +ext=".class" + +function help() +{ + echo "Usage: $scriptName [-h | -help | -cpp | -python | -java]" + echo "" + echo " Runs the compiler present in current directory or in a subdirectory (fails if none exists," + echo " or if there are more than one)." + echo " Accepts program files as arguments (uses stdin if no argument is passed)." + echo "" + echo " target language:" + echo " -java: java (default)" + echo " -cpp: c++" + echo " -python: python3" + exit 1 +} + +case $1 in + "") + ;; + -h | -help) + help + ;; + -java) + shift + ;; + -cpp | -c++) + shift + target="cpp" + ext="" + ;; + -python | -python3) + shift + target="python" + ext=".py" + ;; +esac + +count=`find . -name \*Main$ext | wc -l` + +if ((count == 0)); then + echo "Main file not found!" + exit 1 +elif ((count > 1)); then + echo "Too many main files!" + find . -name \*Main$ext -printf " %p\n" + exit 1 +fi + +case $target in + java) + main=`find . -name \*Main.class | sed 's/.class//g' | sed 's/^.\///1'` + cat $* | java -ea $main + ;; + cpp) + main=`find . -name \*Main` + cat $* | exec $main + ;; + python) + main=`find . -name \*Main.py` + cat $* | python3 $main + ;; +esac + diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-test b/2ano2/Compiladores/antlr4-bin/antlr4-test new file mode 100755 index 0000000..48327f9 --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-test @@ -0,0 +1,97 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2017-2020 + +if [ -z "$ANTLR4_PATH" ]; then + cp="" +else + TMP_VERSION=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | tail -1 | sed 's/.*\///g' | sed 's/-com.*//g') + ANTLR4File=$(ls -f $ANTLR4_PATH/antlr-4*-complete.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + TMP_VERSION=$(ls -f $ANTLR4_PATH/ST-*.jar | tail -1 | sed 's/.*\///g' | sed 's/\.jar//g') + STFile=$(ls -f $ANTLR4_PATH/ST-*.jar | grep "$TMP_VERSION" | awk '{ print length(), $0 | "sort -n" }' | sed 's/^[0-9 ]\+//g' | tail -1) + cp="-cp .:$ANTLR4File:$STFile" +fi + +function help() +{ + echo "Usage: antlr4-test [ ] [options]" + echo "" + echo " Tests the ANTLR4 starting at rule ." + echo " Arguments may be omitted iff there is only one grammar in the directory" + echo " (and eventual subdirectories), and the first symbol in the grammar is the desired symbol." + echo "" + echo " principal options:" + echo " -h" + echo " -help" + echo " help page" + echo " -gui" + echo " shows the syntax tree" + echo " -tokens" + echo " shows the tokens" + echo "" + echo " other options:" + java -ea $cp org.antlr.v4.gui.TestRig 2>&1 | tail -n +2 | sed 's/^/ /g' + exit 1; +} + +if [[ $# == 1 && ($1 == "-h" || $1 == "-help") ]]; then + help +fi + +if [ $# -eq 1 ]; then + if [[ "$1" =~ "-h" ]]; then + java -ea $cp org.antlr.v4.gui.TestRig + exit 1 + fi +fi + +if [ $# -eq 0 ] || [ $# -eq 1 ] && [[ "$1" =~ "-"* ]]; then + if (command -v cpp >/dev/null 2>&1); then + count=`find . -name \*.g4 | sed 's/Parser.g4$\|Lexer.g4$\|.g4$//1' | uniq | wc -l` + if ((count == 0)); then + echo "ERROR: Grammar file not found! (try option -h)" + exit 1 + elif ((count > 1)); then + echo "ERROR: Too many grammar files!" + find . -name \*.g4 -printf " %p\n" + exit 1 + fi + g4=`find . -name \*.g4 | sed 's/Parser.g4$\|Lexer.g4$\|.g4$//1' | uniq` + p=`dirname $g4 | sed 's/^\.\///1'` + if [[ "$p" == "." ]]; then + p="" + else + p=$p. + fi + + if [ ! -e $g4.g4 ]; then + g4=${g4}Parser + fi + + grammar=`cat "$g4"*.g4 | cpp 2>/dev/null | grep -wv ^# | sed 's/{/ { /g' | sed 's/}/ } /g' | tr '\n' ' ' | tr ' ' '\n' | grep -wv parser | grep -wv options | grep -v ^\;$ | grep -v ^$ | gawk 'BEGIN {incode=0;} /{/ {incode++;} /}/ {incode--;} {if (incode == 0) print $0;}' | grep -v \} | grep -v @.* | head -2 | tail -1 | sed 's/[:;].*$//g' | grep -v ^$ | sed 's/Parser$//'` + rule=`cat "$g4"*.g4 | cpp 2>/dev/null | grep -wv ^# | sed 's/{/ { /g' | sed 's/}/ } /g' | tr '\n' ' ' | tr ' ' '\n' | grep -wv parser | grep -wv options | grep -v ^\;$ | grep -v ^$ | gawk 'BEGIN {incode=0;} /{/ {incode++;} /}/ {incode--;} {if (incode == 0) print $0;}' | grep -v \} | grep -v @.* | head -3 | tail -1 | sed 's/[:;].*$//g' | grep -v ^$` + + #echo "Grammar: $grammar" + #echo "Main rule: $rule" + + if [ -z "$grammar" ]; then + echo "ERROR: grammar name missing! (try option -h)" + exit 1 + fi + if [ -z "$rule" ]; then + echo "ERROR: first grammar rule missing!" + exit 1 + fi + + #echo "Grammar: $grammar" + #echo "Rule: $rule" + + java -ea $cp org.antlr.v4.gui.TestRig $p$grammar $rule $* + else + java -ea $cp org.antlr.v4.gui.TestRig $* + fi +else + java -ea $cp org.antlr.v4.gui.TestRig $* +fi + +exit $? diff --git a/2ano2/Compiladores/antlr4-bin/antlr4-visitor b/2ano2/Compiladores/antlr4-bin/antlr4-visitor new file mode 100755 index 0000000..752f2b2 --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/antlr4-visitor @@ -0,0 +1,255 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2017-2021 + +scriptName=antlr4-visitor +target=java +sourceExt="java" + +function help() +{ + echo -e "Usage: $scriptName [-h | -help] [-cpp [inline] | -python | -java] [-f | -force]\n [] " + echo "" + echo " Creates a visitor class named in the target language for ." + echo " Type instance of base generic visitor class will be ." + echo " Argument may be omitted iff there is only one grammar in the directory" + echo " (and eventual subdirectories)." + echo "" + echo " Target language:" + echo " -java: java (default)" + echo " -cpp: c++" + echo " -cpp inline: c++ with inline implementation (implementation in *.h class definition)" + echo " -python: python3" + echo "" + echo " options:" + echo " -h" + echo " -help" + echo " help page" + echo " -f" + echo " -force" + echo " force creation of visitor file" + echo " -i " + echo " -indent " + echo " number of indentation spaces (default: 3)" + echo " -l" + echo " -log" + echo " add method log stdout print" + exit 1 +} + +function logJava() +{ + local visitorType=$1 + local indent=$2 + if [[ $logActive == "true" ]]; then + cat - | sed "s/\($visitorType \)\(visit[a-zA-Z0-9_]\+\)\((.*$\)/\1\2\3\n${indent}${indent}System.out.println(\"[\2]\");/g" + else + cat - + fi +} + +function logCpp() +{ + local indent=$1 + if [[ $logActive == "true" ]]; then + cat - | sed "s/\(visit[a-zA-Z0-9_]\+\)\((.*{$\)/\1\2\n${indent}printf(\"[%s]\\\n\", \"\1\");/g" + else + cat - + fi +} + +function logPython() +{ + local indent=$1 + if [[ $logActive == "true" ]]; then + cat - | sed "s/\(visit[a-zA-Z0-9_]\+\)\((.*:$\)/\1\2\n${indent}${indent}print(\"[\1]\")/g" + else + cat - + fi +} + +indentSpaces="3" +forceCreation="false" +logActive="false" + +# process options: +while [[ $1 == -* ]]; do + case $1 in + -h | -help) + help + ;; + -cpp | -c++) + target="cpp" + sourceExt="cpp" + if [[ $# > 1 && $2 == "inline" ]]; then + shift + inline="true" + else + inline="false" + fi + ;; + -python | -python3) + target="python" + sourceExt="py" + ;; + -java) + target="java" + sourceExt="java" + ;; + -i | -indent) + shift + if (( $# == 0 )); then + echo -e "ERROR: missing indentation value!" + exit 1 + fi + indentSpaces="$1" + if ! [[ "$indentSpaces" =~ ^[0-9]+$ ]]; then + echo "ERROR: invalid indentation number" + exit 1 + fi + ;; + -f | -force) + forceCreation="true" + ;; + -l | -log) + logActive="true" + ;; + -*) + echo "ERROR: invalid argument!" + exit 1 + ;; + esac + shift +done + +if [[ $# == 0 || $# == 1 && $target != "python" ]]; then + echo "ERROR: Missing arguments!" + echo "" + help +fi + +indentval=${indentSpaces}; indent=$(printf "%${indentval}s") + +if (! command -v cpp >/dev/null 2>&1); then + echo "ERROR: cpp command missing (install gcc)" + exit 1 +fi + +grammar="" +grammarFile="" +if [ $# -eq 3 ]; then + gr=${1%.g4} + grammar=${gr%Parser} + if [[ ! -e "${grammar}.g4" && ! -e "${grammar}Parser.g4" ]]; then + echo "ERROR: Grammar file not found!" + exit 1 + fi + shift +else + count=`find . -name \*.g4 | sed 's/Parser.g4$\|Lexer.g4$\|.g4$//1' | uniq | wc -l` + if ((count == 0)); then + echo "ERROR: Grammar file not found!" + exit 1 + elif ((count > 1)); then + echo "ERROR: Too many grammar files!" + find . -name \*.g4 -printf " %p\n" + exit 1 + fi + g4=`find . -name \*.g4 | sed 's/Parser.g4$\|Lexer.g4$\|.g4$//1' | uniq` + p=`dirname $g4 | sed 's/^\.\///1'` + if [[ "$p" == "." ]]; then + p="" + else + p=$p. + fi + + if [ ! -e $g4.g4 ]; then + g4=${g4}Parser + fi + + grammar=`cat "$g4"*.g4 | cpp 2>/dev/null | grep -wv ^# | sed 's/{/ { /g' | sed 's/}/ } /g' | tr '\n' ' ' | tr ' ' '\n' | grep -wv parser | grep -wv options | grep -v ^\;$ | grep -v ^$ | gawk 'BEGIN {incode=0;} /{/ {incode++;} /}/ {incode--;} {if (incode == 0) print $0;}' | grep -v \} | grep -v @.* | head -2 | tail -1 | sed 's/[:;].*$//g' | grep -v ^$ | sed 's/Parser$//'` + + if [ -z "$grammar" ]; then + echo "ERROR: grammar name missing!" + exit 1 + fi +fi + +grammarFile="${grammar}.g4" +if [[ ! -e "$grammarFile" ]]; then + grammarFile="${grammar}Parser.g4" + if [[ ! -e "$grammarFile" ]]; then + echo "ERROR: Grammar file not found!" + exit 1 + fi +fi + +if ! [[ $# == 2 || ( $# == 1 && $target == "python" ) ]]; then + echo "ERROR: Missing arguments!" + echo "" + help +fi + +visitor=$(echo $1 | sed "s/\.${sourceExt}$//1" | sed 's/\.*//g') +if [[ $forceCreation == "false" ]]; then + if [ -e ${visitor}.$sourceExt ]; then + echo "ERROR: Visitor file \"${visitor}.$sourceExt\" already exists!" + exit 2 + fi +fi + +if [[ ${visitor} == ${grammar}Visitor || ${visitor} == ${grammar}BaseVisitor || + ${visitor} == ${grammar}Listener || ${visitor} == ${grammar}BaseListener || + ${visitor} == ${grammar}Parser || ${visitor} == ${grammar}Lexer ]]; then + echo "ERROR: Invalid visitor name (\"${visitor}\")!" + exit 1 +fi + +visitorType=${2} + +echo "Grammar: $grammar" +echo "Visitor: $visitor" +echo "Type: $visitorType" +echo "Target language: $target" + +if [[ -e "${grammar}Lexer.g4" ]]; then + antlr4 -$target "${grammar}Lexer.g4" +fi +antlr4 -$target -visitor "$grammarFile" +if [[ -e "${grammar}Parser.g4" ]]; then + grammar=${grammar}Parser +fi + +case $target in + java) + cpp "${grammar}BaseVisitor.java" | grep -v "^#.*$" | grep -v "^import.*$" | grep -v "^[ \t]*$" | sed "s/${grammar}BaseVisitor.*/${visitor} extends ${grammar}BaseVisitor<${visitorType}> {/1" | sed "s/\/$visitorType/g" | sed "s/^ /\n${indent}/g" | sed "s/ \(return.*;\)/\n${indent}${indent}$visitorType res = null;\n${indent}${indent}\1\n${indent}${indent}\/\/return res;/g" | sed "s/; }/;\n${indent}}/g" | logJava "$visitorType" "${indent}" > "${visitor}.java" + ;; + cpp) + if [[ $inline == "false" ]]; then + echo -e "#pragma once\n" > "${visitor}.h" + echo -e "#include \"${grammar}BaseVisitor.h\"\n" >> "${visitor}.h" + cat "${grammar}BaseVisitor.h" | grep -v "^#.*$" | cpp | grep -v "^#.*$" | grep -v "^[ \t]*$" | grep -v "^[ \t]*}$" | grep -wv "return" | sed "s/${grammar}BaseVisitor.*/${visitor} : public ${grammar}BaseVisitor {/1" | sed "s/^ /${indent}/g" | sed "s/^\(${indent}virtual\)/\n\1/g" | sed 's/override {/override;/g' >> "${visitor}.h" + echo "#include \"${visitor}.h\"" > "${visitor}.cpp" + cat "${grammar}BaseVisitor.h" | grep -v "^#.*$" | cpp | grep -v "^#.*$" | grep -v "^[ \t]*$" | grep -v "};" | grep -wv "class\|public" | sed "s/^ //g" | sed "s/^virtual /\n/g" | sed 's/override //g' | sed "s/any \(visit\)/any ${visitor}::\1/g" | sed "s/ \(return.*\)/${indent}std::any res;\n${indent}$visitorType r;\n${indent}\/\/ if (res.has_value()) {\n${indent}${indent}\/\/ r = std::any_cast<$visitorType>(res);\n${indent}\/\/ }\n${indent}\1\n${indent}\/\/return res;/g" | logCpp "${indent}" >> "${visitor}.cpp" + else + echo -e "#pragma once\n" > "${visitor}.h" + echo -e "#include \"${grammar}BaseVisitor.h\"\n" >> "${visitor}.h" + cat "${grammar}BaseVisitor.h" | grep -v "^#.*$" | cpp | grep -v "^#.*$" | grep -v "^[ \t]*$" | sed "s/${grammar}BaseVisitor.*/${visitor} : public ${grammar}BaseVisitor {/1" | sed "s/^ /${indent}/g" | sed "s/ \(return.*\)/${indent}std::any res;\n${indent}${indent}$visitorType r;\n${indent}${indent}\/\/ if (res.has_value()) {\n${indent}${indent}${indent}\/\/ r = std::any_cast<$visitorType>(res);\n${indent}${indent}\/\/ }\n${indent}${indent}\1\n${indent}${indent}\/\/return res;/g" | sed "s/^\(${indent}virtual\)/\n\1/g" | logCpp "${indent}${indent}" >> "${visitor}.h" + echo "#include \"${visitor}.h\"" > "${visitor}.cpp" + fi + ;; + python) + echo -e "from antlr4 import *" > "${visitor}.py" + echo -e "from ${grammar}Parser import ${grammar}Parser" >> "${visitor}.py" + echo -e "from ${grammar}Visitor import ${grammar}Visitor" >> "${visitor}.py" + echo -e "" >> "${visitor}.py" + echo -e "class $visitor(${grammar}Visitor):" >> "${visitor}.py" + cat "${grammar}Visitor.py" | grep -v "^[ \t]*#.*$" | grep "visit\|return" | sed -e 's/^[ \t]*//g' | sed -e "s/^\(def.*\)$/${indent}\1/g" | sed -e "s/^\(return.*\)$/${indent}${indent}\1\n/g" | logPython "${indent}" >> "${visitor}.py" + ;; + *) + echo "ERROR: $target visitors not yet implemented!" + ;; +esac +antlr4-clean -$target >& /dev/null + +exit 0 diff --git a/2ano2/Compiladores/antlr4-bin/java-clean b/2ano2/Compiladores/antlr4-bin/java-clean new file mode 100755 index 0000000..7c0a1ff --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/java-clean @@ -0,0 +1,5 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2006-2020 + +find . -name \*.class -printf "removing %p\n" -exec rm -f {} \; diff --git a/2ano2/Compiladores/antlr4-bin/st-groupfile2string b/2ano2/Compiladores/antlr4-bin/st-groupfile2string new file mode 100755 index 0000000..75997da --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/st-groupfile2string @@ -0,0 +1,23 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2020 + +if (( $# != 1 )); then + echo "Converts a STGroupFile to a String template (STGroupString)." + echo "" + echo "USAGE: st-groupfile2string " + exit 1 +fi + +file=$1 +if ! [ -e ${file} ]; then + echo "ERROR: STGroupFile ${file} not found!" + exit 2 +fi + +echo " // Automatically generated from $file" +echo ' String templates = ""+' +cat "$file" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed 's/^/ "/g' | sed 's/$/\\n"\+/g' +echo ' "";' + +exit 0 diff --git a/2ano2/Compiladores/antlr4-bin/view-javadoc b/2ano2/Compiladores/antlr4-bin/view-javadoc new file mode 100755 index 0000000..2125582 --- /dev/null +++ b/2ano2/Compiladores/antlr4-bin/view-javadoc @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Miguel Oliveira e Silva (mos@ua.pt), 2006-2020 + +# change the following variables to point to browser and javadoc directories! + +#BROWSER="/usr/bin/firefox" +BROWSER="firefox" +JDKDIR1=$(ls -fd /usr/share/doc/openjdk-*-jre-headless) +#JDKDIR1="/usr/share/doc/openjdk-8-jre-headless" +#JDKDIR2="/usr/local/share/java/docs" +JDKDIR2="" +#OTHERDIR="/usr/local/doc" +OTHERDIR="/usr/share/doc" +#OTHERDIR="" + +if [ $# -eq 0 ]; then + echo "Usage: view-javadoc " + exit 1; +fi + +declare -a docs; +docs=( $( find $OTHERDIR $JDKDIR1 $JDKDIR2 ! -path \*/class-use/\* -name "$1".html ) ) + +# ALTERNATIVE A: Open all found (if > 1) +if [ ${#docs[@]} -eq 0 ]; then + echo "Class not found!" + exit 2 +fi + +"$BROWSER" ${docs[@]} & + +exit 0 + +# ALTERNATIVE B: Let user select which one (if > 1) +case ${#docs[@]} in +0) + echo "Class not found!" + exit 2 + ;; +1) + doc=${docs[0]} + "$BROWSER" $doc & + ;; +*) + select doc in ${docs[@]}; do + break; + done + if [ -z "$doc" ]; then + exit 0; + fi + ;; +esac +"$BROWSER" $doc & + +exit 0 diff --git a/2ano2/Compiladores/flake.lock b/2ano2/Compiladores/flake.lock new file mode 100644 index 0000000..327c208 --- /dev/null +++ b/2ano2/Compiladores/flake.lock @@ -0,0 +1,60 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1708958830, + "narHash": "sha256-dsoGSxCJfgisVIzaD6OzJ3xwTk989ZVoLaGLBZNyXmM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "cec67db0d94418c44baae5b81e600c17605bc97d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/2ano2/Compiladores/flake.nix b/2ano2/Compiladores/flake.nix new file mode 100644 index 0000000..7abdbe5 --- /dev/null +++ b/2ano2/Compiladores/flake.nix @@ -0,0 +1,24 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs"; + flake-utils.url = "github:numtide/flake-utils"; + }; + outputs = { + nixpkgs, + flake-utils, + ... + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = import nixpkgs { + inherit system; + }; + in { + devShell = pkgs.mkShell { + packages = with pkgs; [ + jdk17 + antlr + doxygen + ]; + }; + }); +} diff --git a/2ano2/Compiladores/libs/ST-4.3.4.jar b/2ano2/Compiladores/libs/ST-4.3.4.jar new file mode 100644 index 0000000..21a2f61 Binary files /dev/null and b/2ano2/Compiladores/libs/ST-4.3.4.jar differ diff --git a/2ano2/Compiladores/src/Bloco1_1/Main.java b/2ano2/Compiladores/src/Bloco1_1/Main.java new file mode 100644 index 0000000..4c06e79 --- /dev/null +++ b/2ano2/Compiladores/src/Bloco1_1/Main.java @@ -0,0 +1,22 @@ +package Bloco1; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +public class Main { + public static void main(String[] args) { + final Tokenizer tokenizer = new Tokenizer(new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8))); + + try { + Token token = tokenizer.nextToken(); + while (token != null) { + System.out.println(token); + token = tokenizer.nextToken(); + } + } catch(IOException e) { + System.out.println(e.getMessage()); + } + } +}