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