1buildrec(3) ANTLR3C buildrec(3)
2
3
4
6 buildrec - .TH "buildrec" 3 "Wed Oct 13 2010" "Version 3.1.2" "ANTLR3C"
7
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
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)