1buildrec(3)                         ANTLR3C                        buildrec(3)
2
3
4

NAME

6       buildrec - .TH "buildrec" 3 "Wed Oct 13 2010" "Version 3.1.2" "ANTLR3C"
7

NAME

9       buildrec - .SH "Generated Files"
10
11       The antlr tool jar, run against a grammar file that targets the C
12       language, will generate the following files according to whether your
13       grammar file contains a lexer, parser, combined or treeparser
14       specification. Your grammar file name and the subject of the grammar
15       line in your file are expected to match. Here the generic name G is
16       used:
17
18       Suffix  Generated files   lexer grammar (G.g3l)  GLexer.c GLexer.h
19       parser grammar (G.g3p)  GParser.c GParser.h   grammar G (G.g3pl)
20       GParser.c GParser.h GLexer.c GLexer.h  tree grammar G; (G.g3t)  G.c G.h
21
22       The generated .c files reference the .h files using <G.h>, so you must
23       use -I. on your compiler command line (or include the current directory
24       in your include paths in Visual Studio). Additionally, the generated .h
25       files reference antlr3.h, so you must use -I/path/to/antlr/include
26       (E.g. -I /usr/local/include) to reference the standard ANTLR include
27       files.
28
29       In order to reference the library file at compile time (you can/should
30       only reference one) you need to use the -L/path/to/antlr/lib (E.g. -L
31       /usr/local/lib) on Unix, or add the path to your 'Additional Library
32       Path' in Visual Studio. You also need to specify the library using -L
33       on Unix (E.g. -L /usr/local/lib -l antlr3c) or add antlr3c_dll.lib to
34       your Additional Library Dependencies in Visual Studio.
35
36       In case it isn't obvious, the generated files may be used to produce
37       either a library or an executable (.EXE on Windows) file.
38
39       If you use the shared version of the libraries, DLL or .so/.so/.a then
40       you must ship the library with your application must run in an
41       environment whereby the library can be found by the runtime
42       linker/loader. This usually involves specifying the directory in which
43       the library lives to an environment variable. On Windows,
44       X:{yourwininstalldir} will be searched automatically.
45

Invoking Your Generated Recognizer

