├── .gitignore ├── LICENSE.md ├── README.md ├── build ├── apg-overview.html ├── apg.mf ├── examples.mf ├── generate-demos ├── generate-generator-grammar ├── javadoc-args.txt ├── make-jars └── make-javadoc ├── maven.md └── src ├── apg ├── ABNFforSABNF.bnf ├── Ast.java ├── Generator.java ├── GeneratorAttributes.java ├── GeneratorCommandLine.java ├── GeneratorGrammar.java ├── GeneratorSyntax.java ├── Grammar.java ├── Opcode.java ├── Parser.java ├── Statistics.java ├── Trace.java ├── UdtLib.java ├── Utilities.java └── package.html └── examples ├── Main.java ├── RunTests.java ├── Utils.java ├── anbn ├── AnBn.java ├── HandwrittenAnBn.java ├── RunAnBn.java ├── UAnBn.java ├── anbn.bnf ├── input.txt ├── package.html └── uanbn.bnf ├── anbncn ├── AnBnCn.java ├── HandwrittenAnBnCn.java ├── RunAnBnCn.java ├── UAnBnCn.java ├── anbncn.bnf ├── package.html └── uanbncn.bnf ├── demo ├── DisplayAst.java ├── DisplayTrace.java ├── Expressions.java ├── Hostname.java ├── IPv4.java ├── TranslateAst.java ├── UExpressions.java ├── UHostname.java ├── UIPv4.java ├── UdtAsAlt.java ├── UdtToAst.java ├── expressions.bnf ├── hostname.bnf ├── ipv4.bnf ├── package.html ├── uexpressions.bnf ├── uhostname.bnf └── uipv4.bnf ├── expressions ├── Expressions.java ├── RunExpressions.java ├── UExpressions.java ├── expressions.bnf ├── package.html └── uexpressions.bnf ├── inifile ├── IniFile.input ├── IniFile.java ├── RunIniFile.java ├── UIniFile.java ├── inifile.bnf ├── package.html └── uinifile.bnf ├── mailbox ├── Atom.java ├── DContent.java ├── Ldh_str.java ├── Mailbox.java ├── RunMailbox.java ├── ULet_dig.java ├── UMailbox.java ├── mailbox.bnf ├── package.html └── umailbox.bnf ├── package.html └── testudtlib ├── Alphanum.java ├── AnyString.java ├── Comment.java ├── DecNum.java ├── HexNum.java ├── LineEnd.java ├── QuotedString.java ├── RunUdtTest.java ├── UEmpty.bnf ├── UEmpty.java ├── UNonEmpty.bnf ├── UNonEmpty.java ├── WhiteSpace.java ├── alphanum.bnf ├── any.bnf ├── comment.bnf ├── decnum.bnf ├── hexnum.bnf ├── lineend.bnf ├── package.html ├── quotedstring.bnf └── whitespace.bnf /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .* 3 | !.gitignore 4 | **/bin 5 | **/classes 6 | **/javadoc 7 | **/out 8 | *.jar 9 | *.iml 10 | /build/*.txt 11 | cmsg 12 | README.html 13 | RemoteSystemsTempFiles 14 | /bin/ 15 | how-to.txt 16 | grammar-regen.sh 17 | /src/examples/target/ 18 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause) 2 | 3 |

4 | Copyright (c) 2021 Lowell D. Thomas
5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 |

29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Java APG 2 | 3 | **Version:** 1.1.0 4 | 5 | *Note:* Version 1.1.0 updates version 1.0 in a couple of ways. Primarily, the license is changed to the more permissive 2-Clause BSD license. Also, in the installation section below are instructions on how to include Java APG in a [maven](https://maven.apache.org/) project. I want to thank [Raviteja Lokineni](https://github.com/bond-) (@bond-) for suggesting these changes and especially [Stephen Sill II](https://github.com/ssill2) (@ssill2) for his friendly and expert nudging of me up the maven learning curve. (See issue #6.) 6 | 7 | **Description:** 8 | 9 | 30 | For more details see the documentation or visit the APG website. 31 | 32 | | Directories/files: | description | 33 | | :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 34 | | src/apg | Java APG, the generator and the runtime library required by all generated parsers. | 35 | | src/examples/ | Examples to demonstrate how to set up and use a Java APG parser. The main function here is the driver for running any and all of the following examples. See javadoc `examples.Main` for a complete list of the tests that it runs. | 36 | | src/examples/anbn | Comparisons the CFG and UDT parsers for the anbn, n > 0, grammar. | 37 | | src/examples/anbncn | Comparisons the CFG and UDT parsers for the anbncn, n > 0, grammar. | 38 | | src/examples/demo | Demonstrates many of the main features of Java APG including UDTs. | 39 | | src/examples/expressions | Comparisons the CFG and UDT parsers for the expressions grammar. | 40 | | src/examples/inifile | Comparisons the CFG and UDT parsers for the inifile grammar. | 41 | | src/examples/mailbox | Comparisons the CFG and UDT parsers for the mailbox grammar (). | 42 | | src/examples/testudtlib | Comparisons the CFG and UDT parsers for the suite of UdtLib UDTs. | 43 | | build/ | Scripts and files for compiling and documenting Java APG. | 44 | | LICENSE.md | 2-Clause BSD license. | 45 | | README.md | This file. | 46 | 47 | **Installation:** 48 | The `build/` directory has scripts and files for compiling and documenting Java APG. 49 | To compile all source code and create the package `.jar` files: 50 | 51 | ``` 52 | git clone https://github.com/ldthomas/apg-java.git 53 | cd apg-java/build 54 | ./make-jars 55 | ``` 56 | 57 | This will create `apg.jar` and `examples.jar`. To test `apg.jar` run: 58 | 59 | ``` 60 | java -jar apg.jar /version 61 | ``` 62 | To test `examples.jar` run: 63 | ``` 64 | java -jar examples.jar /test=all 65 | ``` 66 | **Maven:** 67 | For maven development, install apg.jar in the local repository. 68 | ``` 69 | mvn install:install-file -DgroupId=com.sabnf -DartifactId=apg -Dversion=1.1-SNAPSHOT -Dpackaging=jar -Dfile=apg.jar -DgeneratePom=true 70 | ``` 71 | Then modify the project's pom.xml file to include, 72 | ``` 73 | 74 | 75 | com.sabnf 76 | apg 77 | 1.1-SNAPSHOT 78 | compile 79 | 80 | 81 | 82 | ``` 83 | See the [maven.md](maven.md) for details on how to run the examples in a NetBeans maven project. 84 | 85 | _NOTE:_ A second branch, maven, has been added which is a complete maven project for apg and the examples. 86 | It was created by [Stephen Sill II](https://github.com/ssill2) on his [apg-java fork](https://github.com/ssill2/apg-java). 87 | It has updates to satisfy some of the security items flagged by 88 | [Fortify](https://www.microfocus.com/en-us/cyberres/application-security/static-code-analyzer) security scans. 89 | The Fortify updates have not been integrated into the master branch. 90 | 91 | **Documentation:** 92 | To see the documentation run: 93 | 94 | ``` 95 | ./make-javadoc 96 | ``` 97 | 98 | Open `../javadoc/index.html` in any web browser. Or visit the [APG website](https://sabnf.com). 99 | 100 | **Copyright:** 101 | _Copyright © 2021 Lowell D. Thomas, all rights reserved_ 102 | 103 | **License:** 104 | Java APG Version 1.1.0 is released under the [2-Clause BSD license](https://opensource.org/licenses/BSD-2-Clause). 105 | 106 | -------------------------------------------------------------------------------- /build/apg-overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | Java APG is APG, an ABNF Parser Generator, 5 | written in the Java language. 6 |

7 |

8 | The "apg" package contains the parser generator and the runtime library of functions required 9 | by all parsers that it generates. 10 |

11 |

The "examples" package contains a driver function to run any and all of the included tests. 12 | The tests themselves are in the examples sub-packages.
13 | These examples demonstrate a variety of ways to use Java APG and its new UDT feature. 14 |

15 |

16 | A summary of Java APG's new features is: 17 |

32 |

33 | APG was originally written to fulfill a need for a parser generator that would generate parsers 34 | directly from ABNF grammars as defined by the IETF in 35 | RFC 5234. 36 | Since then the grammar syntax for APG has evolved from that standard 37 | 1) to generate unambiguous parsers 38 | and 2) to add capabilities beyond the class of context-free-languages. 39 | Because of 2) the APG grammars are called SABNF (Superset ABNF). 40 | ABNF and SABNF will often be used interchangably in this document. 41 | The differences between RFC 5234 grammars and SABNF are summarized here: 42 | 76 |

77 | (*) The reason for the two designations u_ and 78 | e_ is a subtle but serious difference as to whether the UDT will accept empty 79 | strings or not. e_ indicates that the UDT will accept empty strings. 80 | u_ indicates that the UDT will not accept empty strings. The Parser 81 | enforces this distinction. If a UDT named u_my-udt, for example, returns 82 | an empty string the Parser will throw and exception. The reason for this has to do with the 83 | fact that left-recursive grammars will put the Parser into an infinite loop that will cause a stack-overflow. 84 | The check for left-recursiveness in the GeneratorAttributes class relies on 85 | knowing whether the rule name operators (and UDT operators as well) accept empty strings. 86 | The general properties of the UDT's are unknown to the Generator because they are user written. This 87 | naming convention and the Parser's enforcing of it is the only way to prevent a possible stack-overflow 88 | due to a hidden left-recursion.

89 |

90 |

91 | For more information about APG, UDTs, its versions and downloads, 92 | you can visit the 93 | APG web site . 94 | For information on how to use Java APG you should consult the examples in this document 95 | and the source code. 96 |

97 | 98 | 99 | -------------------------------------------------------------------------------- /build/apg.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: apg.Generator 3 | 4 | -------------------------------------------------------------------------------- /build/examples.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: examples.Main 3 | 4 | -------------------------------------------------------------------------------- /build/generate-demos: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # re-generates some of the demo parsers from their ABNF grammars 4 | # this is how the parser's opcode files are generated from the ABNF grammar files (.bnf) 5 | # 6 | DIR=../src/examples/ 7 | java -jar apg.jar /in=expressions.bnf /javadoc=Expressions /dir="$DIR/demo/" /package="examples.demo" /da /dm /de /dw 8 | java -jar apg.jar /in=uexpressions.bnf /javadoc=UExpressions /dir="$DIR/demo/" /package="examples.demo" /da /dm /de /dw 9 | java -jar apg.jar /in=ipv4.bnf /javadoc=IPv4 /dir="$DIR/demo/" /package="examples.demo" /da /dm /de /dw 10 | java -jar apg.jar /in=uipv4.bnf /javadoc=UIPv4 /dir="$DIR/demo/" /package="examples.demo" /da /dm /de /dw 11 | java -jar apg.jar /in=hostname.bnf /javadoc=Hostname /dir="$DIR/demo/" /package="examples.demo" /da /dm /de /dw 12 | java -jar apg.jar /in=uhostname.bnf /javadoc=UHostname /dir="$DIR/demo/" /package="examples.demo" /da /dm /de /dw 13 | exit 0 14 | -------------------------------------------------------------------------------- /build/generate-generator-grammar: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # re-generates APG's parser opcode file (GeneratorGrammar.java) from the ABNF grammar 4 | # 5 | DIR=../src/apg/ 6 | java -jar apg.jar /in=ABNFforSABNF.bnf /javadoc=GeneratorGrammar /dir="$DIR" /package="apg" /da /dm /de /dw 7 | exit 0 8 | -------------------------------------------------------------------------------- /build/javadoc-args.txt: -------------------------------------------------------------------------------- 1 | -d ../javadoc 2 | -sourcepath ../src 3 | -header '
Java APG Version 1.1.0
Copyright © 2021 Lowell D. Thomas' 4 | -footer '
Java APG Version 1.1.0
Copyright © 2021 Lowell D. Thomas' 5 | -bottom 'Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License
Copyright (c) 2021 Lowell D. Thomas, All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.' 6 | -overview ./apg-overview.html 7 | -windowtitle "Java APG" 8 | -public 9 | apg 10 | examples 11 | examples.anbn 12 | examples.anbncn 13 | examples.demo 14 | examples.expressions 15 | examples.inifile 16 | examples.mailbox 17 | examples.testudtlib 18 | -------------------------------------------------------------------------------- /build/make-jars: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # define the binary and source directories 4 | bindir=../bin 5 | srcdir=../src 6 | 7 | # create the binary directory if it does not exist 8 | if [ ! -d $bindir ] 9 | then 10 | mkdir $bindir ; 11 | echo "make-jars: made classes directory $bindir" ; 12 | fi 13 | 14 | # compile the apg source 15 | javac -d $bindir $srcdir/apg/*.java 16 | if [ $? -eq 0 ] 17 | then 18 | echo "make-jars: apg source compiled ok"; 19 | else 20 | echo "make-jars: apg source compile failed"; 21 | exit 1 22 | fi 23 | 24 | # make apg.jar 25 | jar cmf apg.mf apg.jar -C $bindir . 26 | if [ $? -eq 0 ] 27 | then 28 | echo "make-jars: created apg.jar"; 29 | else 30 | echo "make-jars: apg.jar failed"; 31 | exit 1 32 | fi 33 | 34 | # compile the examples source 35 | javac -sourcepath $srcdir -d $bindir $srcdir/examples/*.java 36 | if [ $? -eq 0 ] 37 | then 38 | echo "make-jars: examples source compiled ok"; 39 | else 40 | echo "make-jars: examples source compile failed"; 41 | exit 1 42 | fi 43 | 44 | # make examples.jar 45 | jar cmf examples.mf examples.jar -C $bindir/apg . -C $bindir . 46 | if [ $? -eq 0 ] 47 | then 48 | echo "make-jars: created examples.jar"; 49 | else 50 | echo "make-jars: examples.jar failed"; 51 | exit 1 52 | fi 53 | 54 | exit 0 55 | -------------------------------------------------------------------------------- /build/make-javadoc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # create the HTML documentation files 3 | javadoc @javadoc-args.txt 4 | exit 0 5 | -------------------------------------------------------------------------------- /maven.md: -------------------------------------------------------------------------------- 1 |  2 | ## A Maven Project for the Java APG 1.1.0 Examples 3 | The examples are meant to illustrate the basic usage of Java APG with emphasis on the new UDT feature, first introduced in Java APG Version 1.0. Building the jar file and executing the examples is fine, as far as it goes. But to be really useful, you need to be able to follow along in a debugger, make changes, play with your own modifications, etc. 4 | 5 | As released, Java APG 1.1.0 is not set up for an "in place" maven project. If you are already a maven expert, you should have no trouble doing this. (See, for example, the branch [ssill2/apg-java](https://github.com/ssill2/apg-java/tree/maven).) However, here is one way to convert just the examples to a maven project. I'll assume that we are in the directory `/my-path` and using maven 3.8.1, JDK 11 and NetBeans 12.3. Other versions will surely work and you can adjust these instructions accordingly. 6 | ``` 7 | git clone https://github.com/ldthomas/apg-java.git 8 | cd apg-java/build 9 | ./make-jars 10 | mvn install:install-file -DgroupId=com.sabnf -DartifactId=apg -Dversion=1.1-SNAPSHOT -Dpackaging=jar -Dfile=apg.jar -DgeneratePom=true 11 | ``` 12 | In NetBeans open a new project with `File->New Project->Java with maven->Project from Archetype`. Click `next` and select `maven-archetype-quickstart`. There may be more than one selection with that name. Just select the first one. Click `next` and set, 13 | ``` 14 | Project Name: examples 15 | Project Location: browse to /my-path 16 | Group Id: examples 17 | Version: 1.1-SNAPSHOT 18 | Package: examples 19 | Click finish 20 | ``` 21 | At this point you should have a complete "Hello World" project. Click `Run->Run Project (examples)` and you should see "Hello Wold" in the output. If it fails, check `Tools->Options->Java->Maven` and make sure the Maven Home points to your installation of maven 3.8.1 and that the Default JDK selection is JDK 11. _(Note that the selection JDK 11 (Default) may not actually be pointing to a valid JDK installation._ 22 | 23 | From here, we just need to get the examples into the project shell and update the Project Object Model. 24 | ``` 25 | rm /my-path/examples/src/main/java/examples/* 26 | cp -r /my-path/apg-java/src/examples/* /my-path/examples/src/main/java/examples 27 | ``` 28 | In NetBeans, open the pom.xml file. In the `` section, if JDK 11 is not already specified, replace the maven compiler directives with 29 | ``` 30 | 11 31 | 11 32 | ``` 33 | In the `` section add 34 | ``` 35 | 36 | com.sabnf 37 | apg 38 | 1.1-SNAPSHOT 39 | compile 40 | 41 | ``` 42 | In NetBeans, right-click on the examples project and select `Properties->Run` and set, 43 | ``` 44 | Main Class: examples.Main 45 | Arguments /test=all /reps=1 46 | click OK 47 | ``` 48 | _(Thanks to @ssill2 for showing me this obscure way of setting the runtime arguments.)_ 49 | Now `Run->Run Project (examples)` should run all of the tests. At this point you can now set break points and run `Debug->Debug Project (examples)` as well. 50 | 51 | There is another clever way to debug with varying runtime arguments, this again thanks to @ssill2. Open the file `Test Packages/examples/AppTest.java` and replace the simple assertion test with, 52 | ``` 53 | examples.Main.main((new String[] {"/test=demo-ast", "/reps=1"})); 54 | ``` 55 | Toggle a break point on the line. To debug right click on the AppTest.java file and select `Debug Test File`. 56 | 57 | There you have it. You are on your way to fully exploring the Java APG, Version 1.1.0 examples. 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/apg/ABNFforSABNF.bnf: -------------------------------------------------------------------------------- 1 | ;******************************************************************** 2 | ; APG - an ABNF Parser Generator 3 | ; Copyright (C) 2011 Lowell D. Thomas, all rights reserved 4 | ; 5 | ; author: Lowell D. Thomas 6 | ; lowell@coasttocoastresearch.com 7 | ; http://www.coasttocoastresearch.com 8 | ; 9 | ; purpose: ABNF for SABNF 10 | ; 11 | ;********************************************************************* 12 | ; symbol alphabet is ASCII 13 | ; code points: 9, 10, 13, 32-126 14 | ; 15 | File = *(BlankLine/Rule/RuleError) 16 | BlankLine = *sp LineEnd 17 | Rule = NameDef owsp (IncAlt/DefinedAs) owsp Alternation owsp LineEnd 18 | RuleError = *fsp LineEnd 19 | Alternation = Concatenation *(AltOp Concatenation) 20 | Concatenation = owsp Repetition *(CatOp Repetition) 21 | Repetition = Repeat / Predicate / Element 22 | Repeat = Rep Element 23 | Predicate = (AndOp / NotOp) Element 24 | Rep = (rep-min StarOp rep-max) / 25 | (rep-min StarOp) / 26 | (StarOp rep-max) / 27 | StarOp / 28 | rep-min-max 29 | Element = TrgOp / 30 | TbsOp / 31 | TlsOp / 32 | TcsOp / 33 | UdtOp / 34 | RnmOp / 35 | Group / 36 | Option / 37 | ProsVal 38 | Group = %d40 owsp Alternation owsp %d41 39 | Option = %d91 owsp Alternation owsp %d93 40 | ProsVal = %d60 *(%d32-61/%d63-127/%d9) %d62 41 | 42 | NameDef = alphanum 43 | DefinedAs = %d61 44 | IncAlt = %d61.47 45 | RnmOp = alphanum 46 | UdtOp = (%d117.95/%d101.95) alphanum 47 | AltOp = owsp %d47 48 | CatOp = wsp 49 | StarOp = %d42 50 | AndOp = %d38 51 | NotOp = %d33 52 | TrgOp = %d37 TrgRange 53 | TbsOp = %d37 TbsString 54 | TlsOp = [ "%i" ] %d34 *(%d32-33/%d35-127/%d9) %d34 55 | TcsOp = %d39 *(%d32-38/%d40-127/%d9) %d39 / "%s" %d34 *(%d32-33/%d35-127/%d9) %d34 56 | 57 | rep-min = 1*(%d48-57) 58 | rep-min-max = 1*(%d48-57) 59 | rep-max = 1*(%d48-57) 60 | TrgRange = (Dec dnum %d45 dnum) / (Hex xnum %d45 xnum) / (Bin bnum %d45 bnum) 61 | TbsString = (Dec dnum *(%d46 dnum)) / (Hex xnum *(%d46 xnum)) / (Bin bnum *(%d46 bnum)) 62 | Dec = (%d68/%d100) 63 | Hex = (%d88/%d120) 64 | Bin = (%d66/%d98) 65 | dnum = 1*(%d48-57) 66 | bnum = 1*%d48-49 67 | xnum = 1*(%d48-57 / %d65-70 / %d97-102) 68 | 69 | ; Basics 70 | alphanum = (%d97-122/%d65-90) *(%d97-122/%d65-90/%d48-57/%d45) 71 | sp = %d32 / 72 | %d9 / 73 | comment 74 | fsp = %d32 / 75 | %d9 / 76 | comment / 77 | LineContinue 78 | owsp = *fsp 79 | wsp = 1*fsp 80 | comment = %d59 *(%d32-127 / %d9) 81 | LineEnd = %d13.10 / %d10 /%d13 82 | LineContinue = LineEnd (%d32/%d9) 83 | -------------------------------------------------------------------------------- /src/apg/package.html: -------------------------------------------------------------------------------- 1 | 2 |

This package contains APG, the parser generator, 3 | and the runtime library required by the generated parsers.

4 |

More package info.

5 | -------------------------------------------------------------------------------- /src/examples/anbn/AnBn.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.anbn; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class AnBn extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new AnBn(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 1; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "AnBn" */ 38 | ANBN("AnBn", 0, 0, 5); 39 | private String name; 40 | private int id; 41 | private int offset; 42 | private int count; 43 | RuleNames(String string, int id, int offset, int count){ 44 | this.name = string; 45 | this.id = id; 46 | this.offset = offset; 47 | this.count = count; 48 | } 49 | /** Associates the enum with the original grammar name of the rule it represents. 50 | * @return the original grammar rule name. */ 51 | public String ruleName(){return name;} 52 | /** Associates the enum with an identifier for the grammar rule it represents. 53 | * @return the rule name identifier. */ 54 | public int ruleID(){return id;} 55 | private int opcodeOffset(){return offset;} 56 | private int opcodeCount(){return count;} 57 | } 58 | 59 | // UDT name enum 60 | /** The number of UDTs in the grammar */ 61 | public static int udtCount = 0; 62 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 63 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 64 | public enum UdtNames{ 65 | } 66 | 67 | // private 68 | private static AnBn factoryInstance = null; 69 | private AnBn(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 70 | super(rules, udts, opcodes); 71 | } 72 | 73 | private static Rule[] getRules(){ 74 | Rule[] rules = new Rule[1]; 75 | for(RuleNames r : RuleNames.values()){ 76 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 77 | } 78 | return rules; 79 | } 80 | 81 | private static Udt[] getUdts(){ 82 | Udt[] udts = new Udt[0]; 83 | return udts; 84 | } 85 | 86 | // opcodes 87 | private static Opcode[] getOpcodes(){ 88 | Opcode[] op = new Opcode[5]; 89 | addOpcodes00(op); 90 | return op; 91 | } 92 | 93 | private static void addOpcodes00(Opcode[] op){ 94 | {int[] a = {1,2,4}; op[0] = getOpcodeCat(a);} 95 | {char[] a = {97}; op[1] = getOpcodeTls(a);} 96 | op[2] = getOpcodeRep((char)0, (char)1, 3); 97 | op[3] = getOpcodeRnm(0, 0); // AnBn 98 | {char[] a = {98}; op[4] = getOpcodeTls(a);} 99 | } 100 | 101 | /** Displays the original SABNF grammar on the output device. 102 | * @param out the output device to display on.*/ 103 | public static void display(PrintStream out){ 104 | out.println(";"); 105 | out.println("; examples.anbn.AnBn"); 106 | out.println(";"); 107 | out.println("AnBn = \"a\" [AnBn] \"b\""); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/examples/anbn/HandwrittenAnBn.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.anbn; 10 | 11 | import apg.Parser; 12 | import apg.Parser.UdtCallback; 13 | 14 | class HandwrittenAnBn extends UdtCallback { 15 | 16 | HandwrittenAnBn(Parser p) { 17 | super(p); 18 | } 19 | 20 | @Override 21 | public int callback(int offset) { 22 | int as = 0; 23 | int bs = 0; 24 | int i; 25 | for (i = offset; i < callbackData.inputString.length; i++) { 26 | if (callbackData.inputString[i] == 'a') { 27 | as++; 28 | } else { 29 | break; 30 | } 31 | } 32 | for (; i < callbackData.inputString.length; i++) { 33 | if (callbackData.inputString[i] == 'b') { 34 | bs++; 35 | } else { 36 | break; 37 | } 38 | } 39 | if (as == 0 || as != bs) { 40 | return -1; 41 | } else { 42 | return as + bs; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/examples/anbn/RunAnBn.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.anbn; 10 | 11 | import apg.Parser; 12 | import examples.RunTests; 13 | 14 | import java.io.PrintStream; 15 | 16 | /** 17 | * Uses the grammar for the strings anbn, n > 0, for a 18 | * comparison of timing and node hits between the normal CFG grammar and the use 19 | * of UDT functions. 20 | */ 21 | public class RunAnBn extends RunTests { 22 | 23 | /** 24 | * Constructor for the test. Parameters are supplied explicitly or by 25 | * default from the command line to the driver function. 26 | * 27 | * @param testName the name of the test 28 | * @param reps the number of repetitions of the parser 29 | * @param out the output device 30 | */ 31 | public RunAnBn(String testName, int reps, PrintStream out) { 32 | super(testName, reps, out); 33 | } 34 | 35 | @Override 36 | protected void run() throws Exception { 37 | setupForCompare(); 38 | runComparisionOfCfgAndUdt(); 39 | } 40 | 41 | // Sets up the parser, input strings, CFG and UDT grammars for the 42 | // time and node statistics comparisons. 43 | private void setupForCompare() throws Exception { 44 | // display the title and an abstract 45 | if (testName != null) { 46 | outputTestName(); 47 | } else { 48 | throw new Exception("testName may not be null"); 49 | } 50 | outputAbstract("CFG/UDT time & statistics comparison for the a^nb^n grammar"); 51 | out.println(); 52 | 53 | // display the grammars 54 | outputCfgGrammar(); 55 | AnBn.display(out); 56 | out.println(); 57 | outputUdtGrammar(); 58 | UAnBn.display(out); 59 | out.println(); 60 | 61 | // set up input strings 62 | inputStringCount = 10; 63 | inputStrings = new String[inputStringCount]; 64 | inputStrings[0] = "ab"; 65 | inputStrings[1] = "aabb"; 66 | inputStrings[2] = "aaabbb"; 67 | inputStrings[3] = "aaaabbbb"; 68 | inputStrings[4] = "aaaaabbbbb"; 69 | inputStrings[5] = "aaaaaabbbbbb"; 70 | inputStrings[6] = "aaaaaaabbbbbbb"; 71 | inputStrings[7] = "aaaaaaaabbbbbbbb"; 72 | inputStrings[8] = "aaaaaaaaabbbbbbbbb"; 73 | inputStrings[9] = "aaaaaaaaaabbbbbbbbbb"; 74 | 75 | // CFG grammar-dependent setup 76 | int startRule = AnBn.RuleNames.ANBN.ruleID(); // grammar.RuleNames.RULE.ruldID(); 77 | cfgIn = new RunInput("cfg", new Parser(AnBn.getInstance()), startRule); 78 | 79 | // UDT grammar-dependent setup 80 | Parser parser = new Parser(UAnBn.getInstance()); 81 | startRule = UAnBn.RuleNames.ANBN.ruleID(); 82 | parser.setUdtCallback(UAnBn.UdtNames.U_ANBN.udtID(), new HandwrittenAnBn(parser)); 83 | udtIn = new RunInput("udt", parser, startRule); 84 | } 85 | } 86 | //private void runDemo() throws Exception{ 87 | //// print the test title and an abstract of what it does 88 | //title = "*** Title: "+testName; 89 | //out.println(title); 90 | //out.println("*** Abstract: Using the a^nb^n grammar, " + 91 | // "to demonstrate how to write and use AST callback functions."); 92 | // 93 | //// display the grammars 94 | //out.println("*** Display the grammars used."); 95 | //out.println("\nthe AnBn CFG grammar:"); 96 | //AnBn.display(out); 97 | //out.println("\nthe AnBn UDT grammar:"); 98 | //UAnBn.display(out); 99 | //out.println(); 100 | // 101 | //// get the UDT parser 102 | //Parser parser = new Parser(UAnBn.getInstance()); 103 | // 104 | //// set up & display the input string 105 | //inputStringCount = 1; 106 | //inputStrings = new String[1]; 107 | //inputStrings[0] = "aaabbb"; 108 | //out.println("*** Display the input string used."); 109 | //out.print("input string: \""); 110 | //out.print(Utilities.charArrayToXml(inputStrings[0].toCharArray(), 111 | // 0, inputStrings[0].length())); 112 | //out.println("\""); 113 | // 114 | //// set the parser's input string 115 | //parser.setInputString(inputStrings[0]); 116 | // 117 | //// set the parser's start rule 118 | //int startRule = AnBn.RuleNames.ANBN.ruleID(); 119 | //parser.setStartRule(startRule); 120 | // 121 | //// set the parser's UDT callback function 122 | //parser.setUdtCallback(UAnBn.UdtNames.U_ANBN.udtID(), new HandwrittenAnBn(parser)); 123 | // 124 | //// set up the parser to generate an AST 125 | //Ast ast = parser.enableAst(true); 126 | // 127 | //// tell the AST which rule/UDT nodes to keep on the tree 128 | //ast.enableRuleNode(startRule, true); 129 | //ast.enableUdtNode(UAnBn.UdtNames.U_ANBN.udtID(), true); 130 | // 131 | //// parse the input string 132 | //Result result = parser.parse(); 133 | //if(result.success()){ 134 | // // the parse succeeded: display the AST in native format 135 | // out.println(); 136 | // out.println("*** Display the AST in native APG format."); 137 | // ast.display(out); 138 | // 139 | // // display the AST in XML format 140 | // out.println(); 141 | // out.println("*** Display the AST in XML format."); 142 | // ast.display(out, true); 143 | //} else{ 144 | // // the parse failed: re-parse with a default trace enabled 145 | // Trace trace = parser.enableTrace(true); 146 | // 147 | // // display the trace in native format 148 | // out.println(); 149 | // out.println("*** The parser failed."); 150 | // out.println("*** Display the trace in native APG format."); 151 | // parser.parse(); 152 | // 153 | // // display the trace in XML format 154 | // out.println(); 155 | // out.println("*** Display the trace in XML format."); 156 | // trace.enableXml(true); 157 | // parser.parse(); 158 | //} 159 | //} 160 | -------------------------------------------------------------------------------- /src/examples/anbn/UAnBn.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.anbn; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class UAnBn extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new UAnBn(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 1; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "AnBn" */ 38 | ANBN("AnBn", 0, 0, 1); 39 | private String name; 40 | private int id; 41 | private int offset; 42 | private int count; 43 | RuleNames(String string, int id, int offset, int count){ 44 | this.name = string; 45 | this.id = id; 46 | this.offset = offset; 47 | this.count = count; 48 | } 49 | /** Associates the enum with the original grammar name of the rule it represents. 50 | * @return the original grammar rule name. */ 51 | public String ruleName(){return name;} 52 | /** Associates the enum with an identifier for the grammar rule it represents. 53 | * @return the rule name identifier. */ 54 | public int ruleID(){return id;} 55 | private int opcodeOffset(){return offset;} 56 | private int opcodeCount(){return count;} 57 | } 58 | 59 | // UDT name enum 60 | /** The number of UDTs in the grammar */ 61 | public static int udtCount = 1; 62 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 63 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 64 | public enum UdtNames{ 65 | /** id = 0, name = "u_anbn" */ 66 | U_ANBN(0, "u_anbn", false); 67 | private String name; 68 | private int id; 69 | private boolean empty; 70 | UdtNames(int id, String string, boolean empty){ 71 | this.name = string; 72 | this.id = id; 73 | this.empty = empty; 74 | } 75 | /** Associates the enum with the original grammar name of the UDT it represents. 76 | * @return the original grammar UDT name. */ 77 | public String udtName(){return name;} 78 | /** Associates the enum with an identifier for the UDT it represents. 79 | * @return the UDT identifier. */ 80 | public int udtID(){return id;} 81 | /** Associates the enum with the "empty" attribute of the UDT it represents. 82 | * @return the "empty" attribute. 83 | * True if the UDT name begins with "e_", false if it begins with "u_". */ 84 | public boolean udtMayBeEmpty(){return empty;} 85 | } 86 | 87 | // private 88 | private static UAnBn factoryInstance = null; 89 | private UAnBn(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 90 | super(rules, udts, opcodes); 91 | } 92 | 93 | private static Rule[] getRules(){ 94 | Rule[] rules = new Rule[1]; 95 | for(RuleNames r : RuleNames.values()){ 96 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 97 | } 98 | return rules; 99 | } 100 | 101 | private static Udt[] getUdts(){ 102 | Udt[] udts = new Udt[1]; 103 | for(UdtNames r : UdtNames.values()){ 104 | udts[r.udtID()] = getUdt(r.udtID(), r.udtName(), r.udtMayBeEmpty()); 105 | } 106 | return udts; 107 | } 108 | 109 | // opcodes 110 | private static Opcode[] getOpcodes(){ 111 | Opcode[] op = new Opcode[1]; 112 | addOpcodes00(op); 113 | return op; 114 | } 115 | 116 | private static void addOpcodes00(Opcode[] op){ 117 | op[0] = getOpcodeUdt(0); // u_anbn 118 | } 119 | 120 | /** Displays the original SABNF grammar on the output device. 121 | * @param out the output device to display on.*/ 122 | public static void display(PrintStream out){ 123 | out.println(";"); 124 | out.println("; examples.anbn.UAnBn"); 125 | out.println(";"); 126 | out.println("AnBn = u_anbn"); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/examples/anbn/anbn.bnf: -------------------------------------------------------------------------------- 1 | AnBn = "a" [AnBn] "b" 2 | 3 | -------------------------------------------------------------------------------- /src/examples/anbn/input.txt: -------------------------------------------------------------------------------- 1 | aaaaaaaaaabbbbbbbbbb 2 | -------------------------------------------------------------------------------- /src/examples/anbn/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A comparison of timing and node hit statistics between 4 | the CFG and UDT parsers for 5 | the anbn, n > 0, grammar. 6 |

