Home | History | Annotate | only in /external/antlr/antlr-3.4/runtime/Delphi
Up to higher level directory
NameDateSize
LICENSE.TXT09-Oct-20131.7K
NOTICE.TXT09-Oct-20131.7K
README.TXT09-Oct-201310.3K
Sources/09-Oct-2013

README.TXT

      1 ==================================================
      2 ANTLR v3 Delphi Code generator and Runtime library
      3 ==================================================
      4 
      5 October 27, 2008
      6 Erik van Bilsen (erik AT bilsen DOT com)
      7 
      8 Please see LICENSE.TXT for the full text of the license and NOTICE.TXT
      9 for attribution notices.
     10 
     11 Architecture
     12 ============
     13 The Delphi target consists of a set of code generation templates and a runtime 
     14 library (written in Delphi 2009) for the Win32 platform.
     15 The Delphi code generation targets and the runtime library are modeled on the 
     16 C# version.
     17 
     18 You need to use Delphi 2009 or a later version to be able to use this target. 
     19 You will not be able to compile generated code with older versions of Delphi.
     20 The reason for this is that this Delphi target uses a lot of new Delphi 
     21 language features such as generics.
     22 
     23 To use the Delphi target, you only need to put the runtime source code in a 
     24 directory of your choice, and add this directory to you Delphi library path or 
     25 to your project's search path.
     26 
     27 The runtime consists of the following units:
     28 -Antlr.Runtime: the main Antlr unit that contains the parser and lexer classes
     29 -Antlr.Runtime.Tree: the tree parser class and other tree related classes
     30 -Antlr.Runtime.Collections: several collection utilities
     31 -Antlr.Runtime.Tools: this is a special Delphi addition to the runtime 
     32  containing several helper classes and utilities
     33 You will find these files in the "Antlr3.Runtime" subdirectory.
     34 
     35 In your projects, you usually only need to use the Antlr.Runtime unit, and the
     36 Antlr.Runtime.Tree unit for tree parsers.
     37 This target does not require any third party libraries, and you do not have to
     38 deploy any DLLs or other files with your ANTLR Delphi projects.
     39 
     40 Please note that this Delphi target does not support StringTemplate output, but
     41 it does support all other output types, including AST output.
     42 
     43 Status
     44 ======
     45 As of October 2008, the Delphi target is in sync with ANTLR 3.1.
     46 
     47 This version passes all the unit tests (which you can find in the
     48 "Antlr3.Runtime.Tests" subdirectory) without any memory leaks.
     49 Also, all the grammar samples in the "examples-v3\Delphi" directory function
     50 correctly and without any memory leaks.
     51 
     52 Performance
     53 ===========
     54 This target should perform reasonably well compared to other ANTLR targets.
     55 For some grammars, especially tree grammars, the code that is generated is not
     56 as efficient as for other targets. This has to do with the way the code is
     57 generated to work around some issues with the Delphi language. But even with
     58 these workarounds, the target performs within reasonable boundaries.
     59 
     60 Usage
     61 =====
     62 Here is a short list of Delphi specific issues you need to take into account
     63 when using this target. Please check out the Delphi sample grammars in the
     64 "examples-v3" archive for examples of all the issues described below. And these
     65 examples are a great way to get started with ANTLR.
     66 
     67 Specify that Delphi code should be generated for a grammar
     68 ----------------------------------------------------------
     69 To specify that the ANTLR tool should generate Delphi (2009) code (rather than
     70 the default of generating Java code) for a grammar, set the grammar-level option
     71 named "language" to the value "Delphi" as shown below:
     72 
     73   grammar MyGrammar;
     74 
     75   options {
     76   	language=Delphi;
     77   }
     78   ...
     79 
     80 For the example grammar named MyGrammar above, the grammar file would typically
     81 be named MyGrammar.g. The grammar filename (excluding the extension) must match
     82 the grammar name as declared with the grammar directive in the file.
     83 
     84 Use Delphi code in actions
     85 --------------------------
     86 Obviously, any custom actions inside your grammars should be written in the
     87 Delphi language. This also applies to less obvious actions like
     88 {$channel=HIDDEN;}, which should be written as {$channel:=HIDDEN;} (with the
     89 colon before the equals sign).
     90 
     91 Rule names must not be case sensitive
     92 -------------------------------------
     93 Since the Delphi language is not case sensitive, you must take care that the
     94 names of rules in your grammars differ by more than only case. For example, if
     95 you have a parser rule called "expression", then you shouldn't have a lexer rule
     96 called "EXPRESSION" or "Expression" or any other combination of upper- and lower
     97 case characters that math the same word. ANTLR will still be able to generate
     98 Delphi code for this, but you will not be able to compile it because of
     99 duplicate identifiers.
    100 
    101 The @members grammar action
    102 ---------------------------
    103 The Delphi target does not recognize the default @members grammar action. It
    104 uses the following three grammar actions instead (see the C and Java sample
    105 grammars for examples):
    106 
    107 @memberDeclarations: use this action that declare members in the generated
    108 parser/lexer class. For example:
    109 
    110   @memberDeclarations {
    111 	enumIsKeyword: Boolean;
    112 	function isTypeName(const name: String): Boolean;
    113   }
    114 
    115   These declarations will appear inside the parser/lexer class declaration.
    116 
    117 @memberInitializations: use this action to initialize variables declared in the
    118 @memberDeclarations action. For example:
    119 
    120   @memberInitializations {
    121 	enumIsKeyword := True;
    122   }
    123 
    124   These statements will appear inside the constructor of the parser/lexer class.
    125 
    126 @memberImplementations: use this action for any code that must appear in the
    127 parser class implementation. For example:
    128 
    129   @memberImplementations {
    130   function TCParser.isTypeName(const name: String): Boolean;
    131   begin
    132     Result := [...]
    133   end;
    134   }
    135 
    136   The code inside this action appears as-is inside the implementation section of
    137   the parser/lexer unit. This means that you need to specify the full name of
    138   the method, including the parser/lexer class name (eg. TCParser.isTypeName).
    139   The class name is based on the name of the grammar, and whether it is a parser
    140   or lexer. So, if your grammar is called "MyGrammar", then the lexer class will
    141   be called TMyGrammarLexer and the parser class will be called
    142   TMyGrammarParser.
    143 
    144 The @vars grammar action
    145 ------------------------
    146 ANTLR supports an @init (and @after) grammar action for any code you want to
    147 execute at the beginning (or end) of a rule. If that code, or any other code
    148 inside the rule, makes use of a local variable, then you need to declare that
    149 variable first. The Delphi target adds the @vars grammar action for this
    150 purpose. You can declare any local variables inside this action, as in this
    151 example (taken from the Python example grammar):
    152 
    153   LEADING_WS
    154   @vars {
    155     spaces: Integer;
    156     S: String;
    157   }
    158   @init {
    159     spaces := 0;
    160   }
    161 
    162 The variables you declare in the @vars action will appear inside the "var"
    163 declaration block of the method for the rule (in this case for the
    164 LEADING_WS rule).
    165 
    166 The @usesInterface and @usedImplementation grammar actions
    167 ----------------------------------------------------------
    168 If you need to add units to the uses clause of the generated units, then you can
    169 use the @usesInterface and @usesImplementation grammar actions. For example, if
    170 some code inside the grammer rules needs access to the Delphi TStringList class,
    171 then you will need to use the Classes unit.
    172 Use the @usesInterface action if you need the units to appear in the interface
    173 part, or @usesImplementation if you only need a unit inside the implementation.
    174 For example:
    175 
    176   @usesImplementation {
    177     Classes,
    178     Generics.Collections,
    179   }
    180 
    181 Note that you need to add a comma after each unit in this list. The Delphi units
    182 SysUtils, StrUtils and Math are added to the uses clause automatically.
    183 Also note that you will usually put the @usesInterface/@usesImplementation
    184 actions at the top of your grammar file, like you would the with the @header
    185 action for other language targets.
    186 
    187 The Delphi target is interface based
    188 ------------------------------------
    189 All classes inside the Delphi ANTLR runtime use object interfaces. This greatly
    190 simplifies memory management and makes using the runtime much easier. This means
    191 that you will never declare class variables for ANTLR objects, but only use
    192 interface variables. For example, a typical test rig in Delphi looks like this
    193 (taken from the SimpleC example):
    194 
    195   procedure Run(const InputFilename: String);
    196   var
    197     Input: ICharStream;
    198     Lex: ISimpleCLexer;
    199     Tokens: ICommonTokenStream;
    200     Parser: ISimpleCParser;
    201     R: Iprog_return;
    202   begin
    203     Input := TANTLRFileStream.Create(InputFilename);
    204     Lex := TSimpleCLexer.Create(Input);
    205     Tokens := TCommonTokenStream.Create(Lex);
    206     Parser := TSimpleCParser.Create(Tokens);
    207     R := Parser.prog;
    208     WriteLn('tree=' + (R.Tree as ITree).ToStringTree);
    209   end;
    210 
    211 Note that all variables are declared as interface variables (starting with a
    212 capital I) instead of class variables (with a capital T). And there is no need
    213 to destroy these objects yourself (there are no calls to Free and no
    214 try..finally blocks to protect these resources).
    215 
    216 If you are new to interface-based programming, then don't worry: just remember
    217 to declare all ANTLR objects using interface variables, and don't call Free
    218 on them.
    219 
    220 Note that the C# and Java versions of the tree creation classes use the general
    221 Object type for tree nodes. In the Delphi version, tree nodes are of type
    222 IANTLRInterface, and can be implemented in various class (like TCommonTree).
    223 
    224 Antlr.Runtime.Tools
    225 -------------------
    226 This unit contains some classes and interfaces you may find useful inside ANTLR
    227 projects. Also, this unit contains declarations for the IANTLRInterface
    228 interface and TANTLRObject class. All ANTLR classes derive from TANTLRObject and
    229 implement the IANTLRInterface interface.
    230 
    231 Other interfaces/classes you may find useful are:
    232 
    233 * IANTLRString (implemented in TANTLRString): a wrapper around a Delphi string
    234   that allows you to treat a string as a regular ANTLR object.
    235 
    236 * IList<T> (implemented in TList<T>): a generic list containing elements of
    237   type <T>. For example, you can create a list of Integers like this:
    238 
    239   var
    240     List: IList<Integer>;
    241   begin
    242     List := TList<Integer>.Create;
    243     List.Add(123);
    244   end;
    245 
    246   Note that this is basically the same TList<T> declared in Delphi's unit
    247   Generics.Collections, but it implements the IList<T> interface.
    248 
    249 * IDictionary<TKey, TValue> (implemented in TDictionary<TKey, TValue>): a
    250   generic dictionary that maps elements of type <TKey> to <TValue>. For example,
    251   to map Strings to TANTLRObjects, use:
    252 
    253   var
    254     Map: IDictionary<String, IANTLRInterface>
    255   begin
    256     Map := TDictionary<String, IANTLRInterface>.Create;
    257     Map.Add('foo', TANTLRObject.Create);
    258   end;
    259 
    260   Again, this class is similar to Delphi's TDictionary, but it implements the
    261   IDictionary<TKey, TValue> interface.
    262 
    263 
    264 
    265 Erik van Bilsen
    266