summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorDavid Beazley <dave@dabeaz.com>2007-11-29 16:51:07 +0000
committerDavid Beazley <dave@dabeaz.com>2007-11-29 16:51:07 +0000
commit9680ee44a5e8a15c4e86c67090605733f3f67e05 (patch)
treeb4852d7f6f707bd2154413246537e46484f263ff /doc
parent051284882c89795552e84813b506f7cd99a094d9 (diff)
downloadply-9680ee44a5e8a15c4e86c67090605733f3f67e05.tar.gz
*** empty log message ***
Diffstat (limited to 'doc')
-rw-r--r--doc/ply.html67
1 files changed, 15 insertions, 52 deletions
diff --git a/doc/ply.html b/doc/ply.html
index 2476c36..42d48ec 100644
--- a/doc/ply.html
+++ b/doc/ply.html
@@ -427,6 +427,8 @@ reserved = {
...
}
+tokens = ['LPAREN','RPAREN',...,'ID'] + reserved.values()
+
def t_ID(t):
r'[a-zA-Z_][a-zA-Z_0-9]*'
t.type = reserved.get(t.value,'ID') # Check for reserved words
@@ -976,10 +978,7 @@ lexer = lex.lex(object=m)
The class approach may be the easiest to manage if your application is going to be creating multiple instances of the same lexer and
you need to manage a lot of state.
-<H3><a name="ply_nn19"></a>3.16 Duplicating lexers</H3>
-
-
-<b>NOTE: I am thinking about deprecating this feature. Post comments on <a href="http://groups.google.com/group/ply-hack">ply-hack@googlegroups.com</a> or send me a private email at dave@dabeaz.com.</b>
+<H3><a name="ply_nn19"></a>3.16 Lexer cloning</H3>
<p>
If necessary, a lexer object can be quickly duplicated by invoking its <tt>clone()</tt> method. For example:
@@ -992,23 +991,19 @@ newlexer = lexer.clone()
</pre>
</blockquote>
-When a lexer is cloned, the copy is identical to the original lexer,
-including any input text. However, once created, different text can be
-fed to the clone which can be used independently. This capability may
-be useful in situations when you are writing a parser/compiler that
+When a lexer is cloned, the copy is exactly identical to the original lexer
+including any input text and internal state. However, the clone allows a
+different set of input text to be supplied which may be processed separately.
+This may be useful in situations when you are writing a parser/compiler that
involves recursive or reentrant processing. For instance, if you
needed to scan ahead in the input for some reason, you could create a
-clone and use it to look ahead.
-
-<p>
-The advantage of using <tt>clone()</tt> instead of reinvoking <tt>lex()</tt> is
-that it is significantly faster. Namely, it is not necessary to re-examine all of the
-token rules, build a regular expression, and construct internal tables. All of this
-information can simply be reused in the new lexer.
+clone and use it to look ahead. Or, if you were implementing some kind of preprocessor,
+cloned lexers could be used to handle different input files.
<p>
-Special considerations need to be made when cloning a lexer that is defined as a class. Previous sections
-showed an example of a class <tt>MyLexer</tt>. If you have the following code:
+Special considerations need to be made when cloning lexers that also maintain their own
+internal state. Namely, you need to be aware that the newly created lexers will share all
+of this state with the original lexer. For example, if you defined a lexer as a class and did this:
<blockquote>
<pre>
@@ -1020,41 +1015,9 @@ b = a.clone() # Clone the lexer
</blockquote>
Then both <tt>a</tt> and <tt>b</tt> are going to be bound to the same
-object <tt>m</tt>. If the object <tt>m</tt> contains internal state
-related to lexing, this sharing may lead to quite a bit of confusion. To fix this,
-the <tt>clone()</tt> method accepts an optional argument that can be used to supply a new object. This
-can be used to clone the lexer and bind it to a new instance. For example:
-
-<blockquote>
-<pre>
-m = MyLexer() # Create a lexer
-a = lex.lex(object=m)
-
-# Create a clone
-n = MyLexer() # New instance of MyLexer
-b = a.clone(n) # New lexer bound to n
-</pre>
-</blockquote>
-
-It may make sense to encapsulate all of this inside a method:
-
-<blockquote>
-<pre>
-class MyLexer:
- ...
- def clone(self):
- c = MyLexer() # Create a new instance of myself
- # Copy attributes from self to c as appropriate
- ...
- # Clone the lexer
- c.lexer = self.lexer.clone(c)
- return c
-</pre>
-</blockquote>
-
-The fact that a new instance of <tt>MyLexer</tt> may be created while cloning a lexer is the reason why you should never
-invoke <tt>lex.lex()</tt> inside <tt>__init__()</tt>. If you do, the lexer will be rebuilt from scratch and you lose
-all of the performance benefits of using <tt>clone()</tt> in the first place.
+object <tt>m</tt> and any changes to <tt>m</tt> will be reflected in both lexers. It's
+important to emphasize that <tt>clone()</tt> is not meant to make a totally new copy of a
+lexer. If you want to do that, call <tt>lex()</tt> again to create a new lexer.
<H3><a name="ply_nn20"></a>3.17 Internal lexer state</H3>