7 | 8 | Disclaimer: This example should not be considered as part of the Java APG API. Backward compatibility or even the existance of this example from version to version is not guaranteed. 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/examples/anbn/uanbn.bnf: -------------------------------------------------------------------------------- 1 | AnBn = u_anbn 2 | 3 | -------------------------------------------------------------------------------- /src/examples/anbncn/AnBnCn.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.anbncn; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class AnBnCn extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new AnBnCn(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 8; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 5, name = "A" */ 38 | A("A", 5, 20, 1), 39 | /** id = 3, name = "AnBn" */ 40 | ANBN("AnBn", 3, 10, 5), 41 | /** id = 0, name = "AnBnCn" */ 42 | ANBNCN("AnBnCn", 0, 0, 5), 43 | /** id = 6, name = "B" */ 44 | B("B", 6, 21, 1), 45 | /** id = 4, name = "BnCn" */ 46 | BNCN("BnCn", 4, 15, 5), 47 | /** id = 7, name = "C" */ 48 | C("C", 7, 22, 1), 49 | /** id = 2, name = "ConsumeAs" */ 50 | CONSUMEAS("ConsumeAs", 2, 8, 2), 51 | /** id = 1, name = "Prefix" */ 52 | PREFIX("Prefix", 1, 5, 3); 53 | private String name; 54 | private int id; 55 | private int offset; 56 | private int count; 57 | RuleNames(String string, int id, int offset, int count){ 58 | this.name = string; 59 | this.id = id; 60 | this.offset = offset; 61 | this.count = count; 62 | } 63 | /** Associates the enum with the original grammar name of the rule it represents. 64 | * @return the original grammar rule name. */ 65 | public String ruleName(){return name;} 66 | /** Associates the enum with an identifier for the grammar rule it represents. 67 | * @return the rule name identifier. */ 68 | public int ruleID(){return id;} 69 | private int opcodeOffset(){return offset;} 70 | private int opcodeCount(){return count;} 71 | } 72 | 73 | // UDT name enum 74 | /** The number of UDTs in the grammar */ 75 | public static int udtCount = 0; 76 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 77 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 78 | public enum UdtNames{ 79 | } 80 | 81 | // private 82 | private static AnBnCn factoryInstance = null; 83 | private AnBnCn(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 84 | super(rules, udts, opcodes); 85 | } 86 | 87 | private static Rule[] getRules(){ 88 | Rule[] rules = new Rule[8]; 89 | for(RuleNames r : RuleNames.values()){ 90 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 91 | } 92 | return rules; 93 | } 94 | 95 | private static Udt[] getUdts(){ 96 | Udt[] udts = new Udt[0]; 97 | return udts; 98 | } 99 | 100 | // opcodes 101 | private static Opcode[] getOpcodes(){ 102 | Opcode[] op = new Opcode[23]; 103 | addOpcodes00(op); 104 | return op; 105 | } 106 | 107 | private static void addOpcodes00(Opcode[] op){ 108 | {int[] a = {1,3,4}; op[0] = getOpcodeCat(a);} 109 | op[1] = getOpcodeAnd(2); 110 | op[2] = getOpcodeRnm(1, 5); // Prefix 111 | op[3] = getOpcodeRnm(2, 8); // ConsumeAs 112 | op[4] = getOpcodeRnm(4, 15); // BnCn 113 | {int[] a = {6,7}; op[5] = getOpcodeCat(a);} 114 | op[6] = getOpcodeRnm(3, 10); // AnBn 115 | op[7] = getOpcodeRnm(7, 22); // C 116 | op[8] = getOpcodeRep((char)0, Character.MAX_VALUE, 9); 117 | op[9] = getOpcodeRnm(5, 20); // A 118 | {int[] a = {11,12,14}; op[10] = getOpcodeCat(a);} 119 | op[11] = getOpcodeRnm(5, 20); // A 120 | op[12] = getOpcodeRep((char)0, (char)1, 13); 121 | op[13] = getOpcodeRnm(3, 10); // AnBn 122 | op[14] = getOpcodeRnm(6, 21); // B 123 | {int[] a = {16,17,19}; op[15] = getOpcodeCat(a);} 124 | op[16] = getOpcodeRnm(6, 21); // B 125 | op[17] = getOpcodeRep((char)0, (char)1, 18); 126 | op[18] = getOpcodeRnm(4, 15); // BnCn 127 | op[19] = getOpcodeRnm(7, 22); // C 128 | {char[] a = {97}; op[20] = getOpcodeTbs(a);} 129 | {char[] a = {98}; op[21] = getOpcodeTbs(a);} 130 | {char[] a = {99}; op[22] = getOpcodeTbs(a);} 131 | } 132 | 133 | /** Displays the original SABNF grammar on the output device. 134 | * @param out the output device to display on.*/ 135 | public static void display(PrintStream out){ 136 | out.println(";"); 137 | out.println("; examples.anbncn.AnBnCn"); 138 | out.println(";"); 139 | out.println("AnBnCn = &Prefix ConsumeAs BnCn"); 140 | out.println("Prefix = AnBn C"); 141 | out.println("ConsumeAs = *A"); 142 | out.println("AnBn = A [AnBn] B"); 143 | out.println("BnCn = B [BnCn] C"); 144 | out.println("A = %d97"); 145 | out.println("B = %d98"); 146 | out.println("C = %d99"); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/examples/anbncn/HandwrittenAnBnCn.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.anbncn; 10 | 11 | import apg.Parser; 12 | import apg.Parser.UdtCallback; 13 | 14 | class HandwrittenAnBnCn extends UdtCallback { 15 | 16 | HandwrittenAnBnCn(Parser p) { 17 | super(p); 18 | } 19 | 20 | @Override 21 | public int callback(int offset) { 22 | int as = 0; 23 | int bs = 0; 24 | int cs = 0; 25 | int i; 26 | for (i = offset; i < callbackData.inputString.length; i++) { 27 | if (callbackData.inputString[i] == 'a') { 28 | as++; 29 | } else { 30 | break; 31 | } 32 | } 33 | for (; i < callbackData.inputString.length; i++) { 34 | if (callbackData.inputString[i] == 'b') { 35 | bs++; 36 | } else { 37 | break; 38 | } 39 | } 40 | for (; i < callbackData.inputString.length; i++) { 41 | if (callbackData.inputString[i] == 'c') { 42 | cs++; 43 | } else { 44 | break; 45 | } 46 | } 47 | if (as == 0 || as != bs || as != cs) { 48 | return -1; 49 | } else { 50 | return as + bs + cs; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/examples/anbncn/RunAnBnCn.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.anbncn; 10 | 11 | import java.io.PrintStream; 12 | 13 | import apg.Parser; 14 | import examples.RunTests; 15 | 16 | /** 17 | * Uses the grammar for the strings anbncn, n 18 | * > 0, for a comparison of timing and node hits between the normal CFG 19 | * grammar and the use of UDT functions. 20 | */ 21 | public class RunAnBnCn extends RunTests { 22 | 23 | /** 24 | * Constructor for the test. Parameters are supplied explicitly or by 25 | * default from the command line to the driver function. 26 | * 27 | * @param testName the name of the test 28 | * @param reps the number of repetitions of the parser 29 | * @param out the output device 30 | */ 31 | public RunAnBnCn(String testName, int reps, PrintStream out) { 32 | super(testName, reps, out); 33 | } 34 | 35 | @Override 36 | protected void run() throws Exception { 37 | setup(); 38 | runComparisionOfCfgAndUdt(); 39 | } 40 | 41 | void setup() throws Exception { 42 | // display the title and an abstract 43 | if (testName != null) { 44 | outputTestName(); 45 | } else { 46 | throw new Exception("testName may not be null"); 47 | } 48 | outputAbstract("CFG/UDT time & statistics comparison for the a^nb^nc^n grammar"); 49 | out.println(); 50 | 51 | // display the grammars 52 | outputCfgGrammar(); 53 | AnBnCn.display(out); 54 | out.println(); 55 | outputUdtGrammar(); 56 | UAnBnCn.display(out); 57 | out.println(); 58 | 59 | // set up input strings 60 | if (inputStrings == null 61 | || inputStrings.length == 0 62 | || inputStrings[0] == null 63 | || inputStrings[0].length() == 0) { 64 | inputStringCount = 10; 65 | inputStrings = new String[inputStringCount]; 66 | inputStrings[0] = "abc"; 67 | inputStrings[1] = "aabbcc"; 68 | inputStrings[2] = "aaabbbccc"; 69 | inputStrings[3] = "aaaabbbbcccc"; 70 | inputStrings[4] = "aaaaabbbbbccccc"; 71 | inputStrings[5] = "aaaaaabbbbbbcccccc"; 72 | inputStrings[6] = "aaaaaaabbbbbbbccccccc"; 73 | inputStrings[7] = "aaaaaaaabbbbbbbbcccccccc"; 74 | inputStrings[8] = "aaaaaaaaabbbbbbbbbccccccccc"; 75 | inputStrings[9] = "aaaaaaaaaabbbbbbbbbbcccccccccc"; 76 | } 77 | 78 | // CFG grammar-dependent setup 79 | int startRule = AnBnCn.RuleNames.ANBNCN.ruleID(); // grammar.RuleNames.RULE.ruldID(); 80 | cfgIn = new RunInput("cfg", new Parser(AnBnCn.getInstance()), startRule); 81 | 82 | // UDT setup 83 | Parser parser = new Parser(UAnBnCn.getInstance()); 84 | startRule = UAnBnCn.RuleNames.ANBNCN.ruleID(); 85 | parser.setUdtCallback(UAnBnCn.UdtNames.U_ANBNCN.udtID(), new HandwrittenAnBnCn(parser)); 86 | udtIn = new RunInput("udt", parser, startRule); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/examples/anbncn/UAnBnCn.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.anbncn; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class UAnBnCn extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new UAnBnCn(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 1; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "AnBnCn" */ 38 | ANBNCN("AnBnCn", 0, 0, 1); 39 | private String name; 40 | private int id; 41 | private int offset; 42 | private int count; 43 | RuleNames(String string, int id, int offset, int count){ 44 | this.name = string; 45 | this.id = id; 46 | this.offset = offset; 47 | this.count = count; 48 | } 49 | /** Associates the enum with the original grammar name of the rule it represents. 50 | * @return the original grammar rule name. */ 51 | public String ruleName(){return name;} 52 | /** Associates the enum with an identifier for the grammar rule it represents. 53 | * @return the rule name identifier. */ 54 | public int ruleID(){return id;} 55 | private int opcodeOffset(){return offset;} 56 | private int opcodeCount(){return count;} 57 | } 58 | 59 | // UDT name enum 60 | /** The number of UDTs in the grammar */ 61 | public static int udtCount = 1; 62 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 63 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 64 | public enum UdtNames{ 65 | /** id = 0, name = "u_anbncn" */ 66 | U_ANBNCN(0, "u_anbncn", false); 67 | private String name; 68 | private int id; 69 | private boolean empty; 70 | UdtNames(int id, String string, boolean empty){ 71 | this.name = string; 72 | this.id = id; 73 | this.empty = empty; 74 | } 75 | /** Associates the enum with the original grammar name of the UDT it represents. 76 | * @return the original grammar UDT name. */ 77 | public String udtName(){return name;} 78 | /** Associates the enum with an identifier for the UDT it represents. 79 | * @return the UDT identifier. */ 80 | public int udtID(){return id;} 81 | /** Associates the enum with the "empty" attribute of the UDT it represents. 82 | * @return the "empty" attribute. 83 | * True if the UDT name begins with "e_", false if it begins with "u_". */ 84 | public boolean udtMayBeEmpty(){return empty;} 85 | } 86 | 87 | // private 88 | private static UAnBnCn factoryInstance = null; 89 | private UAnBnCn(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 90 | super(rules, udts, opcodes); 91 | } 92 | 93 | private static Rule[] getRules(){ 94 | Rule[] rules = new Rule[1]; 95 | for(RuleNames r : RuleNames.values()){ 96 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 97 | } 98 | return rules; 99 | } 100 | 101 | private static Udt[] getUdts(){ 102 | Udt[] udts = new Udt[1]; 103 | for(UdtNames r : UdtNames.values()){ 104 | udts[r.udtID()] = getUdt(r.udtID(), r.udtName(), r.udtMayBeEmpty()); 105 | } 106 | return udts; 107 | } 108 | 109 | // opcodes 110 | private static Opcode[] getOpcodes(){ 111 | Opcode[] op = new Opcode[1]; 112 | addOpcodes00(op); 113 | return op; 114 | } 115 | 116 | private static void addOpcodes00(Opcode[] op){ 117 | op[0] = getOpcodeUdt(0); // u_anbncn 118 | } 119 | 120 | /** Displays the original SABNF grammar on the output device. 121 | * @param out the output device to display on.*/ 122 | public static void display(PrintStream out){ 123 | out.println(";"); 124 | out.println("; examples.anbncn.UAnBnCn"); 125 | out.println(";"); 126 | out.println("AnBnCn = u_anbncn"); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/examples/anbncn/anbncn.bnf: -------------------------------------------------------------------------------- 1 | AnBnCn = &Prefix ConsumeAs BnCn 2 | Prefix = AnBn C 3 | ConsumeAs = *A 4 | AnBn = A [AnBn] B 5 | BnCn = B [BnCn] C 6 | A = %d97 7 | B = %d98 8 | C = %d99 9 | -------------------------------------------------------------------------------- /src/examples/anbncn/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A comparison of timing and node hit statistics between 4 | the CFG and UDT parsers for 5 | the anbncn, n > 0, grammar.

