Skip to content

kaby76/Trash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Trash

Build

Status: The toolset is still undergoing a major rewrite. Consider this toolkit as "pre-alpha". Old tools are being removed, and new ones are being added. Features are being added, while bugs are constantly being fixed. The XPath/XQuery engine is still being rewritten.

The repo g4-scripts contains a collections of Bash which use Trash. The repo also contains XQuery scripts that implement complex operations on a parse tree. You can also read about Trash details in my blog.

Trash is a collection of ~40 command-line tools to analyze and transform Antlr parse trees and grammars. The toolkit can: generate a parser application for an Antlr4 grammar for any target and any OS; analyze the grammar for common problems; automate changes applied to a grammar scraped from a specification; transform parse trees for transpilating and proprocessing source code. With the Antlr toolkit and the collection of Antlr grammars, one can write programming language tools quickly and easily.

The toolkit is designed around a JSON representation of parse trees and command-line tools that read, modify, and write those tree via standard input and output. Complex refactorings can be achieved by chaining different commands together.

Each app in Trash is implemented as a Dotnet Tool console application, and can be used on Windows, Linux, or Mac. No prerequisites are required other than installing the NET SDK, and the toolchains for any other targets you want to use.

The toolkit uses Antlr and XPath2. The code is implemented in C#.

An application of the toolkit was used to scrape and refactor the Dart2 grammar from spec. See this script.

Installation

Requirements

Install Dotnet 8.0.x

Install Globally

Copy this script and execute it in a command-line prompt.

dotnet tool install -g trcaret
dotnet tool install -g trclonereplace
dotnet tool install -g trcombine
dotnet tool install -g trconvert
dotnet tool install -g trcover
dotnet tool install -g trfoldlit
dotnet tool install -g trgen
dotnet tool install -g trgenvsc
dotnet tool install -g trglob
dotnet tool install -g triconv
dotnet tool install -g tritext
dotnet tool install -g trjson
dotnet tool install -g trparse
dotnet tool install -g trperf
dotnet tool install -g trquery
dotnet tool install -g trrename
dotnet tool install -g trsort
dotnet tool install -g trsplit
dotnet tool install -g trsponge
dotnet tool install -g trtext
dotnet tool install -g trtokens
dotnet tool install -g trtree
dotnet tool install -g trunfold
dotnet tool install -g trwdog
dotnet tool install -g trxml
dotnet tool install -g trxml2

Uninstall

dotnet tool uninstall -g trcaret
dotnet tool uninstall -g trclonereplace
dotnet tool uninstall -g trcombine
dotnet tool uninstall -g trconvert
dotnet tool uninstall -g trcover
dotnet tool uninstall -g trfoldlit
dotnet tool uninstall -g trgen
dotnet tool uninstall -g trgenvsc
dotnet tool uninstall -g trglob
dotnet tool uninstall -g triconv
dotnet tool uninstall -g tritext
dotnet tool uninstall -g trjson
dotnet tool uninstall -g trparse
dotnet tool uninstall -g trperf
dotnet tool uninstall -g trrename
dotnet tool uninstall -g trsort
dotnet tool uninstall -g trsplit
dotnet tool uninstall -g trsponge
dotnet tool uninstall -g trtext
dotnet tool uninstall -g trtokens
dotnet tool uninstall -g trtree
dotnet tool uninstall -g trunfold
dotnet tool uninstall -g trwdog
dotnet tool uninstall -g trxml
dotnet tool uninstall -g trxml2

Install Locally

dotnet new tool-manifest
dotnet tool install trcaret
dotnet tool install trclonereplace
dotnet tool install trcombine
dotnet tool install trconvert
dotnet tool install trcover
dotnet tool install trfoldlit
dotnet tool install trgen
dotnet tool install trgenvsc
dotnet tool install trglob
dotnet tool install triconv
dotnet tool install tritext
dotnet tool install trjson
dotnet tool install trparse
dotnet tool install trperf
dotnet tool install trquery
dotnet tool install trrename
dotnet tool install trsort
dotnet tool install trsplit
dotnet tool install trsponge
dotnet tool install trtext
dotnet tool install trtokens
dotnet tool install trtree
dotnet tool install trunfold
dotnet tool install trwdog
dotnet tool install trxgrep
dotnet tool install trxml
dotnet tool install trxml2

List of commands

