!cat -n Expr.g4
#!type Expr.g4   # For Windows

"""
Explanation: Testing an <span style="font-variant:small-caps;">Antlr</span> Grammar via grun or pygrun
In order for the examples using <span style="font-variant:small-caps;">Antlr</span> to work, 
we first have to install <span style="font-variant:small-caps;">Antlr</span> by downloading
https://www.antlr.org/download/antlr-4.8-complete.jar.  I will assume that this .jarfile is 
stored in the directory /usr/local/lib/.  Furthermore, I assume that both a java runtime
and a java compiler are available.  We also need to install the python language bindings 
using the following command:
pip install antlr4-python3-runtime
At the time of this writing, conda install does not work if the python kernel is running Python 3.9.
Our grammar is stored in the file Expr.g4.  In order to inspect it, we use the command line tool cat.  This will work with MacOs and Linux.  On Windows,
either use the power shell, which understands cat,  or use the command type instead.  The option  -n of cat provides numbered output.
End of explanation
"""


!java -jar /usr/local/lib/antlr-4.8-complete.jar -Dlanguage=Python3 Expr.g4

"""
Explanation: Note that this grammar does not contain any embedded actions.
Hence we cannot compute anything with it.  We will only be able to 
check whether a given string is generated by this grammar.  Provided you have stored the file 
antlr-4.8-complete.jar in the directory
/usr/local/lib/ we can generate both the scanner and the parser using the following command:
End of explanation
"""


!ls -l
#!dir /B   # For Windows

"""
Explanation: On Unix-like systems it is also convenient to define an <em style="color:blue">alias</em> of the following form in the file .bashrc
that is used to initialize the bash shell:
alias antlr='java -jar /usr/local/lib/antlr-4.8-complete.jar -Dlanguage=Python3'
We can use the system command ls to see which files have been generated by <span style="font-variant:small-caps;">Antlr</span>.
If you are using a windows system you have to use the command dir instead.
End of explanation
"""


from ExprLexer  import ExprLexer
from ExprParser import ExprParser

"""
Explanation: The files ExprLexer.py and ExprParser.py contain the generated scanner and parser, respectively.
If we want to test the parser in this notebook, we have to import these files.
End of explanation
"""


import antlr4

"""
Explanation: In order to use the <span style="font-variant:small-caps;">Antlr</span> runtime, we have to import it.
Note that this runtime is not contained in antlr-4.8-complete.jar and needs to be installed separately using the following command:
pip install antlr4-python3-runtime
End of explanation
"""


def parse_string(string): 
    inputStream = antlr4.InputStream(string)
    lexer       = ExprLexer(inputStream)
    tokenStream = antlr4.CommonTokenStream(lexer)
    parser      = ExprParser(tokenStream)
    parser.expr()

parse_string('1 + 2 * 3 - 4')

"""
Explanation: Now we can parse a string.  The function parser_string takes the string s as its argument and checks,
whether this string can be parsed as an arithmetic expression.  This is done in five steps:
- The string is converted into an antlr4.InputStream.
- The input stream is converted into a lexer.
- The lexer is converted into an antlr4.CommonTokenStream.
- The token stream is converted into a parser.
- The parser tries to parse with start symbol.
End of explanation
"""


parse_string('1 + 2 * 3 ** 4')

"""
Explanation: As there is no syntax error, the string '1 + 2 * 3 - 4' adheres to the specification given by our grammar.
Lets try a string that is not generated by our grammar.
End of explanation
"""


parse_string('1 < 2')

"""
Explanation: As the operator ** is not supported by our grammar, we get a syntax error at the 
last occurrence of the character * in the given string.
End of explanation
"""


!java -jar /usr/local/lib/antlr-4.8-complete.jar -Dlanguage=Java Expr.g4

"""
Explanation: This time we get a lexical error as the character &lt; is not a legal token.
We can also generate a parse tree with our grammar.  However, for this to work <span style="font-variant:small-caps;">Antlr</span>
first has to generate a java parser.  Hence we have to call antlr4 again, but this time with Java as the target language.
End of explanation
"""


!ls -l *.java
#!dir /B *.java   # For Windows

"""
Explanation: This command has generated some files for us that contain a both a lexer and a parser.
However, this time these are .java-files.
End of explanation
"""


!javac -cp .:/usr/local/lib/antlr-4.8-complete.jar *.java
#!javac -cp .;C:/Users/xxx/antlr-4.8-complete.jar *.java   # For Windows

"""
Explanation: We have to compile the generated .java files.  Below, you might have to change the path to 
the file antlr-4.8-complete.jar to make this work.
End of explanation
"""


!echo "1+2*3-4" | java -cp .:/usr/local/lib/antlr-4.8-complete.jar org.antlr.v4.gui.TestRig Expr expr -gui
# For Windows
#!echo 1+2*3-4 | java -cp .;C:/Users/xxx/Downloads/antlr-4.8-complete.jar org.antlr.v4.gui.TestRig Expr expr -gui

"""
Explanation: Next, we can start the so called TestRig to generate and display the <em style="color:blue">parse tree</em> for a given string.
End of explanation
"""


!ls
# !dir /B   # For Windows

!rm *.py *.tokens *.interp *.java *.class
!rm -r __pycache__/

# For Windows
#!del *.py *.tokens *.interp *.java *.class /Q
#!rmdir __pycache__ /S /Q

!ls -l
!dir /B   # For Windows

"""
Explanation: Let us clean up the working directory.
End of explanation
"""