6 | 7 | Disclaimer: This example should not be considered as part of the Java APG API. Backward compatibility or even the existance of this example from version to version is not guaranteed. 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/examples/anbncn/uanbncn.bnf: -------------------------------------------------------------------------------- 1 | AnBnCn = u_anbncn 2 | 3 | -------------------------------------------------------------------------------- /src/examples/demo/DisplayAst.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.demo; 10 | 11 | import java.io.PrintStream; 12 | import apg.Ast; 13 | import apg.Parser; 14 | import apg.Parser.Result; 15 | import apg.Trace; 16 | import apg.UdtLib; 17 | import apg.Utilities; 18 | import examples.RunTests; 19 | 20 | /** 21 | * A simple demonstration of how to generate and display an Abstract Syntax Tree 22 | * (AST). The source code should be consulted for details. 23 | */ 24 | public class DisplayAst extends RunTests { 25 | 26 | /** 27 | * Constructor for the test. Parameters are supplied explicitly or by 28 | * default from the command line to the driver function. 29 | * 30 | * @param testName the name of the test 31 | * @param out the output device 32 | */ 33 | public DisplayAst(String testName, PrintStream out) { 34 | super(testName, out); 35 | } 36 | 37 | @Override 38 | protected void run() throws Exception { 39 | // display the title and an abstract 40 | if (testName != null) { 41 | outputTestName(); 42 | } else { 43 | throw new Exception("testName may not be null"); 44 | } 45 | outputAbstract("Use the Expressions grammar to " 46 | + "demonstrate the generation and display the AST."); 47 | out.println(); 48 | 49 | // display the grammars 50 | outputCfgGrammar(); 51 | Expressions.display(out); 52 | out.println(); 53 | outputUdtGrammar(); 54 | UExpressions.display(out); 55 | out.println(); 56 | 57 | // display the input string 58 | String inputString = "(a+b)*(c+(d+e*(topA+topB)))"; 59 | out.println("INPUT STRING: (" + testName + ")"); 60 | out.println(Utilities.charArrayToXml(inputString.toCharArray(), 0, inputString.length())); 61 | out.println(); 62 | 63 | // create a parser from the UDT grammar 64 | Parser parser = new Parser(UExpressions.getInstance()); 65 | 66 | // tell the parser what the start rule is 67 | parser.setStartRule(UExpressions.RuleNames.E.ruleID()); 68 | 69 | // tell the parser what the input string is 70 | parser.setInputString(inputString); 71 | 72 | // tell the parser to use Alphanum from UdtLib as the "u_id" UDT function 73 | UdtLib.Alphanum idCallback = new UdtLib.Alphanum(parser); 74 | parser.setUdtCallback(UExpressions.UdtNames.U_ID.udtID(), idCallback); 75 | 76 | // tell the parser to generate an AST 77 | Ast ast = parser.enableAst(true); 78 | 79 | // tell the AST which rule name nodes to keep 80 | ast.enableRuleNode(UExpressions.RuleNames.E.ruleID(), true); 81 | ast.enableRuleNode(UExpressions.RuleNames.T.ruleID(), true); 82 | ast.enableRuleNode(UExpressions.RuleNames.F.ruleID(), true); 83 | ast.enableRuleNode(UExpressions.RuleNames.EPRIME.ruleID(), true); 84 | ast.enableRuleNode(UExpressions.RuleNames.TPRIME.ruleID(), true); 85 | 86 | // tell the AST which UDT nodes to keep 87 | ast.enableUdtNode(UExpressions.UdtNames.U_ID.udtID(), true); 88 | 89 | // parse the input string 90 | Result result = parser.parse(); 91 | 92 | // handle the parser result 93 | if (result.success()) { 94 | // display the AST in APG format 95 | outputAst(false); 96 | ast.display(out); 97 | 98 | // display the AST in XML format 99 | out.println(); 100 | outputAst(true); 101 | ast.display(out, true); 102 | out.println(); 103 | } else { 104 | Trace trace = parser.enableTrace(true); 105 | trace.setOut(out); 106 | 107 | // display the trace in APG format 108 | outputTrace(false); 109 | parser.parse(); 110 | out.println(); 111 | 112 | // display the trace in XML format 113 | outputTrace(true); 114 | trace.enableXml(true); 115 | parser.parse(); 116 | out.println(); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/examples/demo/DisplayTrace.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.demo; 10 | 11 | import java.io.PrintStream; 12 | import apg.Ast; 13 | import apg.Parser; 14 | import apg.Parser.Result; 15 | import apg.Trace; 16 | import apg.UdtLib; 17 | import apg.Utilities; 18 | import examples.RunTests; 19 | 20 | /** 21 | * A simple demonstration of how to display the trace of the parser's path 22 | * through the syntax tree. The source code should be consulted for details. 23 | */ 24 | public class DisplayTrace extends RunTests { 25 | 26 | /** 27 | * Constructor for the test. Parameters are supplied explicitly or by 28 | * default from the command line to the driver function. 29 | * 30 | * @param testName the name of the test 31 | * @param out the output device 32 | */ 33 | public DisplayTrace(String testName, PrintStream out) { 34 | super(testName, out); 35 | } 36 | 37 | @Override 38 | protected void run() throws Exception { 39 | // display the title and an abstract 40 | if (testName != null) { 41 | outputTestName(); 42 | } else { 43 | throw new Exception("testName may not be null"); 44 | } 45 | outputAbstract("Use the Expressions grammar to " 46 | + "demonstrate the trace display."); 47 | out.println(" : Can you find where u_id fails because the identifier" 48 | + " is not alphanumeric?"); 49 | out.println(); 50 | 51 | // display the grammars 52 | outputCfgGrammar(); 53 | Expressions.display(out); 54 | out.println(); 55 | outputUdtGrammar(); 56 | UExpressions.display(out); 57 | out.println(); 58 | 59 | // display the input string 60 | String inputString = "(a+b)*(c+(d+e*(topA+#@!^)))"; 61 | out.println("INPUT STRING: (" + testName + ")"); 62 | out.println(Utilities.charArrayToXml(inputString.toCharArray(), 0, inputString.length())); 63 | out.println(); 64 | 65 | // create a parser from the UDT grammar 66 | Parser parser = new Parser(UExpressions.getInstance()); 67 | 68 | // tell the parser what the start rule is 69 | parser.setStartRule(UExpressions.RuleNames.E.ruleID()); 70 | 71 | // tell the parser what the input string is 72 | parser.setInputString(inputString); 73 | 74 | // tell the parser to use Alphanum from UdtLib as the "u_id" UDT function 75 | UdtLib.Alphanum idCallback = new UdtLib.Alphanum(parser); 76 | parser.setUdtCallback(UExpressions.UdtNames.U_ID.udtID(), idCallback); 77 | 78 | // tell the parser to generate an AST 79 | Ast ast = parser.enableAst(true); 80 | 81 | // tell the AST which rule name nodes to keep 82 | ast.enableRuleNode(UExpressions.RuleNames.E.ruleID(), true); 83 | ast.enableRuleNode(UExpressions.RuleNames.T.ruleID(), true); 84 | ast.enableRuleNode(UExpressions.RuleNames.F.ruleID(), true); 85 | ast.enableRuleNode(UExpressions.RuleNames.EPRIME.ruleID(), true); 86 | ast.enableRuleNode(UExpressions.RuleNames.TPRIME.ruleID(), true); 87 | 88 | // tell the AST which UDT nodes to keep 89 | ast.enableUdtNode(UExpressions.UdtNames.U_ID.udtID(), true); 90 | 91 | // parse the input string 92 | Result result = parser.parse(); 93 | 94 | // handle the parser result 95 | if (result.success()) { 96 | // display the AST in APG format 97 | outputAst(false); 98 | ast.display(out); 99 | out.println(); 100 | 101 | // display the AST in XML format 102 | outputAst(true); 103 | ast.display(out, true); 104 | out.println(); 105 | } else { 106 | Trace trace = parser.enableTrace(true); 107 | trace.setOut(out); 108 | 109 | // display the trace in APG format 110 | outputTrace(false); 111 | parser.parse(); 112 | out.println(); 113 | 114 | // display the trace in XML format 115 | outputTrace(true); 116 | trace.enableXml(true); 117 | parser.parse(); 118 | out.println(); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/examples/demo/Expressions.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.demo; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class Expressions extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new Expressions(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 8; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 6, name = "alpha" */ 38 | ALPHA("alpha", 6, 30, 3), 39 | /** id = 7, name = "digit" */ 40 | DIGIT("digit", 7, 33, 1), 41 | /** id = 0, name = "E" */ 42 | E("E", 0, 0, 3), 43 | /** id = 1, name = "Eprime" */ 44 | EPRIME("Eprime", 1, 3, 6), 45 | /** id = 4, name = "F" */ 46 | F("F", 4, 18, 6), 47 | /** id = 5, name = "id" */ 48 | ID("id", 5, 24, 6), 49 | /** id = 2, name = "T" */ 50 | T("T", 2, 9, 3), 51 | /** id = 3, name = "Tprime" */ 52 | TPRIME("Tprime", 3, 12, 6); 53 | private String name; 54 | private int id; 55 | private int offset; 56 | private int count; 57 | RuleNames(String string, int id, int offset, int count){ 58 | this.name = string; 59 | this.id = id; 60 | this.offset = offset; 61 | this.count = count; 62 | } 63 | /** Associates the enum with the original grammar name of the rule it represents. 64 | * @return the original grammar rule name. */ 65 | public String ruleName(){return name;} 66 | /** Associates the enum with an identifier for the grammar rule it represents. 67 | * @return the rule name identifier. */ 68 | public int ruleID(){return id;} 69 | private int opcodeOffset(){return offset;} 70 | private int opcodeCount(){return count;} 71 | } 72 | 73 | // UDT name enum 74 | /** The number of UDTs in the grammar */ 75 | public static int udtCount = 0; 76 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 77 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 78 | public enum UdtNames{ 79 | } 80 | 81 | // private 82 | private static Expressions factoryInstance = null; 83 | private Expressions(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 84 | super(rules, udts, opcodes); 85 | } 86 | 87 | private static Rule[] getRules(){ 88 | Rule[] rules = new Rule[8]; 89 | for(RuleNames r : RuleNames.values()){ 90 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 91 | } 92 | return rules; 93 | } 94 | 95 | private static Udt[] getUdts(){ 96 | Udt[] udts = new Udt[0]; 97 | return udts; 98 | } 99 | 100 | // opcodes 101 | private static Opcode[] getOpcodes(){ 102 | Opcode[] op = new Opcode[34]; 103 | addOpcodes00(op); 104 | return op; 105 | } 106 | 107 | private static void addOpcodes00(Opcode[] op){ 108 | {int[] a = {1,2}; op[0] = getOpcodeCat(a);} 109 | op[1] = getOpcodeRnm(2, 9); // T 110 | op[2] = getOpcodeRnm(1, 3); // Eprime 111 | {int[] a = {4,8}; op[3] = getOpcodeAlt(a);} 112 | {int[] a = {5,6,7}; op[4] = getOpcodeCat(a);} 113 | {char[] a = {43}; op[5] = getOpcodeTls(a);} 114 | op[6] = getOpcodeRnm(2, 9); // T 115 | op[7] = getOpcodeRnm(1, 3); // Eprime 116 | {char[] a = {}; op[8] = getOpcodeTls(a);} 117 | {int[] a = {10,11}; op[9] = getOpcodeCat(a);} 118 | op[10] = getOpcodeRnm(4, 18); // F 119 | op[11] = getOpcodeRnm(3, 12); // Tprime 120 | {int[] a = {13,17}; op[12] = getOpcodeAlt(a);} 121 | {int[] a = {14,15,16}; op[13] = getOpcodeCat(a);} 122 | {char[] a = {42}; op[14] = getOpcodeTls(a);} 123 | op[15] = getOpcodeRnm(4, 18); // F 124 | op[16] = getOpcodeRnm(3, 12); // Tprime 125 | {char[] a = {}; op[17] = getOpcodeTls(a);} 126 | {int[] a = {19,23}; op[18] = getOpcodeAlt(a);} 127 | {int[] a = {20,21,22}; op[19] = getOpcodeCat(a);} 128 | {char[] a = {40}; op[20] = getOpcodeTls(a);} 129 | op[21] = getOpcodeRnm(0, 0); // E 130 | {char[] a = {41}; op[22] = getOpcodeTls(a);} 131 | op[23] = getOpcodeRnm(5, 24); // id 132 | {int[] a = {25,26}; op[24] = getOpcodeCat(a);} 133 | op[25] = getOpcodeRnm(6, 30); // alpha 134 | op[26] = getOpcodeRep((char)0, Character.MAX_VALUE, 27); 135 | {int[] a = {28,29}; op[27] = getOpcodeAlt(a);} 136 | op[28] = getOpcodeRnm(6, 30); // alpha 137 | op[29] = getOpcodeRnm(7, 33); // digit 138 | {int[] a = {31,32}; op[30] = getOpcodeAlt(a);} 139 | op[31] = getOpcodeTrg((char)65, (char)90); 140 | op[32] = getOpcodeTrg((char)97, (char)122); 141 | op[33] = getOpcodeTrg((char)48, (char)57); 142 | } 143 | 144 | /** Displays the original SABNF grammar on the output device. 145 | * @param out the output device to display on.*/ 146 | public static void display(PrintStream out){ 147 | out.println(";"); 148 | out.println("; examples.demo.Expressions"); 149 | out.println(";"); 150 | out.println(";"); 151 | out.println("; ABNF version of grammar (4.2)"); 152 | out.println("; Aho, Lam, Sethi and Ullman, \"Compilers: Principles, Techniques, & Tools\","); 153 | out.println("; 2nd ed., pp. 193, Addison Wesley, (2007)"); 154 | out.println(";"); 155 | out.println("E = T Eprime ; expression = sum of terms"); 156 | out.println("Eprime = \"+\" T Eprime / \"\""); 157 | out.println("T = F Tprime ; term = product of factors"); 158 | out.println("Tprime = \"*\" F Tprime / \"\""); 159 | out.println("F = \"(\" E \")\" / id ; factor = parenthesized expression or identifier"); 160 | out.println("id = alpha *(alpha / digit) ; id = alphanumeric name"); 161 | out.println("alpha = %d65-90 / %d97-122 ; upper or lower case letters"); 162 | out.println("digit = %d48-57 ; digits 0-9"); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /src/examples/demo/Hostname.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.demo; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class Hostname extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new Hostname(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 7; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 4, name = "ALPHA" */ 38 | ALPHA("ALPHA", 4, 33, 3), 39 | /** id = 5, name = "alphanum" */ 40 | ALPHANUM("alphanum", 5, 36, 4), 41 | /** id = 0, name = "context" */ 42 | CONTEXT("context", 0, 0, 4), 43 | /** id = 2, name = "domainlabel" */ 44 | DOMAINLABEL("domainlabel", 2, 14, 9), 45 | /** id = 1, name = "hostname" */ 46 | HOSTNAME("hostname", 1, 4, 10), 47 | /** id = 6, name = "SP" */ 48 | SP("SP", 6, 40, 1), 49 | /** id = 3, name = "toplabel" */ 50 | TOPLABEL("toplabel", 3, 23, 10); 51 | private String name; 52 | private int id; 53 | private int offset; 54 | private int count; 55 | RuleNames(String string, int id, int offset, int count){ 56 | this.name = string; 57 | this.id = id; 58 | this.offset = offset; 59 | this.count = count; 60 | } 61 | /** Associates the enum with the original grammar name of the rule it represents. 62 | * @return the original grammar rule name. */ 63 | public String ruleName(){return name;} 64 | /** Associates the enum with an identifier for the grammar rule it represents. 65 | * @return the rule name identifier. */ 66 | public int ruleID(){return id;} 67 | private int opcodeOffset(){return offset;} 68 | private int opcodeCount(){return count;} 69 | } 70 | 71 | // UDT name enum 72 | /** The number of UDTs in the grammar */ 73 | public static int udtCount = 0; 74 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 75 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 76 | public enum UdtNames{ 77 | } 78 | 79 | // private 80 | private static Hostname factoryInstance = null; 81 | private Hostname(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 82 | super(rules, udts, opcodes); 83 | } 84 | 85 | private static Rule[] getRules(){ 86 | Rule[] rules = new Rule[7]; 87 | for(RuleNames r : RuleNames.values()){ 88 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 89 | } 90 | return rules; 91 | } 92 | 93 | private static Udt[] getUdts(){ 94 | Udt[] udts = new Udt[0]; 95 | return udts; 96 | } 97 | 98 | // opcodes 99 | private static Opcode[] getOpcodes(){ 100 | Opcode[] op = new Opcode[41]; 101 | addOpcodes00(op); 102 | return op; 103 | } 104 | 105 | private static void addOpcodes00(Opcode[] op){ 106 | {int[] a = {1,2,3}; op[0] = getOpcodeCat(a);} 107 | op[1] = getOpcodeRnm(6, 40); // SP 108 | op[2] = getOpcodeRnm(1, 4); // hostname 109 | op[3] = getOpcodeRnm(6, 40); // SP 110 | {int[] a = {5,11,12}; op[4] = getOpcodeCat(a);} 111 | op[5] = getOpcodeRep((char)0, Character.MAX_VALUE, 6); 112 | {int[] a = {7,8,9}; op[6] = getOpcodeCat(a);} 113 | op[7] = getOpcodeRnm(2, 14); // domainlabel 114 | {char[] a = {46}; op[8] = getOpcodeTls(a);} 115 | op[9] = getOpcodeAnd(10); 116 | op[10] = getOpcodeRnm(5, 36); // alphanum 117 | op[11] = getOpcodeRnm(3, 23); // toplabel 118 | op[12] = getOpcodeRep((char)0, (char)1, 13); 119 | {char[] a = {46}; op[13] = getOpcodeTls(a);} 120 | {int[] a = {15,17}; op[14] = getOpcodeCat(a);} 121 | op[15] = getOpcodeRep((char)1, Character.MAX_VALUE, 16); 122 | op[16] = getOpcodeRnm(5, 36); // alphanum 123 | op[17] = getOpcodeRep((char)0, Character.MAX_VALUE, 18); 124 | {int[] a = {19,21}; op[18] = getOpcodeCat(a);} 125 | op[19] = getOpcodeRep((char)1, Character.MAX_VALUE, 20); 126 | {char[] a = {45}; op[20] = getOpcodeTls(a);} 127 | op[21] = getOpcodeRep((char)1, Character.MAX_VALUE, 22); 128 | op[22] = getOpcodeRnm(5, 36); // alphanum 129 | {int[] a = {24,25,27}; op[23] = getOpcodeCat(a);} 130 | op[24] = getOpcodeRnm(4, 33); // ALPHA 131 | op[25] = getOpcodeRep((char)0, Character.MAX_VALUE, 26); 132 | op[26] = getOpcodeRnm(5, 36); // alphanum 133 | op[27] = getOpcodeRep((char)0, Character.MAX_VALUE, 28); 134 | {int[] a = {29,31}; op[28] = getOpcodeCat(a);} 135 | op[29] = getOpcodeRep((char)1, Character.MAX_VALUE, 30); 136 | {char[] a = {45}; op[30] = getOpcodeTls(a);} 137 | op[31] = getOpcodeRep((char)1, Character.MAX_VALUE, 32); 138 | op[32] = getOpcodeRnm(5, 36); // alphanum 139 | {int[] a = {34,35}; op[33] = getOpcodeAlt(a);} 140 | op[34] = getOpcodeTrg((char)65, (char)90); 141 | op[35] = getOpcodeTrg((char)97, (char)122); 142 | {int[] a = {37,38,39}; op[36] = getOpcodeAlt(a);} 143 | op[37] = getOpcodeTrg((char)65, (char)90); 144 | op[38] = getOpcodeTrg((char)97, (char)122); 145 | op[39] = getOpcodeTrg((char)48, (char)57); 146 | {char[] a = {32}; op[40] = getOpcodeTls(a);} 147 | } 148 | 149 | /** Displays the original SABNF grammar on the output device. 150 | * @param out the output device to display on.*/ 151 | public static void display(PrintStream out){ 152 | out.println(";"); 153 | out.println("; examples.demo.Hostname"); 154 | out.println(";"); 155 | out.println(";"); 156 | out.println("; hostname: Taken from the SIP message standard RFC 3261."); 157 | out.println("; SABNF Modifications:"); 158 | out.println("; 1) prioritized-choice disambiguation"); 159 | out.println("; 2) syntactic predicate to differentiate between domainlabel and toplabel"); 160 | out.println("; 3) the interior hyphen requirement corrected for \"greedy\" repetitions"); 161 | out.println(";"); 162 | out.println("context = SP hostname SP"); 163 | out.println("hostname = *(domainlabel \".\" &alphanum) toplabel [ \".\" ]"); 164 | out.println("domainlabel = 1*alphanum *(1*\"-\" 1*alphanum)"); 165 | out.println("toplabel = ALPHA *alphanum *(1*\"-\" 1*alphanum)"); 166 | out.println("ALPHA = %d65-90 / %d97-122"); 167 | out.println("alphanum = %d65-90 / %d97-122 / %d48-57"); 168 | out.println("SP = \" \""); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/examples/demo/IPv4.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.demo; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class IPv4 extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new IPv4(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 3; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 1, name = "byte" */ 38 | BYTE("byte", 1, 6, 2), 39 | /** id = 2, name = "digit" */ 40 | DIGIT("digit", 2, 8, 1), 41 | /** id = 0, name = "ipv4" */ 42 | IPV4("ipv4", 0, 0, 6); 43 | private String name; 44 | private int id; 45 | private int offset; 46 | private int count; 47 | RuleNames(String string, int id, int offset, int count){ 48 | this.name = string; 49 | this.id = id; 50 | this.offset = offset; 51 | this.count = count; 52 | } 53 | /** Associates the enum with the original grammar name of the rule it represents. 54 | * @return the original grammar rule name. */ 55 | public String ruleName(){return name;} 56 | /** Associates the enum with an identifier for the grammar rule it represents. 57 | * @return the rule name identifier. */ 58 | public int ruleID(){return id;} 59 | private int opcodeOffset(){return offset;} 60 | private int opcodeCount(){return count;} 61 | } 62 | 63 | // UDT name enum 64 | /** The number of UDTs in the grammar */ 65 | public static int udtCount = 0; 66 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 67 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 68 | public enum UdtNames{ 69 | } 70 | 71 | // private 72 | private static IPv4 factoryInstance = null; 73 | private IPv4(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 74 | super(rules, udts, opcodes); 75 | } 76 | 77 | private static Rule[] getRules(){ 78 | Rule[] rules = new Rule[3]; 79 | for(RuleNames r : RuleNames.values()){ 80 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 81 | } 82 | return rules; 83 | } 84 | 85 | private static Udt[] getUdts(){ 86 | Udt[] udts = new Udt[0]; 87 | return udts; 88 | } 89 | 90 | // opcodes 91 | private static Opcode[] getOpcodes(){ 92 | Opcode[] op = new Opcode[9]; 93 | addOpcodes00(op); 94 | return op; 95 | } 96 | 97 | private static void addOpcodes00(Opcode[] op){ 98 | {int[] a = {1,2}; op[0] = getOpcodeCat(a);} 99 | op[1] = getOpcodeRnm(1, 6); // byte 100 | op[2] = getOpcodeRep((char)3, (char)3, 3); 101 | {int[] a = {4,5}; op[3] = getOpcodeCat(a);} 102 | {char[] a = {46}; op[4] = getOpcodeTls(a);} 103 | op[5] = getOpcodeRnm(1, 6); // byte 104 | op[6] = getOpcodeRep((char)1, (char)3, 7); 105 | op[7] = getOpcodeRnm(2, 8); // digit 106 | op[8] = getOpcodeTrg((char)48, (char)57); 107 | } 108 | 109 | /** Displays the original SABNF grammar on the output device. 110 | * @param out the output device to display on.*/ 111 | public static void display(PrintStream out){ 112 | out.println(";"); 113 | out.println("; examples.demo.IPv4"); 114 | out.println(";"); 115 | out.println(";"); 116 | out.println("; IPv4 address"); 117 | out.println(";"); 118 | out.println("ipv4 = byte 3(\".\" byte)"); 119 | out.println("byte = 1*3digit"); 120 | out.println("digit = %d48-57"); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/examples/demo/UExpressions.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.demo; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class UExpressions extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new UExpressions(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 5; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "E" */ 38 | E("E", 0, 0, 3), 39 | /** id = 1, name = "Eprime" */ 40 | EPRIME("Eprime", 1, 3, 6), 41 | /** id = 4, name = "F" */ 42 | F("F", 4, 18, 6), 43 | /** id = 2, name = "T" */ 44 | T("T", 2, 9, 3), 45 | /** id = 3, name = "Tprime" */ 46 | TPRIME("Tprime", 3, 12, 6); 47 | private String name; 48 | private int id; 49 | private int offset; 50 | private int count; 51 | RuleNames(String string, int id, int offset, int count){ 52 | this.name = string; 53 | this.id = id; 54 | this.offset = offset; 55 | this.count = count; 56 | } 57 | /** Associates the enum with the original grammar name of the rule it represents. 58 | * @return the original grammar rule name. */ 59 | public String ruleName(){return name;} 60 | /** Associates the enum with an identifier for the grammar rule it represents. 61 | * @return the rule name identifier. */ 62 | public int ruleID(){return id;} 63 | private int opcodeOffset(){return offset;} 64 | private int opcodeCount(){return count;} 65 | } 66 | 67 | // UDT name enum 68 | /** The number of UDTs in the grammar */ 69 | public static int udtCount = 1; 70 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 71 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 72 | public enum UdtNames{ 73 | /** id = 0, name = "u_id" */ 74 | U_ID(0, "u_id", false); 75 | private String name; 76 | private int id; 77 | private boolean empty; 78 | UdtNames(int id, String string, boolean empty){ 79 | this.name = string; 80 | this.id = id; 81 | this.empty = empty; 82 | } 83 | /** Associates the enum with the original grammar name of the UDT it represents. 84 | * @return the original grammar UDT name. */ 85 | public String udtName(){return name;} 86 | /** Associates the enum with an identifier for the UDT it represents. 87 | * @return the UDT identifier. */ 88 | public int udtID(){return id;} 89 | /** Associates the enum with the "empty" attribute of the UDT it represents. 90 | * @return the "empty" attribute. 91 | * True if the UDT name begins with "e_", false if it begins with "u_". */ 92 | public boolean udtMayBeEmpty(){return empty;} 93 | } 94 | 95 | // private 96 | private static UExpressions factoryInstance = null; 97 | private UExpressions(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 98 | super(rules, udts, opcodes); 99 | } 100 | 101 | private static Rule[] getRules(){ 102 | Rule[] rules = new Rule[5]; 103 | for(RuleNames r : RuleNames.values()){ 104 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 105 | } 106 | return rules; 107 | } 108 | 109 | private static Udt[] getUdts(){ 110 | Udt[] udts = new Udt[1]; 111 | for(UdtNames r : UdtNames.values()){ 112 | udts[r.udtID()] = getUdt(r.udtID(), r.udtName(), r.udtMayBeEmpty()); 113 | } 114 | return udts; 115 | } 116 | 117 | // opcodes 118 | private static Opcode[] getOpcodes(){ 119 | Opcode[] op = new Opcode[24]; 120 | addOpcodes00(op); 121 | return op; 122 | } 123 | 124 | private static void addOpcodes00(Opcode[] op){ 125 | {int[] a = {1,2}; op[0] = getOpcodeCat(a);} 126 | op[1] = getOpcodeRnm(2, 9); // T 127 | op[2] = getOpcodeRnm(1, 3); // Eprime 128 | {int[] a = {4,8}; op[3] = getOpcodeAlt(a);} 129 | {int[] a = {5,6,7}; op[4] = getOpcodeCat(a);} 130 | {char[] a = {43}; op[5] = getOpcodeTls(a);} 131 | op[6] = getOpcodeRnm(2, 9); // T 132 | op[7] = getOpcodeRnm(1, 3); // Eprime 133 | {char[] a = {}; op[8] = getOpcodeTls(a);} 134 | {int[] a = {10,11}; op[9] = getOpcodeCat(a);} 135 | op[10] = getOpcodeRnm(4, 18); // F 136 | op[11] = getOpcodeRnm(3, 12); // Tprime 137 | {int[] a = {13,17}; op[12] = getOpcodeAlt(a);} 138 | {int[] a = {14,15,16}; op[13] = getOpcodeCat(a);} 139 | {char[] a = {42}; op[14] = getOpcodeTls(a);} 140 | op[15] = getOpcodeRnm(4, 18); // F 141 | op[16] = getOpcodeRnm(3, 12); // Tprime 142 | {char[] a = {}; op[17] = getOpcodeTls(a);} 143 | {int[] a = {19,23}; op[18] = getOpcodeAlt(a);} 144 | {int[] a = {20,21,22}; op[19] = getOpcodeCat(a);} 145 | {char[] a = {40}; op[20] = getOpcodeTls(a);} 146 | op[21] = getOpcodeRnm(0, 0); // E 147 | {char[] a = {41}; op[22] = getOpcodeTls(a);} 148 | op[23] = getOpcodeUdt(0); // u_id 149 | } 150 | 151 | /** Displays the original SABNF grammar on the output device. 152 | * @param out the output device to display on.*/ 153 | public static void display(PrintStream out){ 154 | out.println(";"); 155 | out.println("; examples.demo.UExpressions"); 156 | out.println(";"); 157 | out.println(";"); 158 | out.println("; Grammar (4.2) - Modified for SABNF syntax with UDT"); 159 | out.println("; Aho, Lam, Sethi and Ullman, \"Compilers: Principles, Techniques, & Tools\","); 160 | out.println("; 2nd ed., pp. 193, Addison Wesley, (2007)"); 161 | out.println(";"); 162 | out.println("E = T Eprime ; expression = sum of terms"); 163 | out.println("Eprime = \"+\" T Eprime / \"\""); 164 | out.println("T = F Tprime ; term = product of factors"); 165 | out.println("Tprime = \"*\" F Tprime / \"\""); 166 | out.println("F = \"(\" E \")\" / u_id ; factor = parenthesized expression or identifier"); 167 | out.println(" ; u_id = UDT for the identifier"); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/examples/demo/UIPv4.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.demo; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class UIPv4 extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new UIPv4(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 2; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 1, name = "byte" */ 38 | BYTE("byte", 1, 1, 1), 39 | /** id = 0, name = "ipv4" */ 40 | IPV4("ipv4", 0, 0, 1); 41 | private String name; 42 | private int id; 43 | private int offset; 44 | private int count; 45 | RuleNames(String string, int id, int offset, int count){ 46 | this.name = string; 47 | this.id = id; 48 | this.offset = offset; 49 | this.count = count; 50 | } 51 | /** Associates the enum with the original grammar name of the rule it represents. 52 | * @return the original grammar rule name. */ 53 | public String ruleName(){return name;} 54 | /** Associates the enum with an identifier for the grammar rule it represents. 55 | * @return the rule name identifier. */ 56 | public int ruleID(){return id;} 57 | private int opcodeOffset(){return offset;} 58 | private int opcodeCount(){return count;} 59 | } 60 | 61 | // UDT name enum 62 | /** The number of UDTs in the grammar */ 63 | public static int udtCount = 1; 64 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 65 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 66 | public enum UdtNames{ 67 | /** id = 0, name = "u_ipv4" */ 68 | U_IPV4(0, "u_ipv4", false); 69 | private String name; 70 | private int id; 71 | private boolean empty; 72 | UdtNames(int id, String string, boolean empty){ 73 | this.name = string; 74 | this.id = id; 75 | this.empty = empty; 76 | } 77 | /** Associates the enum with the original grammar name of the UDT it represents. 78 | * @return the original grammar UDT name. */ 79 | public String udtName(){return name;} 80 | /** Associates the enum with an identifier for the UDT it represents. 81 | * @return the UDT identifier. */ 82 | public int udtID(){return id;} 83 | /** Associates the enum with the "empty" attribute of the UDT it represents. 84 | * @return the "empty" attribute. 85 | * True if the UDT name begins with "e_", false if it begins with "u_". */ 86 | public boolean udtMayBeEmpty(){return empty;} 87 | } 88 | 89 | // private 90 | private static UIPv4 factoryInstance = null; 91 | private UIPv4(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 92 | super(rules, udts, opcodes); 93 | } 94 | 95 | private static Rule[] getRules(){ 96 | Rule[] rules = new Rule[2]; 97 | for(RuleNames r : RuleNames.values()){ 98 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 99 | } 100 | return rules; 101 | } 102 | 103 | private static Udt[] getUdts(){ 104 | Udt[] udts = new Udt[1]; 105 | for(UdtNames r : UdtNames.values()){ 106 | udts[r.udtID()] = getUdt(r.udtID(), r.udtName(), r.udtMayBeEmpty()); 107 | } 108 | return udts; 109 | } 110 | 111 | // opcodes 112 | private static Opcode[] getOpcodes(){ 113 | Opcode[] op = new Opcode[2]; 114 | addOpcodes00(op); 115 | return op; 116 | } 117 | 118 | private static void addOpcodes00(Opcode[] op){ 119 | op[0] = getOpcodeUdt(0); // u_ipv4 120 | {char[] a = {}; op[1] = getOpcodeTls(a);} 121 | } 122 | 123 | /** Displays the original SABNF grammar on the output device. 124 | * @param out the output device to display on.*/ 125 | public static void display(PrintStream out){ 126 | out.println(";"); 127 | out.println("; examples.demo.UIPv4"); 128 | out.println(";"); 129 | out.println(";"); 130 | out.println("; IPv4 address - UDT with dummy \"byte\" rule for AST node creation"); 131 | out.println(";"); 132 | out.println("ipv4 = u_ipv4"); 133 | out.println("byte = \"\""); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/examples/demo/UdtToAst.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.demo; 10 | 11 | import java.io.PrintStream; 12 | import apg.Ast; 13 | import apg.Parser; 14 | import apg.Parser.Result; 15 | import apg.Parser.UdtCallback; 16 | import apg.Trace; 17 | import apg.Utilities; 18 | import examples.RunTests; 19 | 20 | /** 21 | * This example demonstrates how to add nodes to the AST from a UDT. The source 22 | * code should be consulted for details. 23 | */ 24 | public class UdtToAst extends RunTests { 25 | 26 | /** 27 | * Constructor for the test. Parameters are supplied explicitly or by 28 | * default from the command line to the driver function. 29 | * 30 | * @param testName the name of the test 31 | * @param out the output device 32 | */ 33 | public UdtToAst(String testName, PrintStream out) { 34 | super(testName, out); 35 | } 36 | 37 | @Override 38 | protected void run() throws Exception { 39 | // display the title and an abstract 40 | if (testName != null) { 41 | outputTestName(); 42 | } else { 43 | throw new Exception("testName may not be null"); 44 | } 45 | outputAbstract("Demonstrate with the IPv4 grammar how a UDT can add nodes to the AST."); 46 | out.println(); 47 | 48 | // display the grammars 49 | outputCfgGrammar(); 50 | IPv4.display(out); 51 | out.println(); 52 | outputUdtGrammar(); 53 | UIPv4.display(out); 54 | out.println(); 55 | 56 | // display the input string 57 | String inputString = "123.12.012.000"; 58 | out.println("INPUT STRING: (" + testName + ")"); 59 | out.println(Utilities.charArrayToXml(inputString.toCharArray(), 0, inputString.length())); 60 | out.println(); 61 | 62 | // create a parser from the UDT grammar 63 | Parser parser = new Parser(UIPv4.getInstance()); 64 | 65 | // tell the parser what the start rule is 66 | int startRule = UIPv4.RuleNames.IPV4.ruleID(); 67 | int byteRule = UIPv4.RuleNames.BYTE.ruleID(); 68 | parser.setStartRule(startRule); 69 | 70 | // tell the parser what the input string is 71 | parser.setInputString(inputString); 72 | 73 | // tell the parser to use the hand-written UDTIPv4 UDT 74 | int udtId = UIPv4.UdtNames.U_IPV4.udtID(); 75 | int ruleByteId = UIPv4.RuleNames.BYTE.ruleID(); 76 | UdtCallback udtCallback = new UDTIPv4(parser, ruleByteId); 77 | parser.setUdtCallback(udtId, udtCallback); 78 | 79 | // tell the parser to generate an AST 80 | Ast ast = parser.enableAst(true); 81 | 82 | // tell the AST which rule name nodes to keep 83 | ast.enableRuleNode(startRule, true); 84 | ast.enableRuleNode(byteRule, true); 85 | ast.enableUdtNode(udtId, true); 86 | 87 | // tell the AST which UDT nodes to keep 88 | ast.enableUdtNode(UExpressions.UdtNames.U_ID.udtID(), true); 89 | 90 | // parse the input string 91 | Result result = parser.parse(); 92 | 93 | // handle the parser result 94 | if (result.success()) { 95 | // display the AST in APG format 96 | outputAst(false); 97 | ast.display(out); 98 | out.println(); 99 | 100 | // display the AST in XML format 101 | outputAst(true); 102 | ast.display(out, true); 103 | out.println(); 104 | } else { 105 | Trace trace = parser.enableTrace(true); 106 | trace.setOut(out); 107 | 108 | // display the trace in APG format 109 | outputTrace(false); 110 | parser.parse(); 111 | out.println(); 112 | 113 | // display the trace in XML format 114 | outputTrace(true); 115 | trace.enableXml(true); 116 | parser.parse(); 117 | out.println(); 118 | } 119 | } 120 | 121 | class UDTIPv4 extends UdtCallback { 122 | 123 | private final int ruleByteId; 124 | 125 | UDTIPv4(Parser parser, int ruleByteId) { 126 | super(parser); 127 | this.ruleByteId = ruleByteId; 128 | } 129 | 130 | @Override 131 | public int callback(int offset) throws Exception { 132 | int i = offset; 133 | char[] in = callbackData.inputString; 134 | int inlen = callbackData.inputString.length; 135 | int len = 0; 136 | int[] byteOffset = new int[4]; 137 | int[] byteLength = new int[4]; 138 | int beg, end, c; 139 | boolean success = true; 140 | for (int j = 0; j < 4; j++) { 141 | // find the phrase offset and length for each byte integer in the address 142 | for (beg = i, end = 0; i < inlen; i++, end++) { 143 | c = (int) in[i]; 144 | if (c >= 48 && c <= 57) { 145 | } else { 146 | break; 147 | } 148 | } 149 | if (end >= 1 && end <= 3) { // 3-digit constraint 150 | len += end; 151 | byteOffset[j] = beg; 152 | byteLength[j] = end; 153 | // NOTE: could add a check here for the specification 154 | // that byte value must be less than 256 155 | if (j < 3) { 156 | // check for trailing period 157 | if (in[i] == '.') { 158 | i++; 159 | len++; 160 | } else { 161 | success = false; 162 | break; 163 | } 164 | } 165 | } else { 166 | success = false; 167 | break; 168 | } 169 | if (!success) { 170 | break; 171 | } 172 | } 173 | if (success) { 174 | // put the four byte integer phrases on the AST 175 | for (int j = 0; j < 4; j++) { 176 | parser.addAstRuleNode(ruleByteId, byteOffset[j], byteLength[j], true); 177 | } 178 | 179 | } else { 180 | len = -1; 181 | } 182 | return len; 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/examples/demo/expressions.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; ABNF version of grammar (4.2) 3 | ; Aho, Lam, Sethi and Ullman, "Compilers: Principles, Techniques, & Tools", 4 | ; 2nd ed., pp. 193, Addison Wesley, (2007) 5 | ; 6 | E = T Eprime ; expression = sum of terms 7 | Eprime = "+" T Eprime / "" 8 | T = F Tprime ; term = product of factors 9 | Tprime = "*" F Tprime / "" 10 | F = "(" E ")" / id ; factor = parenthesized expression or identifier 11 | id = alpha *(alpha / digit) ; id = alphanumeric name 12 | alpha = %d65-90 / %d97-122 ; upper or lower case letters 13 | digit = %d48-57 ; digits 0-9 14 | 15 | -------------------------------------------------------------------------------- /src/examples/demo/hostname.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; hostname: Taken from the SIP message standard RFC 3261. 3 | ; SABNF Modifications: 4 | ; 1) prioritized-choice disambiguation 5 | ; 2) syntactic predicate to differentiate between domainlabel and toplabel 6 | ; 3) the interior hyphen requirement corrected for "greedy" repetitions 7 | ; 8 | context = SP hostname SP 9 | hostname = *(domainlabel "." &alphanum) toplabel [ "." ] 10 | domainlabel = 1*alphanum *(1*"-" 1*alphanum) 11 | toplabel = ALPHA *alphanum *(1*"-" 1*alphanum) 12 | ALPHA = %d65-90 / %d97-122 13 | alphanum = %d65-90 / %d97-122 / %d48-57 14 | SP = " " 15 | -------------------------------------------------------------------------------- /src/examples/demo/ipv4.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; IPv4 address 3 | ; 4 | ipv4 = byte 3("." byte) 5 | byte = 1*3digit 6 | digit = %d48-57 -------------------------------------------------------------------------------- /src/examples/demo/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Some demonstrations of using the main features of Java APG and some timing tests using UDTs. 4 | The source code should be consulted for details. 5 |

6 | 7 | Disclaimer: This example should not be considered as part of the Java APG API. Backward compatibility or even the existance of this example from version to version is not guaranteed. 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/examples/demo/uexpressions.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Grammar (4.2) - Modified for SABNF syntax with UDT 3 | ; Aho, Lam, Sethi and Ullman, "Compilers: Principles, Techniques, & Tools", 4 | ; 2nd ed., pp. 193, Addison Wesley, (2007) 5 | ; 6 | E = T Eprime ; expression = sum of terms 7 | Eprime = "+" T Eprime / "" 8 | T = F Tprime ; term = product of factors 9 | Tprime = "*" F Tprime / "" 10 | F = "(" E ")" / u_id ; factor = parenthesized expression or identifier 11 | ; u_id = UDT for the identifier 12 | -------------------------------------------------------------------------------- /src/examples/demo/uhostname.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; hostname: Taken from the SIP message standard RFC 3261. 3 | ; SABNF Modifications: 4 | ; 1) prioritized-choice disambiguation 5 | ; 2) UDT is used to select between domanlabel and toplabel 6 | ; 3) the interior hyphen requirement corrected for "greedy" repetitions 7 | ; 8 | context = SP hostname SP 9 | hostname = 1*u_UDT-as-ALT ; UDT to select between domainlabel & toplabel 10 | label = 1*alphanum *(1*"-" 1*alphanum) ; generic label 11 | domainlabel = "" ; dummy rule for AST node creation 12 | toplabel = "" ; dummy rule for AST node creation 13 | alphanum = %d65-90 / %d97-122 / %d48-57 14 | SP = " " 15 | -------------------------------------------------------------------------------- /src/examples/demo/uipv4.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; IPv4 address - UDT with dummy "byte" rule for AST node creation 3 | ; 4 | ipv4 = u_ipv4 5 | byte = "" 6 | -------------------------------------------------------------------------------- /src/examples/expressions/Expressions.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.expressions; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class Expressions extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new Expressions(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 8; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 6, name = "alpha" */ 38 | ALPHA("alpha", 6, 30, 3), 39 | /** id = 7, name = "digit" */ 40 | DIGIT("digit", 7, 33, 1), 41 | /** id = 0, name = "E" */ 42 | E("E", 0, 0, 3), 43 | /** id = 1, name = "Eprime" */ 44 | EPRIME("Eprime", 1, 3, 6), 45 | /** id = 4, name = "F" */ 46 | F("F", 4, 18, 6), 47 | /** id = 5, name = "id" */ 48 | ID("id", 5, 24, 6), 49 | /** id = 2, name = "T" */ 50 | T("T", 2, 9, 3), 51 | /** id = 3, name = "Tprime" */ 52 | TPRIME("Tprime", 3, 12, 6); 53 | private String name; 54 | private int id; 55 | private int offset; 56 | private int count; 57 | RuleNames(String string, int id, int offset, int count){ 58 | this.name = string; 59 | this.id = id; 60 | this.offset = offset; 61 | this.count = count; 62 | } 63 | /** Associates the enum with the original grammar name of the rule it represents. 64 | * @return the original grammar rule name. */ 65 | public String ruleName(){return name;} 66 | /** Associates the enum with an identifier for the grammar rule it represents. 67 | * @return the rule name identifier. */ 68 | public int ruleID(){return id;} 69 | private int opcodeOffset(){return offset;} 70 | private int opcodeCount(){return count;} 71 | } 72 | 73 | // UDT name enum 74 | /** The number of UDTs in the grammar */ 75 | public static int udtCount = 0; 76 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 77 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 78 | public enum UdtNames{ 79 | } 80 | 81 | // private 82 | private static Expressions factoryInstance = null; 83 | private Expressions(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 84 | super(rules, udts, opcodes); 85 | } 86 | 87 | private static Rule[] getRules(){ 88 | Rule[] rules = new Rule[8]; 89 | for(RuleNames r : RuleNames.values()){ 90 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 91 | } 92 | return rules; 93 | } 94 | 95 | private static Udt[] getUdts(){ 96 | Udt[] udts = new Udt[0]; 97 | return udts; 98 | } 99 | 100 | // opcodes 101 | private static Opcode[] getOpcodes(){ 102 | Opcode[] op = new Opcode[34]; 103 | addOpcodes00(op); 104 | return op; 105 | } 106 | 107 | private static void addOpcodes00(Opcode[] op){ 108 | {int[] a = {1,2}; op[0] = getOpcodeCat(a);} 109 | op[1] = getOpcodeRnm(2, 9); // T 110 | op[2] = getOpcodeRnm(1, 3); // Eprime 111 | {int[] a = {4,8}; op[3] = getOpcodeAlt(a);} 112 | {int[] a = {5,6,7}; op[4] = getOpcodeCat(a);} 113 | {char[] a = {43}; op[5] = getOpcodeTls(a);} 114 | op[6] = getOpcodeRnm(2, 9); // T 115 | op[7] = getOpcodeRnm(1, 3); // Eprime 116 | {char[] a = {}; op[8] = getOpcodeTls(a);} 117 | {int[] a = {10,11}; op[9] = getOpcodeCat(a);} 118 | op[10] = getOpcodeRnm(4, 18); // F 119 | op[11] = getOpcodeRnm(3, 12); // Tprime 120 | {int[] a = {13,17}; op[12] = getOpcodeAlt(a);} 121 | {int[] a = {14,15,16}; op[13] = getOpcodeCat(a);} 122 | {char[] a = {42}; op[14] = getOpcodeTls(a);} 123 | op[15] = getOpcodeRnm(4, 18); // F 124 | op[16] = getOpcodeRnm(3, 12); // Tprime 125 | {char[] a = {}; op[17] = getOpcodeTls(a);} 126 | {int[] a = {19,23}; op[18] = getOpcodeAlt(a);} 127 | {int[] a = {20,21,22}; op[19] = getOpcodeCat(a);} 128 | {char[] a = {40}; op[20] = getOpcodeTls(a);} 129 | op[21] = getOpcodeRnm(0, 0); // E 130 | {char[] a = {41}; op[22] = getOpcodeTls(a);} 131 | op[23] = getOpcodeRnm(5, 24); // id 132 | {int[] a = {25,26}; op[24] = getOpcodeCat(a);} 133 | op[25] = getOpcodeRnm(6, 30); // alpha 134 | op[26] = getOpcodeRep((char)0, Character.MAX_VALUE, 27); 135 | {int[] a = {28,29}; op[27] = getOpcodeAlt(a);} 136 | op[28] = getOpcodeRnm(6, 30); // alpha 137 | op[29] = getOpcodeRnm(7, 33); // digit 138 | {int[] a = {31,32}; op[30] = getOpcodeAlt(a);} 139 | op[31] = getOpcodeTrg((char)65, (char)90); 140 | op[32] = getOpcodeTrg((char)97, (char)122); 141 | op[33] = getOpcodeTrg((char)48, (char)57); 142 | } 143 | 144 | /** Displays the original SABNF grammar on the output device. 145 | * @param out the output device to display on.*/ 146 | public static void display(PrintStream out){ 147 | out.println(";"); 148 | out.println("; examples.expressions.Expressions"); 149 | out.println(";"); 150 | out.println(";"); 151 | out.println("; Grammar (4.2) - Modified for ABNF syntax"); 152 | out.println("; Aho, Lam, Sethi and Ullman, \"Compilers: Principles, Techniques, & Tools\","); 153 | out.println("; 2nd ed., pp. 193, Addison Wesley, (2007)"); 154 | out.println(";"); 155 | out.println("E = T Eprime ; expression = sum of terms"); 156 | out.println("Eprime = \"+\" T Eprime / \"\""); 157 | out.println("T = F Tprime ; term = product of factors"); 158 | out.println("Tprime = \"*\" F Tprime / \"\""); 159 | out.println("F = \"(\" E \")\" / id ; factor = parenthesized expression or identifier"); 160 | out.println("id = alpha *(alpha / digit) ; id = alphanumeric name"); 161 | out.println("alpha = %d65-90 / %d97-122 ; upper or lower case letters"); 162 | out.println("digit = %d48-57 ; digits 0-9"); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /src/examples/expressions/RunExpressions.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.expressions; 10 | 11 | import java.io.PrintStream; 12 | 13 | import apg.Parser; 14 | import apg.UdtLib.*; 15 | import examples.RunTests; 16 | 17 | /** 18 | * Uses the the Expressions grammar (4.2) from Aho, Lam, Sethi and Ullman, 2nd 19 | * ed. (the Dragon Book) for a comparison of timing and node hits between the 20 | * normal CFG grammar and the use of UDT functions. 21 | */ 22 | public class RunExpressions extends RunTests { 23 | 24 | /** 25 | * Constructor for the test. Parameters are supplied explicitly or by 26 | * default from the command line to the driver function. 27 | * 28 | * @param testName the name of the test 29 | * @param reps the number of repetitions of the parser 30 | * @param out the output device 31 | */ 32 | public RunExpressions(String testName, int reps, PrintStream out) { 33 | super(testName, reps, out); 34 | } 35 | 36 | @Override 37 | protected void run() throws Exception { 38 | setup(); 39 | runComparisionOfCfgAndUdt(); 40 | } 41 | 42 | void setup() throws Exception { 43 | // display the title and an abstract 44 | if (testName != null) { 45 | outputTestName(); 46 | } else { 47 | throw new Exception("testName may not be null"); 48 | } 49 | outputAbstract("CFG/UDT time & statistics comparison for the Expressions grammar"); 50 | out.println(); 51 | 52 | // display the grammars 53 | outputCfgGrammar(); 54 | Expressions.display(out); 55 | out.println(); 56 | outputUdtGrammar(); 57 | UExpressions.display(out); 58 | out.println(); 59 | 60 | // set up input strings 61 | if (inputStrings == null 62 | || inputStrings.length == 0 63 | || inputStrings[0] == null 64 | || inputStrings[0].length() == 0) { 65 | inputStringCount = 5; 66 | inputStrings = new String[inputStringCount]; 67 | inputStrings[0] = "a+b"; 68 | inputStrings[1] = "a+b*c"; 69 | inputStrings[2] = "(a+b)*(c+d)"; 70 | inputStrings[3] = "a+b*c+(LevelOne*(LevelTwoA+LevelTwoB))"; 71 | inputStrings[4] = "(a+b)*(c+(d+e*(topA+topB)))"; 72 | } 73 | 74 | // CFG grammar-dependent setup 75 | int startRule = Expressions.RuleNames.E.ruleID(); // grammar.RuleNames.RULE.ruldID(); 76 | cfgIn = new RunInput("cfg", new Parser(Expressions.getInstance()), startRule); 77 | 78 | // UDT grammar-dependent setup 79 | Parser udtParser = new Parser(UExpressions.getInstance()); 80 | startRule = UExpressions.RuleNames.E.ruleID(); 81 | 82 | // UDT callback functions 83 | udtParser.setUdtCallback(UExpressions.UdtNames.U_ID.udtID(), new Alphanum(udtParser)); 84 | udtIn = new RunInput("udt", udtParser, startRule); 85 | } 86 | } 87 | //void runDemo() throws Exception{ 88 | //title = "*** Expressions, simple demo ***"; 89 | //out = System.out; 90 | // 91 | //// display the grammars 92 | //out.println("*** Expressions Grammars ***"); 93 | //System.out.println("Display the CFG grammar:"); 94 | //Expressions.display(out); 95 | //System.out.println("\nDisplay the UDT grammar:"); 96 | //UExpressions.display(out); 97 | //out.println(); 98 | // 99 | //// parser setup 100 | //Parser parser = new Parser(UExpressions.getInstance()); 101 | // 102 | //// set the input string 103 | //String inputString = "(a+b)*(c+(d+e*(topA+topB)))"; 104 | //parser.setInputString(inputString); 105 | //out.println(title); 106 | //out.print("input string: \""); 107 | //out.print(Utilities.charArrayToXml(inputString.toCharArray(), 0, inputString.length())); 108 | //out.println("\""); 109 | // 110 | //// set the start rule 111 | //int startRule = UExpressions.RuleNames.E.ruleID(); 112 | //parser.setStartRule(startRule); 113 | // 114 | //// set the UDT callback function 115 | //parser.setUdtCallback(UExpressions.UdtNames.U_ID.udtID(), new Alphanum(parser)); 116 | // 117 | //// set up the AST 118 | //Ast ast = parser.enableAst(true); 119 | //ast.enableRuleNode(UExpressions.RuleNames.E.ruleID(), true); 120 | //ast.enableRuleNode(UExpressions.RuleNames.T.ruleID(), true); 121 | //ast.enableRuleNode(UExpressions.RuleNames.F.ruleID(), true); 122 | //ast.enableRuleNode(UExpressions.RuleNames.EPRIME.ruleID(), true); 123 | //ast.enableRuleNode(UExpressions.RuleNames.TPRIME.ruleID(), true); 124 | //ast.enableUdtNode(UExpressions.UdtNames.U_ID.udtID(), true); 125 | // 126 | //// parse the input string 127 | //Result result = parser.parse(); 128 | //if(result.success()){ 129 | // // display the AST in native format 130 | // out.println("\ndisplay the AST, native format:"); 131 | // ast.display(out); 132 | // 133 | // // display the AST in XML format 134 | // out.println("\ndisplay the AST, XML format:"); 135 | // ast.display(out, true); 136 | // 137 | //} else{ 138 | // Trace trace = parser.enableTrace(true); 139 | // 140 | // // display the trace in native format 141 | // out.println("\nparse failed: display the trace:"); 142 | // out.println("TRACE, native format:"); 143 | // parser.parse(); 144 | // 145 | // // display the trace in XML format 146 | // out.println("\nTRACE, XML format:"); 147 | // trace.enableXml(true); 148 | // parser.parse(); 149 | // 150 | //} 151 | //} 152 | -------------------------------------------------------------------------------- /src/examples/expressions/UExpressions.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.expressions; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class UExpressions extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new UExpressions(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 5; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "E" */ 38 | E("E", 0, 0, 3), 39 | /** id = 1, name = "Eprime" */ 40 | EPRIME("Eprime", 1, 3, 6), 41 | /** id = 4, name = "F" */ 42 | F("F", 4, 18, 6), 43 | /** id = 2, name = "T" */ 44 | T("T", 2, 9, 3), 45 | /** id = 3, name = "Tprime" */ 46 | TPRIME("Tprime", 3, 12, 6); 47 | private String name; 48 | private int id; 49 | private int offset; 50 | private int count; 51 | RuleNames(String string, int id, int offset, int count){ 52 | this.name = string; 53 | this.id = id; 54 | this.offset = offset; 55 | this.count = count; 56 | } 57 | /** Associates the enum with the original grammar name of the rule it represents. 58 | * @return the original grammar rule name. */ 59 | public String ruleName(){return name;} 60 | /** Associates the enum with an identifier for the grammar rule it represents. 61 | * @return the rule name identifier. */ 62 | public int ruleID(){return id;} 63 | private int opcodeOffset(){return offset;} 64 | private int opcodeCount(){return count;} 65 | } 66 | 67 | // UDT name enum 68 | /** The number of UDTs in the grammar */ 69 | public static int udtCount = 1; 70 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 71 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 72 | public enum UdtNames{ 73 | /** id = 0, name = "u_id" */ 74 | U_ID(0, "u_id", false); 75 | private String name; 76 | private int id; 77 | private boolean empty; 78 | UdtNames(int id, String string, boolean empty){ 79 | this.name = string; 80 | this.id = id; 81 | this.empty = empty; 82 | } 83 | /** Associates the enum with the original grammar name of the UDT it represents. 84 | * @return the original grammar UDT name. */ 85 | public String udtName(){return name;} 86 | /** Associates the enum with an identifier for the UDT it represents. 87 | * @return the UDT identifier. */ 88 | public int udtID(){return id;} 89 | /** Associates the enum with the "empty" attribute of the UDT it represents. 90 | * @return the "empty" attribute. 91 | * True if the UDT name begins with "e_", false if it begins with "u_". */ 92 | public boolean udtMayBeEmpty(){return empty;} 93 | } 94 | 95 | // private 96 | private static UExpressions factoryInstance = null; 97 | private UExpressions(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 98 | super(rules, udts, opcodes); 99 | } 100 | 101 | private static Rule[] getRules(){ 102 | Rule[] rules = new Rule[5]; 103 | for(RuleNames r : RuleNames.values()){ 104 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 105 | } 106 | return rules; 107 | } 108 | 109 | private static Udt[] getUdts(){ 110 | Udt[] udts = new Udt[1]; 111 | for(UdtNames r : UdtNames.values()){ 112 | udts[r.udtID()] = getUdt(r.udtID(), r.udtName(), r.udtMayBeEmpty()); 113 | } 114 | return udts; 115 | } 116 | 117 | // opcodes 118 | private static Opcode[] getOpcodes(){ 119 | Opcode[] op = new Opcode[24]; 120 | addOpcodes00(op); 121 | return op; 122 | } 123 | 124 | private static void addOpcodes00(Opcode[] op){ 125 | {int[] a = {1,2}; op[0] = getOpcodeCat(a);} 126 | op[1] = getOpcodeRnm(2, 9); // T 127 | op[2] = getOpcodeRnm(1, 3); // Eprime 128 | {int[] a = {4,8}; op[3] = getOpcodeAlt(a);} 129 | {int[] a = {5,6,7}; op[4] = getOpcodeCat(a);} 130 | {char[] a = {43}; op[5] = getOpcodeTls(a);} 131 | op[6] = getOpcodeRnm(2, 9); // T 132 | op[7] = getOpcodeRnm(1, 3); // Eprime 133 | {char[] a = {}; op[8] = getOpcodeTls(a);} 134 | {int[] a = {10,11}; op[9] = getOpcodeCat(a);} 135 | op[10] = getOpcodeRnm(4, 18); // F 136 | op[11] = getOpcodeRnm(3, 12); // Tprime 137 | {int[] a = {13,17}; op[12] = getOpcodeAlt(a);} 138 | {int[] a = {14,15,16}; op[13] = getOpcodeCat(a);} 139 | {char[] a = {42}; op[14] = getOpcodeTls(a);} 140 | op[15] = getOpcodeRnm(4, 18); // F 141 | op[16] = getOpcodeRnm(3, 12); // Tprime 142 | {char[] a = {}; op[17] = getOpcodeTls(a);} 143 | {int[] a = {19,23}; op[18] = getOpcodeAlt(a);} 144 | {int[] a = {20,21,22}; op[19] = getOpcodeCat(a);} 145 | {char[] a = {40}; op[20] = getOpcodeTls(a);} 146 | op[21] = getOpcodeRnm(0, 0); // E 147 | {char[] a = {41}; op[22] = getOpcodeTls(a);} 148 | op[23] = getOpcodeUdt(0); // u_id 149 | } 150 | 151 | /** Displays the original SABNF grammar on the output device. 152 | * @param out the output device to display on.*/ 153 | public static void display(PrintStream out){ 154 | out.println(";"); 155 | out.println("; examples.expressions.UExpressions"); 156 | out.println(";"); 157 | out.println(";"); 158 | out.println("; SABNF version of grammar (4.2) - including UDT"); 159 | out.println("; Aho, Lam, Sethi and Ullman, \"Compilers: Principles, Techniques, & Tools\","); 160 | out.println("; 2nd ed., pp. 193, Addison Wesley, (2007)"); 161 | out.println(";"); 162 | out.println("E = T Eprime ; expression = sum of terms"); 163 | out.println("Eprime = \"+\" T Eprime / \"\""); 164 | out.println("T = F Tprime ; term = product of factors"); 165 | out.println("Tprime = \"*\" F Tprime / \"\""); 166 | out.println("F = \"(\" E \")\" / u_id ; factor = parenthesized expression or identifier"); 167 | out.println(" ; u_id = UDT for the identifier"); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/examples/expressions/expressions.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Grammar (4.2) - Modified for ABNF syntax 3 | ; Aho, Lam, Sethi and Ullman, "Compilers: Principles, Techniques, & Tools", 4 | ; 2nd ed., pp. 193, Addison Wesley, (2007) 5 | ; 6 | E = T Eprime ; expression = sum of terms 7 | Eprime = "+" T Eprime / "" 8 | T = F Tprime ; term = product of factors 9 | Tprime = "*" F Tprime / "" 10 | F = "(" E ")" / id ; factor = parenthesized expression or identifier 11 | id = alpha *(alpha / digit) ; id = alphanumeric name 12 | alpha = %d65-90 / %d97-122 ; upper or lower case letters 13 | digit = %d48-57 ; digits 0-9 14 | 15 | -------------------------------------------------------------------------------- /src/examples/expressions/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A comparison of timing and node hit statistics between 4 | the CFG and UDT parsers for 5 | the expressions grammar. 6 | Grammar (4.2) from from Aho, Lam, Sethi and Ullman, 2nd ed. (the Dragon Book) is used. 7 |