47       In order to run your lexer/parser/tree parser combination, you will
48       need a small function (or main) function that controls the sequence of
49       events, from reading the input file or string, through to invoking the
50       tree parser(s) and retrieving the results. See 'Using the ANTLR3C C
51       Target' for more detailed instructions, but if you just want to get
52       going as fast as possible, study the following code example.
53
54        // You may adopt your own practices by all means, but in general it is best
55        // to create a single include for your project, that will include the ANTLR3 C
56        // runtime header files, the generated header files (all of which are safe to include
57        // multiple times) and your own project related header files. Use <> to include and
58        // -I on the compile line (which vs2005 now handles, where vs2003 did not).
59        //
60        #include    <treeparser.h>
61
62        // Main entry point for this example
63        //
64        int ANTLR3_CDECL
65        main   (int argc, char *argv[])
66        {
67            // Now we declare the ANTLR related local variables we need.
68            // Note that unless you are convinced you will never need thread safe
69            // versions for your project, then you should always create such things
70            // as instance variables for each invocation.
71            // -------------------
72
73            // Name of the input file. Note that we always use the abstract type pANTLR3_UINT8
74            // for ASCII/8 bit strings - the runtime library guarantees that this will be
75            // good on all platforms. This is a general rule - always use the ANTLR3 supplied
76            // typedefs for pointers/types/etc.
77            //
78            pANTLR3_UINT8      fName;
79
80            // The ANTLR3 character input stream, which abstracts the input source such that
81            // it is easy to privide inpput from different sources such as files, or
82            // memory strings.
83            //
84            // For an ASCII/latin-1 memory string use:
85            //     input = antlr3NewAsciiStringInPlaceStream (stringtouse, (ANTLR3_UINT32) length, NULL);
86            //
87            // For a UCS2 (16 bit) memory string use:
88            //     input = antlr3NewUCS2StringInPlaceStream (stringtouse, (ANTLR3_UINT32) length, NULL);
89            //
90            // For input from a file, see code below
91            //
92            // Note that this is essentially a pointer to a structure containing pointers to functions.
93            // You can create your own input stream type (copy one of the existing ones) and override any
94            // individual function by installing your own pointer after you have created the standard
95            // version.
96            //
97            pANTLR3_INPUT_STREAM       input;
98
99            // The lexer is of course generated by ANTLR, and so the lexer type is not upper case.
100            // The lexer is supplied with a pANTLR3_INPUT_STREAM from whence it consumes its
101            // input and generates a token stream as output. This is the ctx (CTX macro) pointer
102               // for your lexer.
103            //
104            pLangLexer             lxr;
105
106            // The token stream is produced by the ANTLR3 generated lexer. Again it is a structure based
107            // API/Object, which you can customise and override methods of as you wish. a Token stream is
108            // supplied to the generated parser, and you can write your own token stream and pass this in
109            // if you wish.
110            //
111            pANTLR3_COMMON_TOKEN_STREAM        tstream;
112
113            // The Lang parser is also generated by ANTLR and accepts a token stream as explained
114            // above. The token stream can be any source in fact, so long as it implements the
115            // ANTLR3_TOKEN_SOURCE interface. In this case the parser does not return anything
116            // but it can of course specify any kind of return type from the rule you invoke
117            // when calling it. This is the ctx (CTX macro) pointer for your parser.
118            //
119            pLangParser                psr;
120
121            // The parser produces an AST, which is returned as a member of the return type of
122            // the starting rule (any rule can start first of course). This is a generated type
123            // based upon the rule we start with.
124            //
125            LangParser_decl_return     langAST;
126
127
128            // The tree nodes are managed by a tree adaptor, which doles
129            // out the nodes upon request. You can make your own tree types and adaptors
130            // and override the built in versions. See runtime source for details and
131            // eventually the wiki entry for the C target.
132            //
133            pANTLR3_COMMON_TREE_NODE_STREAM    nodes;
134
135            // Finally, when the parser runs, it will produce an AST that can be traversed by the
136            // the tree parser: c.f. LangDumpDecl.g3t This is the ctx (CTX macro) pointer for your
137               // tree parser.
138            //
139            pLangDumpDecl          treePsr;
140
141            // Create the input stream based upon the argument supplied to us on the command line
142            // for this example, the input will always default to ./input if there is no explicit
143            // argument.
144            //
145           if (argc < 2 || argv[1] == NULL)
146           {
147               fName   =(pANTLR3_UINT8)'./input'; // Note in VS2005 debug, working directory must be configured
148           }
149           else
150           {
151               fName   = (pANTLR3_UINT8)argv[1];
152           }
153
154            // Create the input stream using the supplied file name
155            // (Use antlr3AsciiFileStreamNew for UCS2/16bit input).
156            //
157            input  = antlr3AsciiFileStreamNew(fName);
158
159            // The input will be created successfully, providing that there is enough
160            // memory and the file exists etc
161            //
162            if ( input == NULL )
163            {
164                   ANTLR3_FPRINTF(stderr, 'Unable to open file %s due to malloc() failure10, (char *)fName);
165            }
166
167            // Our input stream is now open and all set to go, so we can create a new instance of our
168            // lexer and set the lexer input to our input stream:
169            //  (file | memory | ?) --> inputstream -> lexer --> tokenstream --> parser ( --> treeparser )?
170            //
171            lxr        = LangLexerNew(input);      // CLexerNew is generated by ANTLR
172
173            // Need to check for errors
174            //
175            if ( lxr == NULL )
176            {
177                   ANTLR3_FPRINTF(stderr, 'Unable to create the lexer due to malloc() failure10);
178                   exit(ANTLR3_ERR_NOMEM);
179            }
180
181            // Our lexer is in place, so we can create the token stream from it
182            // NB: Nothing happens yet other than the file has been read. We are just
183            // connecting all these things together and they will be invoked when we
184            // call the parser rule. ANTLR3_SIZE_HINT can be left at the default usually
185            // unless you have a very large token stream/input. Each generated lexer
186            // provides a token source interface, which is the second argument to the
187            // token stream creator.
188            // Note tha even if you implement your own token structure, it will always
189            // contain a standard common token within it and this is the pointer that
190            // you pass around to everything else. A common token as a pointer within
191            // it that should point to your own outer token structure.
192            //
193            tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, lxr->pLexer->tokSource);
194
195            if (tstream == NULL)
196            {
197               ANTLR3_FPRINTF(stderr, 'Out of memory trying to allocate token stream0);
198               exit(ANTLR3_ERR_NOMEM);
199            }
200
201            // Finally, now that we have our lexer constructed, we can create the parser
202            //
203            psr        = LangParserNew(tstream);  // CParserNew is generated by ANTLR3
204
205            if (psr == NULL)
206            {
207               ANTLR3_FPRINTF(stderr, 'Out of memory trying to allocate parser0);
208               exit(ANTLR3_ERR_NOMEM);
209            }
210
211            // We are all ready to go. Though that looked complicated at first glance,
212            // I am sure, you will see that in fact most of the code above is dealing
213            // with errors and there isn;t really that much to do (isn;t this always the
214            // case in C? ;-).
215            //
216            // So, we now invoke the parser. All elements of ANTLR3 generated C components
217            // as well as the ANTLR C runtime library itself are pseudo objects. This means
218            // that they are represented as pointers to structures, which contain any
219            // instance data they need, and a set of pointers to other interfaces or
220            // 'methods'. Note that in general, these few pointers we have created here are
221            // the only things you will ever explicitly free() as everything else is created
222            // via factories, that allocate memory efficiently and free() everything they use
223            // automatically when you close the parser/lexer/etc.
224            //
225            // Note that this means only that the methods are always called via the object
226            // pointer and the first argument to any method, is a pointer to the structure itself.
227            // It also has the side advantage, if you are using an IDE such as VS2005 that can do it
228            // that when you type ->, you will see a list of all the methods the object supports.
229            //
230            langAST = psr->decl(psr);
231
232            // If the parser ran correctly, we will have a tree to parse. In general I recommend
233            // keeping your own flags as part of the error trapping, but here is how you can
234            // work out if there were errors if you are using the generic error messages
235            //
236           if (psr->pParser->rec->errorCount > 0)
237           {
238               ANTLR3_FPRINTF(stderr, 'The parser returned %d errors, tree walking aborted.0, psr->pParser->rec->errorCount);
239
240           }
241           else
242           {
243               nodes   = antlr3CommonTreeNodeStreamNewTree(langAST.tree, ANTLR3_SIZE_HINT); // sIZE HINT WILL SOON BE DEPRECATED!!
244
245               // Tree parsers are given a common tree node stream (or your override)
246               //
247               treePsr = LangDumpDeclNew(nodes);
248
249               treePsr->decl(treePsr);
250               nodes   ->free  (nodes);        nodes   = NULL;
251               treePsr ->free  (treePsr);      treePsr = NULL;
252           }
253
254           // We did not return anything from this parser rule, so we can finish. It only remains
255           // to close down our open objects, in the reverse order we created them
256           //
257           psr     ->free  (psr);      psr     = NULL;
258           tstream ->free  (tstream);  tstream = NULL;
259           lxr     ->free  (lxr);      lxr     = NULL;
260           input   ->close (input);    input   = NULL;
261
262            return 0;
263        }
264
265Version 3.1.2                   Wed Oct 13 2010                    buildrec(3)
Impressum