NB: Out of date

  1. tranalyze -- Analyze a grammar
  2. trcombine -- Combine a split Antlr4 grammar
  3. trconvert -- Convert a grammar from one for to another
  4. trdot -- Print a parse tree in Graphvis Dot format
  5. trenum -- Not functional, to enumerate strings from grammar.
  6. trfirst -- Outputs first sets of a grammar
  7. trfold -- Perform fold transform on a grammar
  8. trfoldlit -- Perform fold transform on grammar with literals
  9. trformat -- Format a grammar
  10. trgen -- Generate an Antlr4 parser for a given target language
  11. trgen2 -- Generate files from template and XML doc list.
  12. trgroup -- Perform a group transform on a grammar
  13. tritext -- Get strings from a PDF file
  14. trjson -- Print a parse tree in JSON structured format
  15. trkleene -- Perform a Kleene transform of a grammar
  16. trmove -- Move nodes in a parse tree
  17. trparse -- Parse a grammar or use generated parse to parse input
  18. trperf -- Perform performance analysis of an Antlr grammar parse
  19. trpiggy -- Perform a parse tree rewrite
  20. trprint -- Print a parse tree, including off-token characters
  21. trrename -- Rename symbols in a grammar
  22. trrr -- (No description.)
  23. trrup -- Remove useless parentheses in a grammar
  24. trsem -- Read static semantics and generate code
  25. trsort -- Sort rules in a grammar
  26. trsplit -- Split a combined Antlr4 grammar
  27. trsponge -- Extract parsing results output of Trash command into files
  28. trst -- Print a parse tree in Antlr4 ToStringTree()
  29. trstrip -- Strip a grammar of all actions, labels, etc.
  30. trtext -- Print a parse tree with a specific interval
  31. trthompson -- (No description.)
  32. trtokens -- Print tokens in a parse tree
  33. trtree -- Print a parse tree in a human-readable format
  34. trull -- Transform a grammar with upper- and lowercase string literals
  35. trunfold -- Perform an unfold transform on a grammar
  36. trungroup -- Perform an ungroup transform on a grammar
  37. trwdog -- Kill a program that runs too long
  38. trxml -- Print a parse tree in XML structured format
  39. trxml2 -- Print an enumeration of all paths in a parse tree to leaves

Examples

Parse a grammar, create a parser for the grammar, build, and test

git clone https://github.com/antlr/grammars-v4
cd grammars-v4/python/python
trparse *.g4 | trquery 'grep //grammarDecl' | trtext
# Output:
# PythonLexer.g4:lexer grammar PythonLexer;
# PythonParser.g4:parser grammar PythonParser;
trgen
cd Generated
dotnet build
cat - <<EOF | trparse | trquery 'grep //test' | trtext
x == y
x == y if z == b else a == u
lambda: a
lambda x, y: a
EOF
# Output:
# a
# lambda x, y: a
# a
# lambda: a
# a == u
# x == y if z == b else a == u
# x == y

Display parse tree

trparse -i "a == b" | trtree

trtree is only one of several ways to view parse tree data. Other programs for different output are trjson for JSON output, trxml for XML output, trst for Antlr runtime ToStringTree output, trdot, trprint for input text for the parse, and tragl.

Convert grammars to Antlr4

trparse ada.g2 | trconvert | trprint | less

This command parses an old Antlr2 grammar using trparse, converts the parse tree data to Antlr4 syntax using trconvert and finally prints out the converted parse tree data, ada.g4 using trprint. Other grammar that can be converted are Antlr3, Bison, and ISO EBNF. In order to use the grammar to parse data, you will need to convert it to an Antlr4 grammar.

Generate an Arithmetic parser application

mkdir foobar; cd foobar; trgen

This command creates a parser application for the C# target. If executed in an empty directory, which is done in the example shown above, trgen creates an application using the Arithmetic grammar. If executed in a directory containing a Antlr Maven plugin (pom.xml), trgen will create a program according to the information specified in the pom.xml file. Either way, it creates a directory Generated/, and places the source code there.

trgen has many options to generate a parser from any Antlr4 grammar, for any target. But, if a parser is generated for the C# target, built using the NET SDK, then trparse can execute the generated parser, and can be used with all the other tools in Trash. _NB: In order to use the generate parser application, you must first build it:

dotnet restore Generated/Test.csproj
dotnet build Generated/Test.csproj

Run the generated parser application

trparse -i "1+2+3" | trtree

After using trgen to generate a parser program in C#, shown previously, and after building the program, you can run the parser using trparse. This program looks for the generated parser in directory Generated/. If it exists, it will run the parser application in the directory. You can pass as command-line arguments an input string or input file. If no command-line arguments are supplied, the program will read stdin. The output of trparse, as with most tools of Trash, is parse tree data.

