Yacker parses ABNF and generates parser executables in a variety of languages.
Yacker parses ABNF and generates parser executables in a variety of languages.
Until november 2023 an on-line HTML demonstration of Yacker was available at https://services.w3.org/yacker. But it was retired due to lack of use and maintenance.
@terminals
directive, or indicated by <terminal>
syntaxEncoding support is not consistent over the languages. 4GLs tend to have regular expression libraries that work with wide characters. The C variants, however, rely on flex
, which compiles a language specified in bytes. Thus, yacker needs to change characters (unicode codepoints) and character ranges to bytes. This process is described in Adding utf-8 Encoding to Lex. Ultimately, it means that the lex specification for the language includes the byte sequences that correspond to the utf-8 encoding of the input characters.
It is generally best to use an operating system package, e.g. libparse-yapp-perl or perl-Parse-Yapp, if one is available. If not, see these CPAN module installation instructions.
$ mkdir /tmp/yack
$ cd /tmp/yack
$ cvs -d :pserver:[email protected]:/sources/public login
enter the password:anonymous
$ cvs -Q -d :pserver:[email protected]:/sources/public co perl/modules/W3C/{Grammar,Util/{Exception,YappDriver}.pm}
$ wget -O foo.bnf http://www.w3.org/2005/01/yacker/uploads/foo/bnf
$ PERL5LIB=perl/modules perl/modules/W3C/Grammar/bin/yacker --lang=perl -s -o foo foo.bnf
$ yapp foo.yp
$ perl foo.pm
you type:word "asdf" num 100 end, carrige return, and control d.
you see: word "asdf" num 100 end
and nod sagely.
The last step will create a new file called foo.pm
which you can
$ mkdir /tmp/yacker
$ cd /tmp/yacker
$ cvs -d :pserver:[email protected]:/sources/public login
enter the password:anonymous
$ cvs -Q -d :pserver:[email protected]:/sources/public co perl/modules/W3C/{Grammar,Util/{Exception,YappDriver,W3CDebugCGI,Filter,FlavorBuffer}.pm}
$ cd perl/modules/W3C/Grammar/bin/
$ echo -e \#\!"/bin/bash\\nexport PERL5LIB=../../..\\n./yacker" > yacker.cgi
$ chmod +x yacker.cgi
$ mkdir uploads
$ chmod go+w uploads
For more instructions on CVS, see the CVS instructions.
The parsers are only designed to serve as input stream validators. You can replace the semantic actions in the grammar file, or use the as-is. To use a parser that was generated, for example, on http://www.example.com/yacker
, you can download the parser. For a perl parser called someParser, that would look like:
wget http://www.example.com/yacker/uploads/someParser/someParser.pm # or with curl: curl http://www.example.com/yacker/uploads/someParser/someParser.pm > someParser.pm
These perl modules can be used to validate some testInput
:
perl -MsomeParser -e test < testInput > /dev/null # or, if you like to see lots of XML: perl -MsomeParser -e test < testInput
More information is available in the embedded perldocs:
perldoc someParser.pm
Building yacc parsers into a large application can be tricky because the generated c file has structures that reference yacc internals. The also have lots of virtual functions so you can't fake a constructor. Yacker C++ grammars include a frob class that is desinged to interface between the intimate parser and the rest of the app. This allows the grammar file to include whatever the knowledge of your application is required in the semantic actions, and the application to include only a simple interface header.
main
.Yacker-generated parsers are designed to be used with each other and other parsers. The Makefile
uses the -p <name>
argument to build Flex/Bison source.
main
from your grammar files.#include <stdio.h> #include "SPARQL/MIN/SPARQLFrob.h" #include "test/testFrob.h" int main (int argc, char **argv) { int result; char* name; if (argc > 1) { name = "SPARQL"; SPARQLFrob spfrob; result = spfrob.parse(); } else { name = "test"; testFrob frob; result = frob.parse(); } printf("%d Parsing %s result: %s.\n", argc, name, result ? "Error" : "OK"); return result; }; extern "C" int yywrap() { return(1); }
main : main.cc SPARQL/MIN/SPARQLParser.o SPARQL/MIN/SPARQLScanner.o SPARQL/MIN/SPARQL.h test/testParser.o test/testScanner.o test/test.h g++ -Wno-deprecated -g -o $@ main.cc SPARQL/MIN/SPARQLParser.o SPARQL/MIN/SPARQLScanner.o test/testParser.o test/testScanner.o
Below is a list of things that would be nice to do to the Yacker. Help is enthusiastically rewarded and new wish list items are grudgingly accepted.