8 | 9 | Disclaimer: This example should not be considered as part of the Java APG API. Backward compatibility or even the existance of this example from version to version is not guaranteed. 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/examples/expressions/uexpressions.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; SABNF version of grammar (4.2) - including UDT 3 | ; Aho, Lam, Sethi and Ullman, "Compilers: Principles, Techniques, & Tools", 4 | ; 2nd ed., pp. 193, Addison Wesley, (2007) 5 | ; 6 | E = T Eprime ; expression = sum of terms 7 | Eprime = "+" T Eprime / "" 8 | T = F Tprime ; term = product of factors 9 | Tprime = "*" F Tprime / "" 10 | F = "(" E ")" / u_id ; factor = parenthesized expression or identifier 11 | ; u_id = UDT for the identifier 12 | -------------------------------------------------------------------------------- /src/examples/inifile/IniFile.input: -------------------------------------------------------------------------------- 1 | 2 | ; blank line and comment before first section 3 | [ FirstSection ] ; comment after section 4 | 5 | ; blank line & comment before value 6 | key1 = 100; integer value 7 | key2 = abc; alphanumeric 8 | key2 = 1bc; alphanumeric may begin with digit 9 | key4 = 'single, quoted, data """"~!@#$%^&*()_+=-[]{}:<>,.?/' ; single quoted value 10 | key5 = "double, quoted, data ''''~!@#$%^&*()_+=-[]{}:<>,.?/" ; double quoted value 11 | 12 | [SecondSection ] 13 | 14 | ; multiple ValueName definitions 15 | ValueName1=1000, 1001, 1002 ; value arrays 16 | ValueName1= 1003 17 | ValueName1 = 1004, 1005 18 | ValueName2=2000, 2001, 2002 19 | ValueName2= 2003 20 | ValueName2 = 2004, 2005 21 | 22 | [ _Third_Section] ; section name starts with underscore 23 | ; value names can start with underscore & digits 24 | line_3 = regular 25 | _3line = underscore 26 | 3_line = digit 27 | 28 | ;section name starts with digit 29 | [4th_Section] 30 | line1 = regular 31 | line2 = 5digits 32 | line3 = digits100 33 | 34 | ; multiple Section Names 35 | [SecondSection ] 36 | ValueName1=3000, 3001, 3002 37 | ValueName1= 3003 38 | ValueName1 = 3004, 3005 39 | ValueName2=4000, 4001, 4002 40 | ValueName2= 4003 41 | ValueName2 = 4004, 4005 42 | 43 | -------------------------------------------------------------------------------- /src/examples/inifile/RunIniFile.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.inifile; 10 | 11 | import java.io.PrintStream; 12 | 13 | import apg.Parser; 14 | import apg.Parser.UdtCallback; 15 | import apg.UdtLib.*; 16 | import examples.RunTests; 17 | 18 | /** 19 | * Uses a grammar for the common "ini" file format for a comparison of timing 20 | * and node hits between the normal CFG grammar and the use of UDT functions. 21 | */ 22 | public class RunIniFile extends RunTests { 23 | 24 | /** 25 | * Constructor for the test. Parameters are supplied explicitly or by 26 | * default from the command line to the driver function. 27 | * 28 | * @param testName the name of the test 29 | * @param reps the number of repetitions of the parser 30 | * @param out the output device 31 | */ 32 | public RunIniFile(String testName, int reps, PrintStream out) { 33 | super(testName, reps, out); 34 | } 35 | 36 | @Override 37 | protected void run() throws Exception { 38 | setup(); 39 | runComparisionOfCfgAndUdt(); 40 | } 41 | 42 | void setup() throws Exception { 43 | // display the title and an abstract 44 | if (testName != null) { 45 | outputTestName(); 46 | } else { 47 | throw new Exception("testName may not be null"); 48 | } 49 | outputAbstract("CFG/UDT time & statistics comparison for the \"ini\" file grammar"); 50 | out.println(); 51 | 52 | // display the grammars 53 | out.println("GRAMMAR: CFG"); 54 | IniFile.display(out); 55 | out.println(); 56 | out.println("GRAMMAR: UDT"); 57 | UIniFile.display(out); 58 | out.println(); 59 | 60 | // set up input strings 61 | if (inputStrings == null 62 | || inputStrings.length == 0 63 | || inputStrings[0] == null 64 | || inputStrings[0].length() == 0) { 65 | inputStringCount = 3; 66 | inputStrings = new String[inputStringCount]; 67 | inputStrings[0] = "[SECTION]\nkey=value\n"; 68 | inputStrings[1] = "[ section1]\r\nkey = value\rkey2 = loooongvalue\n[section2]\n\n\n ;comment\nxkey = xvalue\r\n"; 69 | inputStrings[2] = "[anotherSection_name];section comment\nanotherkey = annothervalue\n"; 70 | } 71 | 72 | // CFG setup 73 | int startRule = IniFile.RuleNames.INIFILE.ruleID(); // grammar.RuleNames.RULE.ruldID(); 74 | cfgIn = new RunInput("cfg", new Parser(IniFile.getInstance()), startRule); 75 | 76 | // UDT setup 77 | Parser parser = new Parser(UIniFile.getInstance()); 78 | startRule = UIniFile.RuleNames.INIFILE.ruleID(); 79 | SemiComment comment = new SemiComment(parser); 80 | LineEnd lineend = new LineEnd(parser); 81 | parser.setUdtCallback(UIniFile.UdtNames.U_LINEEND.udtID(), lineend); 82 | parser.setUdtCallback(UIniFile.UdtNames.U_COMMENT.udtID(), comment); 83 | parser.setUdtCallback(UIniFile.UdtNames.E_ANY.udtID(), new Any(parser)); 84 | parser.setUdtCallback(UIniFile.UdtNames.U_ALPHADIGIT.udtID(), new AlphaDigit(parser)); 85 | parser.setUdtCallback(UIniFile.UdtNames.U_ALPHADIGITUNDER.udtID(), new AlphaDigitUnder(parser)); 86 | parser.setUdtCallback(UIniFile.UdtNames.E_WSP.udtID(), new WhiteSpace(parser)); 87 | parser.setUdtCallback(UIniFile.UdtNames.U_DQSTRING.udtID(), new DoubleQuotedString(parser)); 88 | parser.setUdtCallback(UIniFile.UdtNames.U_SQSTRING.udtID(), new SingleQuotedString(parser)); 89 | parser.setUdtCallback(UIniFile.UdtNames.E_COMMENT_WSP.udtID(), new WhiteSpace(parser, true, comment, null)); 90 | udtIn = new RunInput("udt", parser, startRule); 91 | } 92 | 93 | class AlphaDigit extends UdtCallback { 94 | 95 | AlphaDigit(Parser p) { 96 | super(p); 97 | } 98 | 99 | @Override 100 | public int callback(int offset) { 101 | int len = 0; 102 | int i = offset; 103 | char c; 104 | for (; i < callbackData.inputString.length; i++) { 105 | c = callbackData.inputString[i]; 106 | if ((c >= 'a' && c <= 'z') 107 | || (c >= 'A' && c <= 'Z') 108 | || (c >= '0' && c <= '9')) { 109 | len++; 110 | } else { 111 | break; 112 | } 113 | } 114 | return (len > 0) ? len : -1; 115 | } 116 | } 117 | 118 | class AlphaDigitUnder extends UdtCallback { 119 | 120 | AlphaDigitUnder(Parser p) { 121 | super(p); 122 | } 123 | 124 | @Override 125 | public int callback(int offset) { 126 | int len = 0; 127 | int i = offset; 128 | char c; 129 | for (; i < callbackData.inputString.length; i++) { 130 | c = callbackData.inputString[i]; 131 | if ((c >= 'a' && c <= 'z') 132 | || (c >= 'A' && c <= 'Z') 133 | || (c >= '0' && c <= '9') 134 | || (c == '_')) { 135 | len++; 136 | } else { 137 | break; 138 | } 139 | } 140 | return (len > 0) ? len : -1; 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/examples/inifile/inifile.bnf: -------------------------------------------------------------------------------- 1 | IniFile = *BlankLine *Section 2 | Section = SectionLine *(BlankLine/ValueLine) 3 | SectionLine = GoodSectionLine/BadSectionLine 4 | GoodSectionLine = "[" wsp SectionName wsp "]" wsp [comment] LineEnd 5 | BadSectionLine = "[" *any LineEnd; 6 | ValueLine = GoodValueLine/BadValueLine 7 | GoodValueLine = ValueName wsp "=" wsp ValueArray wsp [comment] LineEnd 8 | BadValueLine = (%d33-90/%d92-126) *any LineEnd 9 | ValueArray = Value *(wsp "," wsp Value) 10 | SectionName = 1*(alpha/digit/%d95) 11 | ValueName = 1*(alpha/digit/%d95) 12 | Value = (1*(alpha/digit)) / 13 | (%d34 1*(%d32-33/%d35-126) %d34) / 14 | (%d39 1*(%d32-38/%d40-126) %d39) 15 | BlankLine = wsp [comment] LineEnd 16 | LineEnd = %d13.10/%d10/%d13 17 | comment = ";" *any 18 | wsp = *(%d32/%d9) 19 | alpha = %d65-90/%d97-122 20 | digit = %d48-57 21 | any = %d32-126/%d9 22 | -------------------------------------------------------------------------------- /src/examples/inifile/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A comparison of timing and node hit statistics between 4 | the CFG and UDT parsers for 5 | the the "ini" file grammar. This is a grammar for a common initialization file format. 6 |

7 | 8 | Disclaimer: This example should not be considered as part of the Java APG API. Backward compatibility or even the existance of this example from version to version is not guaranteed. 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/examples/inifile/uinifile.bnf: -------------------------------------------------------------------------------- 1 | IniFile = *(e_comment-wsp u_lineend) *Section 2 | Section = SectionLine *((e_comment-wsp u_lineend)/ValueLine) 3 | SectionLine = GoodSectionLine/BadSectionLine 4 | GoodSectionLine = "[" e_wsp SectionName e_wsp "]" e_wsp [u_comment] u_lineend 5 | BadSectionLine = "[" e_any u_lineend; 6 | ValueLine = GoodValueLine/BadValueLine 7 | GoodValueLine = ValueName e_wsp "=" e_wsp ValueArray e_wsp [u_comment] u_lineend 8 | BadValueLine = (%d33-90/%d92-126) e_any u_lineend 9 | ValueArray = Value *(e_wsp "," e_wsp Value) 10 | SectionName = u_alphadigitunder 11 | ValueName = u_alphadigitunder 12 | Value = u_alphadigit/u_dqstring/u_sqstring 13 | -------------------------------------------------------------------------------- /src/examples/mailbox/Atom.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.mailbox; 10 | 11 | import apg.Parser; 12 | import apg.Parser.UdtCallback; 13 | 14 | class Atom extends UdtCallback { 15 | // ;Atom = 1*atext 16 | // ;atext = ALPHA / DIGIT / ; Printable US-ASCII 17 | // ; "!" / "#" / ; characters not including 18 | // ; "$" / "%" / ; specials. Used for atoms. 19 | // ; "&" / "'" / 20 | // ; "*" / "+" / 21 | // ; "-" / "/" / 22 | // ; "=" / "?" / 23 | // ; "^" / "_" / 24 | // ; "`" / "{" / 25 | // ; "|" / "}" / 26 | // ; "~" 27 | 28 | Parser parser; 29 | 30 | Atom(Parser parser) { 31 | super(parser); 32 | } 33 | 34 | @Override 35 | public int callback(int offset) { 36 | int len = 0; 37 | int i = offset; 38 | char[] in = callbackData.inputString; 39 | int inlen = callbackData.inputString.length; 40 | int c; 41 | while (true) { 42 | int digits = 0; 43 | for (; i < inlen; i++) { 44 | c = (int) in[i]; 45 | if ((c >= 97 && c <= 122) 46 | || (c >= 65 && c <= 90) 47 | || (c >= 48 && c <= 57)) { 48 | digits++; 49 | } else if (c == 33) { 50 | digits++; 51 | } else if (c >= 35 && c <= 39) { 52 | digits++; 53 | } else if (c == 42 || c == 43) { 54 | digits++; 55 | } else if (c == 45) { 56 | digits++; 57 | } else if (c == 47) { 58 | digits++; 59 | } else if (c == 61) { 60 | digits++; 61 | } else if (c == 63) { 62 | digits++; 63 | } else if (c >= 94 && c <= 96) { 64 | digits++; 65 | } else if (c >= 123 && c <= 126) { 66 | digits++; 67 | } else { 68 | break; 69 | } 70 | } 71 | if (digits == 0) { 72 | break; 73 | } 74 | len += digits; 75 | } 76 | return (len == 0) ? -1 : len; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/examples/mailbox/DContent.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.mailbox; 10 | 11 | import apg.Parser; 12 | import apg.Parser.UdtCallback; 13 | 14 | class DContent extends UdtCallback { 15 | // ;u_dcontent = 1*dcontent 16 | // ;dcontent = %d33-90 / ; Printable US-ASCII 17 | // ; %d94-126 ; excl. "[", "\", "]" 18 | 19 | DContent(Parser parser) { 20 | super(parser); 21 | } 22 | 23 | @Override 24 | public int callback(int offset) { 25 | int len = 0; 26 | int i = offset; 27 | char[] in = callbackData.inputString; 28 | int inlen = callbackData.inputString.length; 29 | int c; 30 | while (true) { 31 | int digits = 0; 32 | for (; i < inlen; i++) { 33 | c = (int) in[i]; 34 | if ((c >= 33 && c <= 90) 35 | || (c >= 94 && c <= 126)) { 36 | digits++; 37 | } else { 38 | break; 39 | } 40 | } 41 | if (digits == 0) { 42 | break; 43 | } 44 | len += digits; 45 | } 46 | return (len == 0) ? -1 : len; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/examples/mailbox/Ldh_str.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.mailbox; 10 | 11 | import apg.Parser; 12 | import apg.Parser.UdtCallback; 13 | 14 | class Ldh_str extends UdtCallback { 15 | // ;e_Ldt-str = *(Ldh-str) 16 | // ;u_Ldt-str = 1*(Ldh-str) 17 | // ;Ldh-str = *"-" 1*Let-dig 18 | 19 | private final boolean optional; 20 | 21 | public Ldh_str(Parser parser) { 22 | super(parser); 23 | this.optional = true; 24 | } 25 | 26 | public Ldh_str(Parser parser, boolean optional) { 27 | super(parser); 28 | this.optional = optional; 29 | } 30 | 31 | @Override 32 | public int callback(int offset) { 33 | int len = 0; 34 | int i = offset; 35 | char[] in = callbackData.inputString; 36 | int inlen = callbackData.inputString.length; 37 | int c; 38 | while (true) { 39 | int digits = 0; 40 | for (; i < inlen; i++) { 41 | if (callbackData.inputString[i] == '-') { 42 | digits++; 43 | } else { 44 | break; 45 | } 46 | } 47 | for (; i < inlen; i++) { 48 | c = (int) in[i]; 49 | if ((c >= 97 && c <= 122) 50 | || (c >= 65 && c <= 90) 51 | || (c >= 48 && c <= 57)) { 52 | digits++; 53 | } else { 54 | break; 55 | } 56 | } 57 | if (digits == 0) { 58 | break; 59 | } 60 | len += digits; 61 | } 62 | if (!optional && len == 0) { 63 | len = -1; 64 | } 65 | return len; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/examples/mailbox/RunMailbox.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.mailbox; 10 | 11 | import java.io.PrintStream; 12 | 13 | import apg.Parser; 14 | import apg.UdtLib.*; 15 | import examples.RunTests; 16 | 17 | /** 18 | * Uses the "mailbox" grammar from RFC 5321 for a comparison of timing and node 19 | * hits between the normal CFG grammar and the use of UDT functions. The mailbox 20 | * grammar is a generally accepted standard for the email addresses. 21 | */ 22 | public class RunMailbox extends RunTests { 23 | 24 | /** 25 | * Constructor for the test. Parameters are supplied explicitly or by 26 | * default from the command line to the driver function. 27 | * 28 | * @param testName the name of the test 29 | * @param reps the number of repetitions of the parser 30 | * @param out the output device 31 | */ 32 | public RunMailbox(String testName, int reps, PrintStream out) { 33 | super(testName, reps, out); 34 | } 35 | 36 | @Override 37 | protected void run() throws Exception { 38 | setup(); 39 | runComparisionOfCfgAndUdt(); 40 | } 41 | 42 | void setup() throws Exception { 43 | // display the title and an abstract 44 | if (testName != null) { 45 | outputTestName(); 46 | } else { 47 | throw new Exception("testName may not be null"); 48 | } 49 | outputAbstract("CFG/UDT time & statistics comparison for the email address grammar"); 50 | out.println(); 51 | 52 | // display the grammars 53 | outputCfgGrammar(); 54 | Mailbox.display(out); 55 | out.println(); 56 | outputUdtGrammar(); 57 | UMailbox.display(out); 58 | out.println(); 59 | 60 | // set up input strings 61 | if (inputStrings == null 62 | || inputStrings.length == 0 63 | || inputStrings[0] == null 64 | || inputStrings[0].length() == 0) { 65 | inputStringCount = 14; 66 | inputStrings = new String[inputStringCount]; 67 | inputStrings[0] = "test@domain.com"; 68 | inputStrings[1] = "test.middle.last@domain.com"; 69 | inputStrings[2] = "test@dom-ain.com"; 70 | inputStrings[3] = "test@dom--ain.com"; 71 | inputStrings[4] = "test@n.com"; 72 | inputStrings[5] = "test_two@domain.com"; 73 | inputStrings[6] = "\"test_two\"@domain.com"; 74 | inputStrings[7] = "test@[1111:2222:3333:4444:5555:6666:7777:8888]"; 75 | inputStrings[8] = "test@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]"; 76 | inputStrings[9] = "test@[IPv6:1111:2222:3333:4444:5555:6666::8888]"; 77 | inputStrings[10] = "test@[IPv6:1111:2222:3333:4444:5555:255.255.255.255]"; 78 | inputStrings[11] = "test@[1.2.3.4]"; 79 | inputStrings[12] = "test@[01.002.0.000]"; 80 | inputStrings[13] = "test@[301.2.3.4]"; 81 | } 82 | 83 | // CFG grammar-dependent setup 84 | int startRule = Mailbox.RuleNames.MAILBOX.ruleID(); // grammar.RuleNames.RULE.ruldID(); 85 | cfgIn = new RunInput("cfg", new Parser(Mailbox.getInstance()), startRule); 86 | 87 | // UDT grammar-dependent setup 88 | Parser udtParser = new Parser(UMailbox.getInstance()); 89 | startRule = UMailbox.RuleNames.MAILBOX.ruleID(); 90 | 91 | // UDT ids 92 | int[] ids = new int[UMailbox.udtCount]; 93 | ids[0] = UMailbox.UdtNames.U_SNUM.udtID(); 94 | ids[1] = UMailbox.UdtNames.U_IPV6_HEX.udtID(); 95 | ids[2] = UMailbox.UdtNames.U_ATOM.udtID(); 96 | ids[3] = UMailbox.UdtNames.U_DCONTENT.udtID(); 97 | ids[4] = UMailbox.UdtNames.U_LET_DIG.udtID(); 98 | ids[5] = UMailbox.UdtNames.U_STANDARDIZED_TAG.udtID(); 99 | ids[6] = UMailbox.UdtNames.E_LDH_STR.udtID(); 100 | 101 | // UDT callback functions 102 | udtParser.setUdtCallback(ids[0], new DecNum(udtParser, 1, 3, true)); 103 | udtParser.setUdtCallback(ids[1], new HexNum(udtParser, 1, 3)); 104 | udtParser.setUdtCallback(ids[2], new Atom(udtParser)); 105 | udtParser.setUdtCallback(ids[3], new DContent(udtParser)); 106 | udtParser.setUdtCallback(ids[4], new ULet_dig(udtParser)); 107 | udtParser.setUdtCallback(ids[5], new Ldh_str(udtParser, false)); 108 | udtParser.setUdtCallback(ids[6], new Ldh_str(udtParser, true)); 109 | udtIn = new RunInput("udt", udtParser, startRule); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/examples/mailbox/ULet_dig.java: -------------------------------------------------------------------------------- 1 | /* ****************************************************************************** 2 | Copyright (c) 2021, Lowell D. Thomas 3 | All rights reserved. 4 | 5 | This file is part of Java APG Version 1.1.0. 6 | Java APG Version 1.1.0 may be used under the terms of the 2-Clause BSD License. 7 | 8 | * ******************************************************************************/ 9 | package examples.mailbox; 10 | 11 | import apg.Parser; 12 | import apg.Parser.UdtCallback; 13 | 14 | class ULet_dig extends UdtCallback { 15 | // ;u_Let-dig = 1*Let-dig 16 | // ;Let-dig = ALPHA / DIGIT 17 | 18 | ULet_dig(Parser parser) { 19 | super(parser); 20 | } 21 | 22 | @Override 23 | public int callback(int offset) { 24 | int len = 0; 25 | int i = offset; 26 | char[] in = callbackData.inputString; 27 | int inlen = callbackData.inputString.length; 28 | int c; 29 | while (true) { 30 | int digits = 0; 31 | for (; i < inlen; i++) { 32 | c = (int) in[i]; 33 | if ((c >= 97 && c <= 122) 34 | || (c >= 65 && c <= 90) 35 | || (c >= 48 && c <= 57)) { 36 | digits++; 37 | } else { 38 | break; 39 | } 40 | } 41 | if (digits == 0) { 42 | break; 43 | } 44 | len += digits; 45 | } 46 | return (len == 0) ? -1 : len; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/examples/mailbox/mailbox.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; From RFC 5321 3 | ; Rules not referenced by Mailbox removed 4 | ; "atext" taken from RFC 5322 5 | ; Core rules ALPHA, DIGIT, etc. from RFC 5234 6 | ; 7 | ; 8 | Mailbox = Local-part "@" ( Domain / address-literal ) 9 | Domain = sub-domain *("." sub-domain) 10 | ;sub-domain = Let-dig [Ldh-str] 11 | sub-domain = 1*Let-dig *Ldh-str 12 | Let-dig = ALPHA / DIGIT 13 | ;Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig 14 | Ldh-str = *"-" 1*Let-dig 15 | address-literal = "[" ( IPv4-address-literal / 16 | IPv6-address-literal / 17 | General-address-literal ) "]" 18 | ; See Section 4.1.3 19 | Local-part = Dot-string / Quoted-string 20 | ; MAY be case-sensitive 21 | Dot-string = Atom *("." Atom) 22 | Atom = 1*atext 23 | Quoted-string = DQUOTE *QcontentSMTP DQUOTE 24 | QcontentSMTP = qtextSMTP / quoted-pairSMTP 25 | quoted-pairSMTP = %d92 %d32-126 26 | ; i.e., backslash followed by any ASCII 27 | ; graphic (including itself) or SPace 28 | qtextSMTP = %d32-33 / %d35-91 / %d93-126 29 | ; i.e., within a quoted string, any 30 | ; ASCII graphic or space is permitted 31 | ; without blackslash-quoting except 32 | ; double-quote and the backslash itself. 33 | IPv4-address-literal = Snum 3("." Snum) 34 | IPv6-address-literal = "IPv6:" IPv6-addr 35 | General-address-literal = Standardized-tag ":" 1*dcontent 36 | Standardized-tag = 1*Ldh-str 37 | ; Standardized-tag MUST be specified in a 38 | ; Standards-Track RFC and registered with IANA 39 | dcontent = %d33-90 / ; Printable US-ASCII 40 | %d94-126 ; excl. "[", "\", "]" 41 | Snum = 1*3DIGIT 42 | ; representing a decimal integer 43 | ; value in the range 0 through 255 44 | IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp 45 | IPv6-hex = 1*4HEXDIG 46 | IPv6-full = IPv6-hex 7(":" IPv6-hex) 47 | IPv6-comp = [IPv6-hex *5(":" IPv6-hex)] "::" 48 | [IPv6-hex *5(":" IPv6-hex)] 49 | ; The "::" represents at least 2 16-bit groups of 50 | ; zeros. No more than 6 groups in addition to the 51 | ; "::" may be present. 52 | IPv6v4-full = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal 53 | IPv6v4-comp = [IPv6-hex *3(":" IPv6-hex)] "::" 54 | [IPv6-hex *3(":" IPv6-hex) ":"] 55 | IPv4-address-literal 56 | ; The "::" represents at least 2 16-bit groups of 57 | ; zeros. No more than 4 groups in addition to the 58 | ; "::" and IPv4-address-literal may be present. 59 | ; 60 | ;RFC 5322 61 | atext = ALPHA / DIGIT / ; Printable US-ASCII 62 | "!" / "#" / ; characters not including 63 | "$" / "%" / ; specials. Used for atoms. 64 | "&" / "'" / 65 | "*" / "+" / 66 | "-" / "/" / 67 | "=" / "?" / 68 | "^" / "_" / 69 | "`" / "{" / 70 | "|" / "}" / 71 | "~" 72 | ; 73 | ;RFC 5234 ABNF January 2008 74 | ;B.1. Core Rules 75 | ; 76 | ; Certain basic rules are in uppercase, such as SP, HTAB, CRLF, DIGIT, 77 | ; ALPHA, etc. 78 | ; 79 | ALPHA = %x41-5A / %x61-7A ; A-Z / a-z 80 | DIGIT = %x30-39 81 | ; 0-9 82 | DQUOTE = %x22 83 | ; " (Double Quote) 84 | HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" 85 | -------------------------------------------------------------------------------- /src/examples/mailbox/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A comparison of timing and node hit statistics between 4 | the CFG and UDT parsers for 5 | an email address grammar. 6 | Uses the "mailbox" grammar from RFC 5321. 7 |

8 | 9 | Disclaimer: This example should not be considered as part of the Java APG API. Backward compatibility or even the existance of this example from version to version is not guaranteed. 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/examples/mailbox/umailbox.bnf: -------------------------------------------------------------------------------- 1 | ; 2 | ; From RFC 5321 3 | ; Rules not referenced by Mailbox removed 4 | ; "atext" taken from RFC 5322 5 | ; Core rules ALPHA, DIGIT, etc. from RFC 5234 6 | ; 7 | ; 8 | Mailbox = Local-part "@" Domain-part 9 | Domain-part = Domain / address-literal 10 | Domain = sub-domain *("." sub-domain) 11 | ;sub-domain = Let-dig [Ldh-str] 12 | ;sub-domain = 1*Let-dig *Ldh-str 13 | sub-domain = u_Let-dig e_Ldh-str 14 | ;Let-dig = ALPHA / DIGIT 15 | ;Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig 16 | ;Ldh-str = *"-" 1*Let-dig 17 | address-literal = "[" ( IPv4-address-literal / 18 | IPv6-address-literal / 19 | General-address-literal ) "]" 20 | ; See Section 4.1.3 21 | Local-part = Dot-string / Quoted-string 22 | ; MAY be case-sensitive 23 | Dot-string = u_Atom *("." u_Atom) 24 | ;Atom = 1*atext 25 | Quoted-string = DQUOTE *QcontentSMTP DQUOTE 26 | QcontentSMTP = qtextSMTP / quoted-pairSMTP 27 | quoted-pairSMTP = %d92 %d32-126 28 | ; i.e., backslash followed by any ASCII 29 | ; graphic (including itself) or SPace 30 | qtextSMTP = %d32-33 / %d35-91 / %d93-126 31 | ; i.e., within a quoted string, any 32 | ; ASCII graphic or space is permitted 33 | ; without blackslash-quoting except 34 | ; double-quote and the backslash itself. 35 | IPv4-address-literal = u_Snum 3("." u_Snum) 36 | IPv6-address-literal = "IPv6:" IPv6-addr 37 | ;General-address-literal = Standardized-tag ":" 1*dcontent 38 | General-address-literal = u_Standardized-tag ":" u_dcontent 39 | ;Standardized-tag = 1*Ldh-str 40 | ;Standardized-tag = u_Ldh-str 41 | ; Standardized-tag MUST be specified in a 42 | ; Standards-Track RFC and registered with IANA 43 | ;dcontent = %d33-90 / ; Printable US-ASCII 44 | ; %d94-126 ; excl. "[", "\", "]" 45 | ;Snum = 1*3DIGIT 46 | ; representing a decimal integer 47 | ; value in the range 0 through 255 48 | IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp 49 | ;IPv6-hex = 1*4HEXDIG 50 | IPv6-full = u_IPv6-hex 7(":" u_IPv6-hex) 51 | IPv6-comp = [u_IPv6-hex *5(":" u_IPv6-hex)] compression 52 | [u_IPv6-hex *5(":" u_IPv6-hex)] 53 | ; The "::" represents at least 2 16-bit groups of 54 | ; zeros. No more than 6 groups in addition to the 55 | ; "::" may be present. 56 | compression = "::"; 57 | IPv6v4-full = u_IPv6-hex 5(":" u_IPv6-hex) ":" IPv4-address-literal 58 | IPv6v4-comp = [u_IPv6-hex *3(":" u_IPv6-hex)] "::" 59 | [u_IPv6-hex *3(":" u_IPv6-hex) ":"] 60 | IPv4-address-literal 61 | ; The "::" represents at least 2 16-bit groups of 62 | ; zeros. No more than 4 groups in addition to the 63 | ; "::" and IPv4-address-literal may be present. 64 | ; 65 | ;RFC 5322 66 | ;atext = ALPHA / DIGIT / ; Printable US-ASCII 67 | ; "!" / "#" / ; characters not including 68 | ; "$" / "%" / ; specials. Used for atoms. 69 | ; "&" / "'" / 70 | ; "*" / "+" / 71 | ; "-" / "/" / 72 | ; "=" / "?" / 73 | ; "^" / "_" / 74 | ; "`" / "{" / 75 | ; "|" / "}" / 76 | ; "~" 77 | ; 78 | ;RFC 5234 ABNF January 2008 79 | ;B.1. Core Rules 80 | ; 81 | ; Certain basic rules are in uppercase, such as SP, HTAB, CRLF, DIGIT, 82 | ; ALPHA, etc. 83 | ; 84 | ;ALPHA = %x41-5A / %x61-7A ; A-Z / a-z 85 | ;DIGIT = %x30-39 86 | ; 0-9 87 | DQUOTE = %x22 88 | ; " (Double Quote) 89 | ;HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" 90 | -------------------------------------------------------------------------------- /src/examples/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | This is the main driver function for all of the following Java APG test examples. 4 | The examples themselves are in the examples sub-packages. 5 | The source code should be consulted for details. 6 |

7 | 8 | Disclaimer: This example should not be considered as part of the Java APG API. Backward compatibility or even the existance of this example from version to version is not guaranteed. 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/examples/testudtlib/Alphanum.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.testudtlib; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class Alphanum extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new Alphanum(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 1; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "alphanum" */ 38 | ALPHANUM("alphanum", 0, 0, 10); 39 | private String name; 40 | private int id; 41 | private int offset; 42 | private int count; 43 | RuleNames(String string, int id, int offset, int count){ 44 | this.name = string; 45 | this.id = id; 46 | this.offset = offset; 47 | this.count = count; 48 | } 49 | /** Associates the enum with the original grammar name of the rule it represents. 50 | * @return the original grammar rule name. */ 51 | public String ruleName(){return name;} 52 | /** Associates the enum with an identifier for the grammar rule it represents. 53 | * @return the rule name identifier. */ 54 | public int ruleID(){return id;} 55 | private int opcodeOffset(){return offset;} 56 | private int opcodeCount(){return count;} 57 | } 58 | 59 | // UDT name enum 60 | /** The number of UDTs in the grammar */ 61 | public static int udtCount = 0; 62 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 63 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 64 | public enum UdtNames{ 65 | } 66 | 67 | // private 68 | private static Alphanum factoryInstance = null; 69 | private Alphanum(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 70 | super(rules, udts, opcodes); 71 | } 72 | 73 | private static Rule[] getRules(){ 74 | Rule[] rules = new Rule[1]; 75 | for(RuleNames r : RuleNames.values()){ 76 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 77 | } 78 | return rules; 79 | } 80 | 81 | private static Udt[] getUdts(){ 82 | Udt[] udts = new Udt[0]; 83 | return udts; 84 | } 85 | 86 | // opcodes 87 | private static Opcode[] getOpcodes(){ 88 | Opcode[] op = new Opcode[10]; 89 | addOpcodes00(op); 90 | return op; 91 | } 92 | 93 | private static void addOpcodes00(Opcode[] op){ 94 | {int[] a = {1,4}; op[0] = getOpcodeCat(a);} 95 | {int[] a = {2,3}; op[1] = getOpcodeAlt(a);} 96 | op[2] = getOpcodeTrg((char)65, (char)90); 97 | op[3] = getOpcodeTrg((char)97, (char)122); 98 | op[4] = getOpcodeRep((char)0, Character.MAX_VALUE, 5); 99 | {int[] a = {6,7,8,9}; op[5] = getOpcodeAlt(a);} 100 | op[6] = getOpcodeTrg((char)65, (char)90); 101 | op[7] = getOpcodeTrg((char)97, (char)122); 102 | op[8] = getOpcodeTrg((char)48, (char)57); 103 | {char[] a = {95}; op[9] = getOpcodeTbs(a);} 104 | } 105 | 106 | /** Displays the original SABNF grammar on the output device. 107 | * @param out the output device to display on.*/ 108 | public static void display(PrintStream out){ 109 | out.println(";"); 110 | out.println("; examples.testudtlib.Alphanum"); 111 | out.println(";"); 112 | out.println("alphanum = (%d65-90 / %d97-122) *(%d65-90 / %d97-122 / %d48-57 / %d95)"); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/examples/testudtlib/AnyString.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.testudtlib; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class AnyString extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new AnyString(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 2; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 1, name = "any" */ 38 | ANY("any", 1, 2, 3), 39 | /** id = 0, name = "AnyString" */ 40 | ANYSTRING("AnyString", 0, 0, 2); 41 | private String name; 42 | private int id; 43 | private int offset; 44 | private int count; 45 | RuleNames(String string, int id, int offset, int count){ 46 | this.name = string; 47 | this.id = id; 48 | this.offset = offset; 49 | this.count = count; 50 | } 51 | /** Associates the enum with the original grammar name of the rule it represents. 52 | * @return the original grammar rule name. */ 53 | public String ruleName(){return name;} 54 | /** Associates the enum with an identifier for the grammar rule it represents. 55 | * @return the rule name identifier. */ 56 | public int ruleID(){return id;} 57 | private int opcodeOffset(){return offset;} 58 | private int opcodeCount(){return count;} 59 | } 60 | 61 | // UDT name enum 62 | /** The number of UDTs in the grammar */ 63 | public static int udtCount = 0; 64 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 65 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 66 | public enum UdtNames{ 67 | } 68 | 69 | // private 70 | private static AnyString factoryInstance = null; 71 | private AnyString(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 72 | super(rules, udts, opcodes); 73 | } 74 | 75 | private static Rule[] getRules(){ 76 | Rule[] rules = new Rule[2]; 77 | for(RuleNames r : RuleNames.values()){ 78 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 79 | } 80 | return rules; 81 | } 82 | 83 | private static Udt[] getUdts(){ 84 | Udt[] udts = new Udt[0]; 85 | return udts; 86 | } 87 | 88 | // opcodes 89 | private static Opcode[] getOpcodes(){ 90 | Opcode[] op = new Opcode[5]; 91 | addOpcodes00(op); 92 | return op; 93 | } 94 | 95 | private static void addOpcodes00(Opcode[] op){ 96 | op[0] = getOpcodeRep((char)0, Character.MAX_VALUE, 1); 97 | op[1] = getOpcodeRnm(1, 2); // any 98 | {int[] a = {3,4}; op[2] = getOpcodeAlt(a);} 99 | op[3] = getOpcodeTrg((char)32, (char)126); 100 | {char[] a = {9}; op[4] = getOpcodeTbs(a);} 101 | } 102 | 103 | /** Displays the original SABNF grammar on the output device. 104 | * @param out the output device to display on.*/ 105 | public static void display(PrintStream out){ 106 | out.println(";"); 107 | out.println("; examples.testudtlib.AnyString"); 108 | out.println(";"); 109 | out.println("AnyString = *any"); 110 | out.println("any = %d32-126 /%d9"); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/examples/testudtlib/Comment.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.testudtlib; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class Comment extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new Comment(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 5; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 3, name = "any" */ 38 | ANY("any", 3, 16, 3), 39 | /** id = 4, name = "anyLF" */ 40 | ANYLF("anyLF", 4, 19, 5), 41 | /** id = 2, name = "c-comment" */ 42 | C_COMMENT("c-comment", 2, 8, 8), 43 | /** id = 1, name = "cpp-comment" */ 44 | CPP_COMMENT("cpp-comment", 1, 4, 4), 45 | /** id = 0, name = "semi-comment" */ 46 | SEMI_COMMENT("semi-comment", 0, 0, 4); 47 | private String name; 48 | private int id; 49 | private int offset; 50 | private int count; 51 | RuleNames(String string, int id, int offset, int count){ 52 | this.name = string; 53 | this.id = id; 54 | this.offset = offset; 55 | this.count = count; 56 | } 57 | /** Associates the enum with the original grammar name of the rule it represents. 58 | * @return the original grammar rule name. */ 59 | public String ruleName(){return name;} 60 | /** Associates the enum with an identifier for the grammar rule it represents. 61 | * @return the rule name identifier. */ 62 | public int ruleID(){return id;} 63 | private int opcodeOffset(){return offset;} 64 | private int opcodeCount(){return count;} 65 | } 66 | 67 | // UDT name enum 68 | /** The number of UDTs in the grammar */ 69 | public static int udtCount = 0; 70 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 71 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 72 | public enum UdtNames{ 73 | } 74 | 75 | // private 76 | private static Comment factoryInstance = null; 77 | private Comment(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 78 | super(rules, udts, opcodes); 79 | } 80 | 81 | private static Rule[] getRules(){ 82 | Rule[] rules = new Rule[5]; 83 | for(RuleNames r : RuleNames.values()){ 84 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 85 | } 86 | return rules; 87 | } 88 | 89 | private static Udt[] getUdts(){ 90 | Udt[] udts = new Udt[0]; 91 | return udts; 92 | } 93 | 94 | // opcodes 95 | private static Opcode[] getOpcodes(){ 96 | Opcode[] op = new Opcode[24]; 97 | addOpcodes00(op); 98 | return op; 99 | } 100 | 101 | private static void addOpcodes00(Opcode[] op){ 102 | {int[] a = {1,2}; op[0] = getOpcodeCat(a);} 103 | {char[] a = {59}; op[1] = getOpcodeTls(a);} 104 | op[2] = getOpcodeRep((char)0, Character.MAX_VALUE, 3); 105 | op[3] = getOpcodeRnm(3, 16); // any 106 | {int[] a = {5,6}; op[4] = getOpcodeCat(a);} 107 | {char[] a = {47,47}; op[5] = getOpcodeTls(a);} 108 | op[6] = getOpcodeRep((char)0, Character.MAX_VALUE, 7); 109 | op[7] = getOpcodeRnm(3, 16); // any 110 | {int[] a = {9,10,15}; op[8] = getOpcodeCat(a);} 111 | {char[] a = {47,42}; op[9] = getOpcodeTls(a);} 112 | op[10] = getOpcodeRep((char)0, Character.MAX_VALUE, 11); 113 | {int[] a = {12,14}; op[11] = getOpcodeCat(a);} 114 | op[12] = getOpcodeNot(13); 115 | {char[] a = {42,47}; op[13] = getOpcodeTls(a);} 116 | op[14] = getOpcodeRnm(4, 19); // anyLF 117 | {char[] a = {42,47}; op[15] = getOpcodeTls(a);} 118 | {int[] a = {17,18}; op[16] = getOpcodeAlt(a);} 119 | op[17] = getOpcodeTrg((char)32, (char)126); 120 | {char[] a = {9}; op[18] = getOpcodeTbs(a);} 121 | {int[] a = {20,21,22,23}; op[19] = getOpcodeAlt(a);} 122 | op[20] = getOpcodeTrg((char)32, (char)126); 123 | {char[] a = {9}; op[21] = getOpcodeTbs(a);} 124 | {char[] a = {10}; op[22] = getOpcodeTbs(a);} 125 | {char[] a = {13}; op[23] = getOpcodeTbs(a);} 126 | } 127 | 128 | /** Displays the original SABNF grammar on the output device. 129 | * @param out the output device to display on.*/ 130 | public static void display(PrintStream out){ 131 | out.println(";"); 132 | out.println("; examples.testudtlib.Comment"); 133 | out.println(";"); 134 | out.println("semi-comment = \";\" *any ; semi comment"); 135 | out.println("cpp-comment = \"//\" *any ; C++ comment"); 136 | out.println("c-comment = \"/*\" *(!\"*/\" anyLF) \"*/\" ; C comment"); 137 | out.println("any = %d32-126 / %d9"); 138 | out.println("anyLF = %d32-126 / %d9 / %d10 / %d13 "); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/examples/testudtlib/DecNum.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.testudtlib; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class DecNum extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new DecNum(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 2; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "decnum" */ 38 | DECNUM("decnum", 0, 0, 2), 39 | /** id = 1, name = "DIGIT" */ 40 | DIGIT("DIGIT", 1, 2, 1); 41 | private String name; 42 | private int id; 43 | private int offset; 44 | private int count; 45 | RuleNames(String string, int id, int offset, int count){ 46 | this.name = string; 47 | this.id = id; 48 | this.offset = offset; 49 | this.count = count; 50 | } 51 | /** Associates the enum with the original grammar name of the rule it represents. 52 | * @return the original grammar rule name. */ 53 | public String ruleName(){return name;} 54 | /** Associates the enum with an identifier for the grammar rule it represents. 55 | * @return the rule name identifier. */ 56 | public int ruleID(){return id;} 57 | private int opcodeOffset(){return offset;} 58 | private int opcodeCount(){return count;} 59 | } 60 | 61 | // UDT name enum 62 | /** The number of UDTs in the grammar */ 63 | public static int udtCount = 0; 64 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 65 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 66 | public enum UdtNames{ 67 | } 68 | 69 | // private 70 | private static DecNum factoryInstance = null; 71 | private DecNum(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 72 | super(rules, udts, opcodes); 73 | } 74 | 75 | private static Rule[] getRules(){ 76 | Rule[] rules = new Rule[2]; 77 | for(RuleNames r : RuleNames.values()){ 78 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 79 | } 80 | return rules; 81 | } 82 | 83 | private static Udt[] getUdts(){ 84 | Udt[] udts = new Udt[0]; 85 | return udts; 86 | } 87 | 88 | // opcodes 89 | private static Opcode[] getOpcodes(){ 90 | Opcode[] op = new Opcode[3]; 91 | addOpcodes00(op); 92 | return op; 93 | } 94 | 95 | private static void addOpcodes00(Opcode[] op){ 96 | op[0] = getOpcodeRep((char)0, Character.MAX_VALUE, 1); 97 | op[1] = getOpcodeRnm(1, 2); // DIGIT 98 | op[2] = getOpcodeTrg((char)48, (char)57); 99 | } 100 | 101 | /** Displays the original SABNF grammar on the output device. 102 | * @param out the output device to display on.*/ 103 | public static void display(PrintStream out){ 104 | out.println(";"); 105 | out.println("; examples.testudtlib.DecNum"); 106 | out.println(";"); 107 | out.println("decnum = *DIGIT"); 108 | out.println("DIGIT = %d48-57"); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/examples/testudtlib/HexNum.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.testudtlib; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class HexNum extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new HexNum(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 4; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 2, name = "ALPHA" */ 38 | ALPHA("ALPHA", 2, 11, 4), 39 | /** id = 3, name = "DIGIT" */ 40 | DIGIT("DIGIT", 3, 15, 1), 41 | /** id = 1, name = "HEXDIGIT" */ 42 | HEXDIGIT("HEXDIGIT", 1, 2, 9), 43 | /** id = 0, name = "hexnum" */ 44 | HEXNUM("hexnum", 0, 0, 2); 45 | private String name; 46 | private int id; 47 | private int offset; 48 | private int count; 49 | RuleNames(String string, int id, int offset, int count){ 50 | this.name = string; 51 | this.id = id; 52 | this.offset = offset; 53 | this.count = count; 54 | } 55 | /** Associates the enum with the original grammar name of the rule it represents. 56 | * @return the original grammar rule name. */ 57 | public String ruleName(){return name;} 58 | /** Associates the enum with an identifier for the grammar rule it represents. 59 | * @return the rule name identifier. */ 60 | public int ruleID(){return id;} 61 | private int opcodeOffset(){return offset;} 62 | private int opcodeCount(){return count;} 63 | } 64 | 65 | // UDT name enum 66 | /** The number of UDTs in the grammar */ 67 | public static int udtCount = 0; 68 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 69 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 70 | public enum UdtNames{ 71 | } 72 | 73 | // private 74 | private static HexNum factoryInstance = null; 75 | private HexNum(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 76 | super(rules, udts, opcodes); 77 | } 78 | 79 | private static Rule[] getRules(){ 80 | Rule[] rules = new Rule[4]; 81 | for(RuleNames r : RuleNames.values()){ 82 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 83 | } 84 | return rules; 85 | } 86 | 87 | private static Udt[] getUdts(){ 88 | Udt[] udts = new Udt[0]; 89 | return udts; 90 | } 91 | 92 | // opcodes 93 | private static Opcode[] getOpcodes(){ 94 | Opcode[] op = new Opcode[16]; 95 | addOpcodes00(op); 96 | return op; 97 | } 98 | 99 | private static void addOpcodes00(Opcode[] op){ 100 | op[0] = getOpcodeRep((char)1, Character.MAX_VALUE, 1); 101 | op[1] = getOpcodeRnm(1, 2); // HEXDIGIT 102 | {int[] a = {3,4,5,6,7,8,9,10}; op[2] = getOpcodeAlt(a);} 103 | op[3] = getOpcodeRnm(2, 11); // ALPHA 104 | op[4] = getOpcodeRnm(3, 15); // DIGIT 105 | {char[] a = {65}; op[5] = getOpcodeTls(a);} 106 | {char[] a = {66}; op[6] = getOpcodeTls(a);} 107 | {char[] a = {67}; op[7] = getOpcodeTls(a);} 108 | {char[] a = {68}; op[8] = getOpcodeTls(a);} 109 | {char[] a = {69}; op[9] = getOpcodeTls(a);} 110 | {char[] a = {70}; op[10] = getOpcodeTls(a);} 111 | {int[] a = {12,13,14}; op[11] = getOpcodeAlt(a);} 112 | op[12] = getOpcodeTrg((char)65, (char)90); 113 | op[13] = getOpcodeTrg((char)97, (char)122); 114 | {char[] a = {95}; op[14] = getOpcodeTbs(a);} 115 | op[15] = getOpcodeTrg((char)48, (char)57); 116 | } 117 | 118 | /** Displays the original SABNF grammar on the output device. 119 | * @param out the output device to display on.*/ 120 | public static void display(PrintStream out){ 121 | out.println(";"); 122 | out.println("; examples.testudtlib.HexNum"); 123 | out.println(";"); 124 | out.println("hexnum = 1*HEXDIGIT"); 125 | out.println("HEXDIGIT = ALPHA / DIGIT / \"A\" / \"B\" / \"C\" / \"D\" / \"E\" / \"F\""); 126 | out.println("ALPHA = %d65-90 / %d97-122 / %d95"); 127 | out.println("DIGIT = %d48-57"); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/examples/testudtlib/LineEnd.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.testudtlib; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class LineEnd extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new LineEnd(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 3; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 2, name = "crlf-lineend" */ 38 | CRLF_LINEEND("crlf-lineend", 2, 5, 1), 39 | /** id = 0, name = "forgiving-lineend" */ 40 | FORGIVING_LINEEND("forgiving-lineend", 0, 0, 4), 41 | /** id = 1, name = "lf-lineend" */ 42 | LF_LINEEND("lf-lineend", 1, 4, 1); 43 | private String name; 44 | private int id; 45 | private int offset; 46 | private int count; 47 | RuleNames(String string, int id, int offset, int count){ 48 | this.name = string; 49 | this.id = id; 50 | this.offset = offset; 51 | this.count = count; 52 | } 53 | /** Associates the enum with the original grammar name of the rule it represents. 54 | * @return the original grammar rule name. */ 55 | public String ruleName(){return name;} 56 | /** Associates the enum with an identifier for the grammar rule it represents. 57 | * @return the rule name identifier. */ 58 | public int ruleID(){return id;} 59 | private int opcodeOffset(){return offset;} 60 | private int opcodeCount(){return count;} 61 | } 62 | 63 | // UDT name enum 64 | /** The number of UDTs in the grammar */ 65 | public static int udtCount = 0; 66 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 67 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 68 | public enum UdtNames{ 69 | } 70 | 71 | // private 72 | private static LineEnd factoryInstance = null; 73 | private LineEnd(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 74 | super(rules, udts, opcodes); 75 | } 76 | 77 | private static Rule[] getRules(){ 78 | Rule[] rules = new Rule[3]; 79 | for(RuleNames r : RuleNames.values()){ 80 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 81 | } 82 | return rules; 83 | } 84 | 85 | private static Udt[] getUdts(){ 86 | Udt[] udts = new Udt[0]; 87 | return udts; 88 | } 89 | 90 | // opcodes 91 | private static Opcode[] getOpcodes(){ 92 | Opcode[] op = new Opcode[6]; 93 | addOpcodes00(op); 94 | return op; 95 | } 96 | 97 | private static void addOpcodes00(Opcode[] op){ 98 | {int[] a = {1,2,3}; op[0] = getOpcodeAlt(a);} 99 | {char[] a = {10}; op[1] = getOpcodeTbs(a);} 100 | {char[] a = {13,10}; op[2] = getOpcodeTbs(a);} 101 | {char[] a = {13}; op[3] = getOpcodeTbs(a);} 102 | {char[] a = {10}; op[4] = getOpcodeTbs(a);} 103 | {char[] a = {13,10}; op[5] = getOpcodeTbs(a);} 104 | } 105 | 106 | /** Displays the original SABNF grammar on the output device. 107 | * @param out the output device to display on.*/ 108 | public static void display(PrintStream out){ 109 | out.println(";"); 110 | out.println("; examples.testudtlib.LineEnd"); 111 | out.println(";"); 112 | out.println("forgiving-lineend = %d10 / %d13.10 / %d13"); 113 | out.println("lf-lineend = %d10"); 114 | out.println("crlf-lineend = %d13.10"); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/examples/testudtlib/QuotedString.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.testudtlib; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class QuotedString extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new QuotedString(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 1; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "qstring" */ 38 | QSTRING("qstring", 0, 0, 8); 39 | private String name; 40 | private int id; 41 | private int offset; 42 | private int count; 43 | RuleNames(String string, int id, int offset, int count){ 44 | this.name = string; 45 | this.id = id; 46 | this.offset = offset; 47 | this.count = count; 48 | } 49 | /** Associates the enum with the original grammar name of the rule it represents. 50 | * @return the original grammar rule name. */ 51 | public String ruleName(){return name;} 52 | /** Associates the enum with an identifier for the grammar rule it represents. 53 | * @return the rule name identifier. */ 54 | public int ruleID(){return id;} 55 | private int opcodeOffset(){return offset;} 56 | private int opcodeCount(){return count;} 57 | } 58 | 59 | // UDT name enum 60 | /** The number of UDTs in the grammar */ 61 | public static int udtCount = 0; 62 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 63 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 64 | public enum UdtNames{ 65 | } 66 | 67 | // private 68 | private static QuotedString factoryInstance = null; 69 | private QuotedString(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 70 | super(rules, udts, opcodes); 71 | } 72 | 73 | private static Rule[] getRules(){ 74 | Rule[] rules = new Rule[1]; 75 | for(RuleNames r : RuleNames.values()){ 76 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 77 | } 78 | return rules; 79 | } 80 | 81 | private static Udt[] getUdts(){ 82 | Udt[] udts = new Udt[0]; 83 | return udts; 84 | } 85 | 86 | // opcodes 87 | private static Opcode[] getOpcodes(){ 88 | Opcode[] op = new Opcode[8]; 89 | addOpcodes00(op); 90 | return op; 91 | } 92 | 93 | private static void addOpcodes00(Opcode[] op){ 94 | {int[] a = {1,2,7}; op[0] = getOpcodeCat(a);} 95 | {char[] a = {34}; op[1] = getOpcodeTbs(a);} 96 | op[2] = getOpcodeRep((char)0, Character.MAX_VALUE, 3); 97 | {int[] a = {4,5,6}; op[3] = getOpcodeAlt(a);} 98 | op[4] = getOpcodeTrg((char)32, (char)33); 99 | op[5] = getOpcodeTrg((char)35, (char)126); 100 | {char[] a = {9}; op[6] = getOpcodeTbs(a);} 101 | {char[] a = {34}; op[7] = getOpcodeTbs(a);} 102 | } 103 | 104 | /** Displays the original SABNF grammar on the output device. 105 | * @param out the output device to display on.*/ 106 | public static void display(PrintStream out){ 107 | out.println(";"); 108 | out.println("; examples.testudtlib.QuotedString"); 109 | out.println(";"); 110 | out.println("qstring = %d34 *(%d32-33 / %d35-126 / %d9) %d34"); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/examples/testudtlib/UEmpty.bnf: -------------------------------------------------------------------------------- 1 | udt = e_udt -------------------------------------------------------------------------------- /src/examples/testudtlib/UEmpty.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.testudtlib; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class UEmpty extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new UEmpty(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 1; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "udt" */ 38 | UDT("udt", 0, 0, 1); 39 | private String name; 40 | private int id; 41 | private int offset; 42 | private int count; 43 | RuleNames(String string, int id, int offset, int count){ 44 | this.name = string; 45 | this.id = id; 46 | this.offset = offset; 47 | this.count = count; 48 | } 49 | /** Associates the enum with the original grammar name of the rule it represents. 50 | * @return the original grammar rule name. */ 51 | public String ruleName(){return name;} 52 | /** Associates the enum with an identifier for the grammar rule it represents. 53 | * @return the rule name identifier. */ 54 | public int ruleID(){return id;} 55 | private int opcodeOffset(){return offset;} 56 | private int opcodeCount(){return count;} 57 | } 58 | 59 | // UDT name enum 60 | /** The number of UDTs in the grammar */ 61 | public static int udtCount = 1; 62 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 63 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 64 | public enum UdtNames{ 65 | /** id = 0, name = "e_udt" */ 66 | E_UDT(0, "e_udt", true); 67 | private String name; 68 | private int id; 69 | private boolean empty; 70 | UdtNames(int id, String string, boolean empty){ 71 | this.name = string; 72 | this.id = id; 73 | this.empty = empty; 74 | } 75 | /** Associates the enum with the original grammar name of the UDT it represents. 76 | * @return the original grammar UDT name. */ 77 | public String udtName(){return name;} 78 | /** Associates the enum with an identifier for the UDT it represents. 79 | * @return the UDT identifier. */ 80 | public int udtID(){return id;} 81 | /** Associates the enum with the "empty" attribute of the UDT it represents. 82 | * @return the "empty" attribute. 83 | * True if the UDT name begins with "e_", false if it begins with "u_". */ 84 | public boolean udtMayBeEmpty(){return empty;} 85 | } 86 | 87 | // private 88 | private static UEmpty factoryInstance = null; 89 | private UEmpty(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 90 | super(rules, udts, opcodes); 91 | } 92 | 93 | private static Rule[] getRules(){ 94 | Rule[] rules = new Rule[1]; 95 | for(RuleNames r : RuleNames.values()){ 96 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 97 | } 98 | return rules; 99 | } 100 | 101 | private static Udt[] getUdts(){ 102 | Udt[] udts = new Udt[1]; 103 | for(UdtNames r : UdtNames.values()){ 104 | udts[r.udtID()] = getUdt(r.udtID(), r.udtName(), r.udtMayBeEmpty()); 105 | } 106 | return udts; 107 | } 108 | 109 | // opcodes 110 | private static Opcode[] getOpcodes(){ 111 | Opcode[] op = new Opcode[1]; 112 | addOpcodes00(op); 113 | return op; 114 | } 115 | 116 | private static void addOpcodes00(Opcode[] op){ 117 | op[0] = getOpcodeUdt(0); // e_udt 118 | } 119 | 120 | /** Displays the original SABNF grammar on the output device. 121 | * @param out the output device to display on.*/ 122 | public static void display(PrintStream out){ 123 | out.println(";"); 124 | out.println("; examples.testudtlib.UEmpty"); 125 | out.println(";"); 126 | out.println("udt = e_udt"); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/examples/testudtlib/UNonEmpty.bnf: -------------------------------------------------------------------------------- 1 | udt = u_udt -------------------------------------------------------------------------------- /src/examples/testudtlib/UNonEmpty.java: -------------------------------------------------------------------------------- 1 | // This class has been generated automatically 2 | // from an SABNF grammar by Java APG, Verision 1.1.0. 3 | // Copyright (c) 2021 Lowell D. Thomas, all rights reserved. 4 | // Licensed under the 2-Clause BSD License. 5 | 6 | package examples.testudtlib; 7 | 8 | import apg.Grammar; 9 | import java.io.PrintStream; 10 | /** This class has been generated automatically from an SABNF grammar by 11 | * the {@link apg.Generator} class of Java APG, Version 1.1.0.
12 | * It is an extension of the {@link apg.Grammar} 13 | * class containing additional members and enums not found 14 | * in the base class.
15 | * The function {@link #getInstance()} will return a reference to a static, 16 | * singleton instance of the class. 17 | */ 18 | 19 | public class UNonEmpty extends Grammar{ 20 | 21 | // public API 22 | /** Called to get a singleton instance of this class. 23 | * @return a singleton instance of this class, cast as the base class, Grammar. */ 24 | public static Grammar getInstance(){ 25 | if(factoryInstance == null){ 26 | factoryInstance = new UNonEmpty(getRules(), getUdts(), getOpcodes()); 27 | } 28 | return factoryInstance; 29 | } 30 | 31 | // rule name enum 32 | /** The number of rules in the grammar */ 33 | public static int ruleCount = 1; 34 | /** This enum provides easy to remember enum constants for locating the rule identifiers and names. 35 | * The enum constants have the same spelling as the rule names rendered in all caps with underscores replacing hyphens. */ 36 | public enum RuleNames{ 37 | /** id = 0, name = "udt" */ 38 | UDT("udt", 0, 0, 1); 39 | private String name; 40 | private int id; 41 | private int offset; 42 | private int count; 43 | RuleNames(String string, int id, int offset, int count){ 44 | this.name = string; 45 | this.id = id; 46 | this.offset = offset; 47 | this.count = count; 48 | } 49 | /** Associates the enum with the original grammar name of the rule it represents. 50 | * @return the original grammar rule name. */ 51 | public String ruleName(){return name;} 52 | /** Associates the enum with an identifier for the grammar rule it represents. 53 | * @return the rule name identifier. */ 54 | public int ruleID(){return id;} 55 | private int opcodeOffset(){return offset;} 56 | private int opcodeCount(){return count;} 57 | } 58 | 59 | // UDT name enum 60 | /** The number of UDTs in the grammar */ 61 | public static int udtCount = 1; 62 | /** This enum provides easy to remember enum constants for locating the UDT identifiers and names. 63 | * The enum constants have the same spelling as the UDT names rendered in all caps with underscores replacing hyphens. */ 64 | public enum UdtNames{ 65 | /** id = 0, name = "u_udt" */ 66 | U_UDT(0, "u_udt", false); 67 | private String name; 68 | private int id; 69 | private boolean empty; 70 | UdtNames(int id, String string, boolean empty){ 71 | this.name = string; 72 | this.id = id; 73 | this.empty = empty; 74 | } 75 | /** Associates the enum with the original grammar name of the UDT it represents. 76 | * @return the original grammar UDT name. */ 77 | public String udtName(){return name;} 78 | /** Associates the enum with an identifier for the UDT it represents. 79 | * @return the UDT identifier. */ 80 | public int udtID(){return id;} 81 | /** Associates the enum with the "empty" attribute of the UDT it represents. 82 | * @return the "empty" attribute. 83 | * True if the UDT name begins with "e_", false if it begins with "u_". */ 84 | public boolean udtMayBeEmpty(){return empty;} 85 | } 86 | 87 | // private 88 | private static UNonEmpty factoryInstance = null; 89 | private UNonEmpty(Rule[] rules, Udt[] udts, Opcode[] opcodes){ 90 | super(rules, udts, opcodes); 91 | } 92 | 93 | private static Rule[] getRules(){ 94 | Rule[] rules = new Rule[1]; 95 | for(RuleNames r : RuleNames.values()){ 96 | rules[r.ruleID()] = getRule(r.ruleID(), r.ruleName(), r.opcodeOffset(), r.opcodeCount()); 97 | } 98 | return rules; 99 | } 100 | 101 | private static Udt[] getUdts(){ 102 | Udt[] udts = new Udt[1]; 103 | for(UdtNames r : UdtNames.values()){ 104 | udts[r.udtID()] = getUdt(r.udtID(), r.udtName(), r.udtMayBeEmpty()); 105 | } 106 | return udts; 107 | } 108 | 109 | // opcodes 110 | private static Opcode[] getOpcodes(){ 111 | Opcode[] op = new Opcode[1]; 112 | addOpcodes00(op); 113 | return op; 114 | } 115 | 116 | private static void addOpcodes00(Opcode[] op){ 117 | op[0] = getOpcodeUdt(0); // u_udt 118 | } 119 | 120 | /** Displays the original SABNF grammar on the output device. 121 | * @param out the output device to display on.*/ 122 | public static void display(PrintStream out){ 123 | out.println(";"); 124 | out.println("; examples.testudtlib.UNonEmpty"); 125 | out.println(";"); 126 | out.println("udt = u_udt"); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/examples/testudtlib/alphanum.bnf: -------------------------------------------------------------------------------- 1 | alphanum = (%d65-90 / %d97-122) *(%d65-90 / %d97-122 / %d48-57 / %d95) 2 | -------------------------------------------------------------------------------- /src/examples/testudtlib/any.bnf: -------------------------------------------------------------------------------- 1 | AnyString = *any 2 | any = %d32-126 /%d9 3 | 4 | -------------------------------------------------------------------------------- /src/examples/testudtlib/comment.bnf: -------------------------------------------------------------------------------- 1 | semi-comment = ";" *any ; semi comment 2 | cpp-comment = "//" *any ; C++ comment 3 | c-comment = "/*" *(!"*/" anyLF) "*/" ; C comment 4 | any = %d32-126 / %d9 5 | anyLF = %d32-126 / %d9 / %d10 / %d13 -------------------------------------------------------------------------------- /src/examples/testudtlib/decnum.bnf: -------------------------------------------------------------------------------- 1 | decnum = *DIGIT 2 | DIGIT = %d48-57 3 | -------------------------------------------------------------------------------- /src/examples/testudtlib/hexnum.bnf: -------------------------------------------------------------------------------- 1 | hexnum = 1*HEXDIGIT 2 | HEXDIGIT = ALPHA / DIGIT / "A" / "B" / "C" / "D" / "E" / "F" 3 | ALPHA = %d65-90 / %d97-122 / %d95 4 | DIGIT = %d48-57 5 | -------------------------------------------------------------------------------- /src/examples/testudtlib/lineend.bnf: -------------------------------------------------------------------------------- 1 | forgiving-lineend = %d10 / %d13.10 / %d13 2 | lf-lineend = %d10 3 | crlf-lineend = %d13.10 4 | -------------------------------------------------------------------------------- /src/examples/testudtlib/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A comparison of timing and node hit statistics between 4 | the CFG and UDT parsers for 5 | the suite of UdtLib UDTs. 6 |

7 | 8 | Disclaimer: This example should not be considered as part of the Java APG API. Backward compatibility or even the existance of this example from version to version is not guaranteed. 9 | ersion is not guaranteed. 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/examples/testudtlib/quotedstring.bnf: -------------------------------------------------------------------------------- 1 | qstring = %d34 *(%d32-33 / %d35-126 / %d9) %d34 2 | -------------------------------------------------------------------------------- /src/examples/testudtlib/whitespace.bnf: -------------------------------------------------------------------------------- 1 | FWSP-COMMENT = 1*(SP / comment / F-SP) ; white space includes comments and folding white space 2 | WSP-COMMENT = 1*(SP / comment) ; white space includes comments 3 | FWSP = 1*(SP / F-SP) ; white space includes folding white space 4 | OWSP = *SP ; optional white space 5 | WSP = 1*SP ; white space (at least one space required) 6 | F-SP = (LF / CRLF / CR) SP ; folding white space - line end followed by a single space 7 | comment = ";" *any ; comment - semicolon to end of line 8 | any = %d32-126 ; any printing character 9 | SP = %d32 / %d9 ; space - space or horizontal tab 10 | LF = %d10 ; line feed 11 | CR = %d13 ; carriage return 12 | CRLF = %d13.10 ; carriage return / line feed pair --------------------------------------------------------------------------------