Find nodes in the parse tree using XPath

mkdir empty; cd empty; trgen; dotnet build Generated/Test.csproj; \
    trparse -i "1+2+3" | trquery "grep //SCIENTIFIC_NUMBER" | trst

With this command, a directory is created, the Arithmetic grammar generated, build, and then run using trparse. The trparse tool unifies all parsing, whether it's parsing a grammar or parsing input using a generated parser application. The output from the trparse tool is a parse tree which you can search. Trquery is the generalized search program for parse trees. Trquery uses XPath expressions to precisely identify nodes in the parse tree.

XPath was added to Antlr4, but Trash takes the idea further with the addition of an XPath2 engine ported from the Eclipse Web toolkit. XPath is a well-defined language that should be used more often in compiler construction.

Rename a symbol in a grammar, generate a parser for new grammar

trparse Arithmetic.g4 | trrename "//parserRuleSpec//labeledAlt//RULE_REF[text() = 'expression']" "xxx" | trtext > new-source.g4
trparse Arithmetic.g4 | trrename -r "expression,expression_;atom,atom_;scientific,scientific_" | trprint

In these two examples, the Arithmetic grammar is parsed. trrename reads the parse tree data and modifies it by renaming the expression symbol two ways: first by XPath expression identifying the LHS terminal symbol of the expression symbol, and the second by assumption that the tree is an Antlr4 parse tree, then renaming a semi-colon-separated list of paired renames. The resulting code is reconstructed and saved. trrename does not rename symbols in actions, nor does it rename identifiers corresponding to the grammar symbols in any support source code (but it could if the tool is extended).

Count method declarations in a Java source file

git clone https://github.com/antlr/grammars-v4.git; \
    cd grammars-v4/java/java9; \
    trgen; dotnet build Generated/Test.csproj;\
    trparse examples/AllInOne8.java | trquery "greap //methodDeclaration" | trst | wc

This command clones the Antlr4 grammars-v4 repo, generates a parser for the Java9 grammar, then runs the parser on examples/AllInOne8.java. The parse tree is then piped to trquery to find all parse tree nodes that are a methodDeclaration type, converts it to a simple string, and counts the result using wc.

Strip a grammar of all non-essential CFG

trparse Java9.g4 | trstrip | trtext > Essential-Java9.g4

Split a grammar

Since Antlr2, one can written a combined parser/lexer in one file, or a split parser/lexer in two files. While it's not hard to split or combine a grammar, it's tedious. For automating transformations, it's necessary because Antlr4 requires the grammars to be split when super classes are needed for different targets.

trcombine ArithmeticLexer.g4 ArithmeticParser.g4 | trprint > Arithmetic.g4

This command calls trcombine which parses two split grammar files ArithmeticLexer.g4 and ArithmeticParser.g4, and creates a combined grammar for the two.

trparse Arithmetic.g4 | trsplit | trsponge -o true

This command calls trsplit which splits the grammar into two parse tree results, one that defines ArithmeticLexer.g4 and the other that defines ArithmeticParser.g4. The tool trsponge is similar to the tee in Linux: the parse tree data is split and placed in files.

Parsing Result Sets -- the data passed between commands

A parsing result set is a JSON serialization of an array of:

  • A set of parse tree nodes.
  • Parser information related to the parse tree nodes.
  • Lexer information related to the parse tree nodes.
  • The name of the input corresponding to the parse tree nodes.
  • The input text corresponding to the parse tree nodes.

Most commands in Trash read and/or write parsing result sets.

Supported grammars

Grammars File suffix
Antlr4 .g4
Antlr3 .g3
Antlr2 .g2
Bison .y
LBNF .cf
W3C EBNF .ebnf
ISO 14977 .iso14977, .iso

Analysis

Recursion

Refactoring

Trash provides a number of transformations that can help to make grammars cleaner (reformatting), more readable (reducing the length of the RHS of a rule), and more efficient (reducing the number of non-terminals) for Antlr.

Some of these refactorings are very specific for Antlr due to the way the parser works, e.g., converting a prioritized chain of productions recognizing an arithmetic expression to a recursive alternate form. The refactorings implemented are:

Raw tree editing

Reordering

Changing rules

Splitting and combining

Conversion


The source code for the extension is open source, free of charge, and free of ads. For the latest developments on the extension, check out my blog.

Building

git clone https://github.com/kaby76/Trash
cd Trash
make clean; make; make install

You must have the NET SDK version 8 installed to build and run.

Releases

See https://github.com/kaby76/Trash/releases.

If you have any questions, email me at ken.domino gmail.com