[pypy-svn] r39432 - in pypy/dist/pypy: config doc/config interpreter interpreter/astcompiler interpreter/pyparser interpreter/pyparser/test interpreter/stablecompiler module/dyngram module/recparser module/recparser/hooksamples module/recparser/test module/symbol rpython translator/goal translator/js translator/js/examples translator/js/examples/bnb translator/js/examples/bnb/data translator/js/examples/bnb/data/images translator/js/examples/console translator/js/examples/console/data translator/js/examples/console/test translator/js/examples/data translator/js/examples/djangoping translator/js/examples/djangoping/templates translator/js/examples/djangoping/test translator/js/examples/test translator/js/jssrc translator/js/lib translator/js/lib/test translator/js/modules translator/js/modules/test translator/js/modules/test/html translator/js/test translator/js/turbogears translator/js/tutorial translator/tool

afayolle at codespeak.net afayolle at codespeak.net
Mon Feb 26 15:06:38 CET 2007


Author: afayolle
Date: Mon Feb 26 15:06:33 2007
New Revision: 39432

Added:
   pypy/dist/pypy/doc/config/objspace.usemodules.dyngram.txt
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.dyngram.txt
   pypy/dist/pypy/interpreter/pyparser/asthelper.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/interpreter/pyparser/asthelper.py
   pypy/dist/pypy/interpreter/pyparser/test/expressions.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/interpreter/pyparser/test/expressions.py
   pypy/dist/pypy/interpreter/pyparser/test/test_parser.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/interpreter/pyparser/test/test_parser.py
   pypy/dist/pypy/module/dyngram/   (props changed)
      - copied from r39399, pypy/branch/ast-experiments/pypy/module/dyngram/
   pypy/dist/pypy/module/recparser/hooksamples/
      - copied from r39399, pypy/branch/ast-experiments/pypy/module/recparser/hooksamples/
   pypy/dist/pypy/module/recparser/test/test_dyn_grammarrules.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/module/recparser/test/test_dyn_grammarrules.py
   pypy/dist/pypy/rpython/rslice.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/rpython/rslice.py
   pypy/dist/pypy/translator/goal/targetebnfparser.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/goal/targetebnfparser.py
   pypy/dist/pypy/translator/js/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/
   pypy/dist/pypy/translator/js/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/__init__.py
   pypy/dist/pypy/translator/js/_class.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/_class.py
   pypy/dist/pypy/translator/js/asmgen.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/asmgen.py
   pypy/dist/pypy/translator/js/autopath.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/autopath.py
   pypy/dist/pypy/translator/js/commproxy.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/commproxy.py
   pypy/dist/pypy/translator/js/conftest.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/conftest.py
   pypy/dist/pypy/translator/js/database.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/database.py
   pypy/dist/pypy/translator/js/examples/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/
   pypy/dist/pypy/translator/js/examples/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/__init__.py
   pypy/dist/pypy/translator/js/examples/autopath.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/autopath.py
   pypy/dist/pypy/translator/js/examples/bnb/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/
   pypy/dist/pypy/translator/js/examples/bnb/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/__init__.py
   pypy/dist/pypy/translator/js/examples/bnb/autopath.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/autopath.py
   pypy/dist/pypy/translator/js/examples/bnb/bnb.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/bnb.py
   pypy/dist/pypy/translator/js/examples/bnb/data/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/
   pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/bnb.html
   pypy/dist/pypy/translator/js/examples/bnb/data/images/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/images/
   pypy/dist/pypy/translator/js/examples/bnb/msgstruct.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/msgstruct.py
   pypy/dist/pypy/translator/js/examples/bnb/servermessage.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/servermessage.py
   pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/start_bnb.py
   pypy/dist/pypy/translator/js/examples/console/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/
   pypy/dist/pypy/translator/js/examples/console/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/__init__.py
   pypy/dist/pypy/translator/js/examples/console/client.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/client.py
   pypy/dist/pypy/translator/js/examples/console/console.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/console.py
   pypy/dist/pypy/translator/js/examples/console/data/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/data/
   pypy/dist/pypy/translator/js/examples/console/data/console.html
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/data/console.html
   pypy/dist/pypy/translator/js/examples/console/test/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/test/
   pypy/dist/pypy/translator/js/examples/console/test/test_console.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/test/test_console.py
   pypy/dist/pypy/translator/js/examples/data/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/data/
   pypy/dist/pypy/translator/js/examples/data/index.html
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/data/index.html
   pypy/dist/pypy/translator/js/examples/data/launcher.html
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/data/launcher.html
   pypy/dist/pypy/translator/js/examples/djangoping/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/
   pypy/dist/pypy/translator/js/examples/djangoping/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/__init__.py
   pypy/dist/pypy/translator/js/examples/djangoping/client.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/client.py
   pypy/dist/pypy/translator/js/examples/djangoping/manage.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/manage.py
   pypy/dist/pypy/translator/js/examples/djangoping/settings.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/settings.py
   pypy/dist/pypy/translator/js/examples/djangoping/templates/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/templates/
   pypy/dist/pypy/translator/js/examples/djangoping/templates/index.html
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/templates/index.html
   pypy/dist/pypy/translator/js/examples/djangoping/test/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/test/
   pypy/dist/pypy/translator/js/examples/djangoping/test/test_build.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/test/test_build.py
   pypy/dist/pypy/translator/js/examples/djangoping/urls.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/urls.py
   pypy/dist/pypy/translator/js/examples/djangoping/views.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/views.py
   pypy/dist/pypy/translator/js/examples/guestbook.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/guestbook.py
   pypy/dist/pypy/translator/js/examples/guestbook_client.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/guestbook_client.py
   pypy/dist/pypy/translator/js/examples/over_client.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/over_client.py
   pypy/dist/pypy/translator/js/examples/overmind.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/overmind.py
   pypy/dist/pypy/translator/js/examples/pythonconsole.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/pythonconsole.py
   pypy/dist/pypy/translator/js/examples/serialise.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/serialise.py
   pypy/dist/pypy/translator/js/examples/test/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/test/
   pypy/dist/pypy/translator/js/examples/test/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/test/__init__.py
   pypy/dist/pypy/translator/js/examples/test/test_examples.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/test/test_examples.py
   pypy/dist/pypy/translator/js/function.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/function.py
   pypy/dist/pypy/translator/js/helper.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/helper.py
   pypy/dist/pypy/translator/js/js.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/js.py
   pypy/dist/pypy/translator/js/jsbuiltin.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/jsbuiltin.py
   pypy/dist/pypy/translator/js/json.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/json.py
   pypy/dist/pypy/translator/js/jssrc/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/jssrc/
   pypy/dist/pypy/translator/js/jssrc/misc.js
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/jssrc/misc.js
   pypy/dist/pypy/translator/js/jts.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/jts.py
   pypy/dist/pypy/translator/js/lib/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/
   pypy/dist/pypy/translator/js/lib/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/__init__.py
   pypy/dist/pypy/translator/js/lib/server.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/server.py
   pypy/dist/pypy/translator/js/lib/support.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/support.py
   pypy/dist/pypy/translator/js/lib/test/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/
   pypy/dist/pypy/translator/js/lib/test/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/__init__.py
   pypy/dist/pypy/translator/js/lib/test/test_server.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/test_server.py
   pypy/dist/pypy/translator/js/lib/test/test_support.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/test_support.py
   pypy/dist/pypy/translator/js/lib/test/test_url.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/test_url.py
   pypy/dist/pypy/translator/js/lib/url.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/url.py
   pypy/dist/pypy/translator/js/log.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/log.py
   pypy/dist/pypy/translator/js/main.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/main.py
   pypy/dist/pypy/translator/js/metavm.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/metavm.py
   pypy/dist/pypy/translator/js/modules/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/
   pypy/dist/pypy/translator/js/modules/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/__init__.py
   pypy/dist/pypy/translator/js/modules/dom.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/dom.py
   pypy/dist/pypy/translator/js/modules/mochikit.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/mochikit.py
   pypy/dist/pypy/translator/js/modules/test/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/
   pypy/dist/pypy/translator/js/modules/test/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/__init__.py
   pypy/dist/pypy/translator/js/modules/test/html/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/html/
   pypy/dist/pypy/translator/js/modules/test/html/anim.html
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/html/anim.html
   pypy/dist/pypy/translator/js/modules/test/html/test.html
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/html/test.html
   pypy/dist/pypy/translator/js/modules/test/test_dom.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/test_dom.py
   pypy/dist/pypy/translator/js/modules/test/test_mochikit.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/test_mochikit.py
   pypy/dist/pypy/translator/js/opcodes.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/opcodes.py
   pypy/dist/pypy/translator/js/support.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/support.py
   pypy/dist/pypy/translator/js/test/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/
   pypy/dist/pypy/translator/js/test/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/__init__.py
   pypy/dist/pypy/translator/js/test/browsertest.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/browsertest.py
   pypy/dist/pypy/translator/js/test/runtest.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/runtest.py
   pypy/dist/pypy/translator/js/test/test_basicexternal.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_basicexternal.py
   pypy/dist/pypy/translator/js/test/test_bltn.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_bltn.py
   pypy/dist/pypy/translator/js/test/test_class.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_class.py
   pypy/dist/pypy/translator/js/test/test_exc_operation.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_exc_operation.py
   pypy/dist/pypy/translator/js/test/test_exception.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_exception.py
   pypy/dist/pypy/translator/js/test/test_extfunc.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_extfunc.py
   pypy/dist/pypy/translator/js/test/test_jseval.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_jseval.py
   pypy/dist/pypy/translator/js/test/test_loops.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_loops.py
   pypy/dist/pypy/translator/js/test/test_main.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_main.py
   pypy/dist/pypy/translator/js/test/test_rclass.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rclass.py
   pypy/dist/pypy/translator/js/test/test_rdict.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rdict.py
   pypy/dist/pypy/translator/js/test/test_rlist.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rlist.py
   pypy/dist/pypy/translator/js/test/test_rpbc.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rpbc.py
   pypy/dist/pypy/translator/js/test/test_rsnippet.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rsnippet.py
   pypy/dist/pypy/translator/js/test/test_rsnippet1.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rsnippet1.py
   pypy/dist/pypy/translator/js/test/test_runtest.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_runtest.py
   pypy/dist/pypy/translator/js/test/test_seq.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_seq.py
   pypy/dist/pypy/translator/js/test/test_snippet.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_snippet.py
   pypy/dist/pypy/translator/js/test/test_typed.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_typed.py
   pypy/dist/pypy/translator/js/test/tgtest.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/tgtest.py
   pypy/dist/pypy/translator/js/tester.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tester.py
   pypy/dist/pypy/translator/js/turbogears/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/
   pypy/dist/pypy/translator/js/turbogears/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/__init__.py
   pypy/dist/pypy/translator/js/turbogears/commandjs.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/commandjs.py
   pypy/dist/pypy/translator/js/turbogears/setup.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/setup.py
   pypy/dist/pypy/translator/js/turbogears/templateplugin.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/templateplugin.py
   pypy/dist/pypy/translator/js/turbogears/upload.sh
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/upload.sh
   pypy/dist/pypy/translator/js/turbogears/widgets.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/widgets.py
   pypy/dist/pypy/translator/js/tutorial/
      - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/
   pypy/dist/pypy/translator/js/tutorial/__init__.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/__init__.py
   pypy/dist/pypy/translator/js/tutorial/step1.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/step1.py
   pypy/dist/pypy/translator/js/tutorial/step2.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/step2.py
   pypy/dist/pypy/translator/js/tutorial/step3.py
      - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/step3.py
Modified:
   pypy/dist/pypy/config/pypyoption.py
   pypy/dist/pypy/interpreter/astcompiler/ast.py
   pypy/dist/pypy/interpreter/astcompiler/ast.txt
   pypy/dist/pypy/interpreter/astcompiler/astgen.py
   pypy/dist/pypy/interpreter/pycompiler.py
   pypy/dist/pypy/interpreter/pyparser/astbuilder.py
   pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py
   pypy/dist/pypy/interpreter/pyparser/ebnflexer.py
   pypy/dist/pypy/interpreter/pyparser/ebnfparse.py
   pypy/dist/pypy/interpreter/pyparser/grammar.py
   pypy/dist/pypy/interpreter/pyparser/pysymbol.py
   pypy/dist/pypy/interpreter/pyparser/pythonlexer.py
   pypy/dist/pypy/interpreter/pyparser/pythonparse.py
   pypy/dist/pypy/interpreter/pyparser/pythonutil.py
   pypy/dist/pypy/interpreter/pyparser/pytoken.py
   pypy/dist/pypy/interpreter/pyparser/syntaxtree.py
   pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py
   pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py
   pypy/dist/pypy/interpreter/pyparser/test/test_lookahead.py
   pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py
   pypy/dist/pypy/interpreter/pyparser/test/test_samples.py
   pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py
   pypy/dist/pypy/interpreter/stablecompiler/transformer.py
   pypy/dist/pypy/module/recparser/__init__.py
   pypy/dist/pypy/module/recparser/codegen.py
   pypy/dist/pypy/module/recparser/compat.py
   pypy/dist/pypy/module/recparser/pyparser.py
   pypy/dist/pypy/module/recparser/test/test_parser.py
   pypy/dist/pypy/module/symbol/__init__.py
   pypy/dist/pypy/translator/tool/make_dot.py
Log:
Merge ast-experiments branch in the trunk

svn merge  -r 22393:39399 svn+ssh://codespeak.net/svn/pypy/branch/ast-experiments



Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py	(original)
+++ pypy/dist/pypy/config/pypyoption.py	Mon Feb 26 15:06:33 2007
@@ -24,7 +24,7 @@
 working_modules = default_modules.copy()
 working_modules.update(dict.fromkeys(
     ["rsocket", "unicodedata", "mmap", "fcntl", "rctime", "select",
-     "crypt", "signal",
+     "crypt", "signal", "dyngram",
     ]
 ))
 

Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/ast.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/ast.py	Mon Feb 26 15:06:33 2007
@@ -30,6 +30,7 @@
     def __init__(self, lineno = -1):
         self.lineno = lineno
         self.filename = ""
+        self.parent = None
         #self.scope = None
         
     def getChildren(self):
@@ -61,6 +62,12 @@
     def descr_repr( self, space ):
         return space.wrap( self.__repr__() )
     
+    def fget_parent(space, self):
+        return space.wrap(self.parent)
+
+    def fset_parent(space, self, w_parent):
+        self.parent = space.interp_w(Node, w_parent, can_be_None=False)
+
     def descr_getChildNodes( self, space ):
         lst = self.getChildNodes()
         return space.newlist( [ space.wrap( it ) for it in lst ] )
@@ -84,6 +91,7 @@
                        mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ),
                        lineno = interp_attrproperty('lineno', cls=Node),
                        filename = interp_attrproperty('filename', cls=Node),
+                       parent=GetSetProperty(Node.fget_parent, Node.fset_parent),
                        )
 
 Node.typedef.acceptable_as_base_class = False
@@ -363,6 +371,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_And_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(And, w_subtype)
@@ -391,6 +408,8 @@
                      accept=interp2app(descr_And_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_And_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(And.fget_nodes, And.fset_nodes ),
+                     insert_after=interp2app(And.descr_insert_after.im_func, unwrap_spec=[ObjSpace, And, Node, W_Root]),
+                     insert_before=interp2app(And.descr_insert_before.im_func, unwrap_spec=[ObjSpace, And, Node, W_Root]),
                     )
 And.typedef.acceptable_as_base_class = False
 
@@ -536,6 +555,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_AssList_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(AssList, w_subtype)
@@ -564,6 +592,8 @@
                      accept=interp2app(descr_AssList_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_AssList_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(AssList.fget_nodes, AssList.fset_nodes ),
+                     insert_after=interp2app(AssList.descr_insert_after.im_func, unwrap_spec=[ObjSpace, AssList, Node, W_Root]),
+                     insert_before=interp2app(AssList.descr_insert_before.im_func, unwrap_spec=[ObjSpace, AssList, Node, W_Root]),
                     )
 AssList.typedef.acceptable_as_base_class = False
 
@@ -671,6 +701,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_AssTuple_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(AssTuple, w_subtype)
@@ -699,6 +738,8 @@
                      accept=interp2app(descr_AssTuple_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_AssTuple_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(AssTuple.fget_nodes, AssTuple.fset_nodes ),
+                     insert_after=interp2app(AssTuple.descr_insert_after.im_func, unwrap_spec=[ObjSpace, AssTuple, Node, W_Root]),
+                     insert_before=interp2app(AssTuple.descr_insert_before.im_func, unwrap_spec=[ObjSpace, AssTuple, Node, W_Root]),
                     )
 AssTuple.typedef.acceptable_as_base_class = False
 
@@ -820,6 +861,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
     def fget_expr( space, self):
         return space.wrap(self.expr)
     def fset_expr( space, self, w_arg):
@@ -858,6 +908,8 @@
                      accept=interp2app(descr_Assign_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Assign_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Assign.fget_nodes, Assign.fset_nodes ),
+                     insert_after=interp2app(Assign.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Assign, Node, W_Root]),
+                     insert_before=interp2app(Assign.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Assign, Node, W_Root]),
                     expr=GetSetProperty(Assign.fget_expr, Assign.fset_expr ),
                     )
 Assign.typedef.acceptable_as_base_class = False
@@ -1100,6 +1152,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_Bitand_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(Bitand, w_subtype)
@@ -1128,6 +1189,8 @@
                      accept=interp2app(descr_Bitand_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Bitand_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Bitand.fget_nodes, Bitand.fset_nodes ),
+                     insert_after=interp2app(Bitand.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Bitand, Node, W_Root]),
+                     insert_before=interp2app(Bitand.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Bitand, Node, W_Root]),
                     )
 Bitand.typedef.acceptable_as_base_class = False
 
@@ -1166,6 +1229,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_Bitor_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(Bitor, w_subtype)
@@ -1194,6 +1266,8 @@
                      accept=interp2app(descr_Bitor_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Bitor_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Bitor.fget_nodes, Bitor.fset_nodes ),
+                     insert_after=interp2app(Bitor.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Bitor, Node, W_Root]),
+                     insert_before=interp2app(Bitor.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Bitor, Node, W_Root]),
                     )
 Bitor.typedef.acceptable_as_base_class = False
 
@@ -1232,6 +1306,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_Bitxor_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(Bitxor, w_subtype)
@@ -1260,6 +1343,8 @@
                      accept=interp2app(descr_Bitxor_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Bitxor_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Bitxor.fget_nodes, Bitxor.fset_nodes ),
+                     insert_after=interp2app(Bitxor.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Bitxor, Node, W_Root]),
+                     insert_before=interp2app(Bitxor.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Bitxor, Node, W_Root]),
                     )
 Bitxor.typedef.acceptable_as_base_class = False
 
@@ -1834,6 +1919,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_Decorators_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(Decorators, w_subtype)
@@ -1862,6 +1956,8 @@
                      accept=interp2app(descr_Decorators_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Decorators_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Decorators.fget_nodes, Decorators.fset_nodes ),
+                     insert_after=interp2app(Decorators.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Decorators, Node, W_Root]),
+                     insert_before=interp2app(Decorators.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Decorators, Node, W_Root]),
                     )
 Decorators.typedef.acceptable_as_base_class = False
 
@@ -3544,6 +3640,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_List_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(List, w_subtype)
@@ -3572,6 +3677,8 @@
                      accept=interp2app(descr_List_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_List_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(List.fget_nodes, List.fset_nodes ),
+                     insert_after=interp2app(List.descr_insert_after.im_func, unwrap_spec=[ObjSpace, List, Node, W_Root]),
+                     insert_before=interp2app(List.descr_insert_before.im_func, unwrap_spec=[ObjSpace, List, Node, W_Root]),
                     )
 List.typedef.acceptable_as_base_class = False
 
@@ -4172,6 +4279,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_Or_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(Or, w_subtype)
@@ -4200,6 +4316,8 @@
                      accept=interp2app(descr_Or_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Or_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Or.fget_nodes, Or.fset_nodes ),
+                     insert_after=interp2app(Or.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Or, Node, W_Root]),
+                     insert_before=interp2app(Or.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Or, Node, W_Root]),
                     )
 Or.typedef.acceptable_as_base_class = False
 
@@ -4350,6 +4468,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
     def fget_dest( space, self):
         if self.dest is None:
             return space.w_None
@@ -4392,6 +4519,8 @@
                      accept=interp2app(descr_Print_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Print_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Print.fget_nodes, Print.fset_nodes ),
+                     insert_after=interp2app(Print.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Print, Node, W_Root]),
+                     insert_before=interp2app(Print.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Print, Node, W_Root]),
                     dest=GetSetProperty(Print.fget_dest, Print.fset_dest ),
                     )
 Print.typedef.acceptable_as_base_class = False
@@ -4439,6 +4568,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
     def fget_dest( space, self):
         if self.dest is None:
             return space.w_None
@@ -4481,6 +4619,8 @@
                      accept=interp2app(descr_Printnl_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Printnl_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Printnl.fget_nodes, Printnl.fset_nodes ),
+                     insert_after=interp2app(Printnl.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Printnl, Node, W_Root]),
+                     insert_before=interp2app(Printnl.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Printnl, Node, W_Root]),
                     dest=GetSetProperty(Printnl.fget_dest, Printnl.fset_dest ),
                     )
 Printnl.typedef.acceptable_as_base_class = False
@@ -4856,6 +4996,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_Sliceobj_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(Sliceobj, w_subtype)
@@ -4884,6 +5033,8 @@
                      accept=interp2app(descr_Sliceobj_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Sliceobj_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Sliceobj.fget_nodes, Sliceobj.fset_nodes ),
+                     insert_after=interp2app(Sliceobj.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Sliceobj, Node, W_Root]),
+                     insert_before=interp2app(Sliceobj.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Sliceobj, Node, W_Root]),
                     )
 Sliceobj.typedef.acceptable_as_base_class = False
 
@@ -4922,6 +5073,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_Stmt_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(Stmt, w_subtype)
@@ -4950,6 +5110,8 @@
                      accept=interp2app(descr_Stmt_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Stmt_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Stmt.fget_nodes, Stmt.fset_nodes ),
+                     insert_after=interp2app(Stmt.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Stmt, Node, W_Root]),
+                     insert_before=interp2app(Stmt.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Stmt, Node, W_Root]),
                     )
 Stmt.typedef.acceptable_as_base_class = False
 
@@ -5352,6 +5514,15 @@
         del self.nodes[:]
         for w_itm in space.unpackiterable(w_arg):
             self.nodes.append( space.interp_w(Node, w_itm))
+    def descr_insert_after(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node) + 1
+        self.nodes[index:index] = added_nodes
+
+    def descr_insert_before(space, self, node, w_added_nodes):
+        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]
+        index = self.nodes.index(node)
+        self.nodes[index:index] = added_nodes
 
 def descr_Tuple_new(space, w_subtype, w_nodes, lineno=-1):
     self = space.allocate_instance(Tuple, w_subtype)
@@ -5380,6 +5551,8 @@
                      accept=interp2app(descr_Tuple_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                      mutate=interp2app(descr_Tuple_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
                     nodes=GetSetProperty(Tuple.fget_nodes, Tuple.fset_nodes ),
+                     insert_after=interp2app(Tuple.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Tuple, Node, W_Root]),
+                     insert_before=interp2app(Tuple.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Tuple, Node, W_Root]),
                     )
 Tuple.typedef.acceptable_as_base_class = False
 

Modified: pypy/dist/pypy/interpreter/astcompiler/ast.txt
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/ast.txt	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/ast.txt	Mon Feb 26 15:06:33 2007
@@ -71,7 +71,7 @@
 CallFunc: node, args!, star_args& = None, dstar_args& = None
 Keyword: name*str, expr
 Subscript: expr, flags*int, sub
-Ellipsis:
+Ellipsis: 
 Sliceobj: nodes!
 Slice: expr, flags*int, lower&, upper&
 Assert: test, fail&
@@ -318,6 +318,7 @@
     self.lineno = lineno
     return space.wrap(self)
 
+
 def descr_Compare_mutate(space, w_self, w_visitor): 
     w_expr = space.getattr(w_self, space.wrap("expr"))
     w_new_expr = space.call_method(w_expr, "mutate", w_visitor)
@@ -337,6 +338,31 @@
     return space.call_method(w_visitor, "visitCompare", w_self)
 
 
+def descr_Compare_mutate(space, w_self, w_visitor): 
+    w_expr = space.getattr(w_self, space.wrap("expr"))
+    w_mutate_expr = space.getattr(w_expr, space.wrap("mutate"))
+    w_mutate_expr_args = Arguments(space, [ w_visitor ])
+    w_new_expr = space.call_args(w_mutate_expr, w_mutate_expr_args)
+    space.setattr(w_self, space.wrap("expr"), w_new_expr)
+
+    w_list = space.getattr(w_self, space.wrap("ops"))
+    list_w = space.unpackiterable(w_list)
+    newlist_w = []
+    for w_item in list_w:
+        w_opname, w_node = space.unpackiterable(w_item, 2)
+        
+        w_node_mutate = space.getattr(w_node, space.wrap("mutate"))
+        w_node_mutate_args = Arguments(space, [ w_visitor ])
+        w_newnode = space.call_args(w_node_mutate, w_node_mutate_args)
+        
+        newlist_w.append(space.newtuple([w_opname, w_newnode]))
+    w_newlist = space.newlist(newlist_w)
+    space.setattr(w_self, space.wrap("ops"), w_newlist)
+    w_visitCompare = space.getattr(w_visitor, space.wrap("visitCompare"))
+    w_visitCompare_args = Arguments(space, [ w_self ])
+    return space.call_args(w_visitCompare, w_visitCompare_args)
+
+
 def descr_Dict_new(space, w_subtype, w_items, lineno=-1):
     self = space.allocate_instance(Dict, w_subtype)
     items = []

Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/astgen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/astgen.py	Mon Feb 26 15:06:33 2007
@@ -319,6 +319,40 @@
                     print >> buf, "        self.%s[:] = newlist"%(argname)
         print >> buf, "        return visitor.visit%s(self)" % self.name
 
+    def _gen_insertnodes_func(self, buf):
+        print >> buf, "    def descr_insert_after(space, self, node, w_added_nodes):"
+        print >> buf, "        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]"
+        print >> buf, "        index = self.nodes.index(node) + 1"
+        print >> buf, "        self.nodes[index:index] = added_nodes"
+        print >> buf
+        print >> buf, "    def descr_insert_before(space, self, node, w_added_nodes):"
+        print >> buf, "        added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]"
+        print >> buf, "        index = self.nodes.index(node)"
+        print >> buf, "        self.nodes[index:index] = added_nodes"
+
+
+    def _gen_mutate(self, buf):
+        print >> buf, "    def mutate(self, visitor):"
+        if len(self.argnames) != 0:
+            for argname in self.argnames:
+                if argname in self.mutate_nodes:
+                    for line in self.mutate_nodes[argname]:
+                        if line.strip():
+                            print >> buf, '    ' + line
+                elif self.argprops[argname] == P_NODE:
+                    print >> buf, "        self.%s = self.%s.mutate(visitor)" % (argname,argname)
+                elif self.argprops[argname] == P_NONE:
+                    print >> buf, "        if self.%s is not None:" % (argname,)
+                    print >> buf, "            self.%s = self.%s.mutate(visitor)" % (argname,argname)
+                elif self.argprops[argname] == P_NESTED:
+                    print >> buf, "        newlist = []"
+                    print >> buf, "        for n in self.%s:"%(argname)
+                    print >> buf, "            item = n.mutate(visitor)"
+                    print >> buf, "            if item is not None:"
+                    print >> buf, "                newlist.append(item)"
+                    print >> buf, "        self.%s[:] = newlist"%(argname)
+        print >> buf, "        return visitor.visit%s(self)" % self.name
+
     def _gen_fget_func(self, buf, attr, prop ):
         # FGET
         print >> buf, "    def fget_%s( space, self):" % attr
@@ -370,6 +404,8 @@
 
             if "fset_%s" % attr not in self.additional_methods:
                 self._gen_fset_func( buf, attr, prop )
+            if prop[attr] == P_NESTED and attr == 'nodes':
+                self._gen_insertnodes_func(buf)
 
     def _gen_descr_mutate(self, buf):
         if self.applevel_mutate:
@@ -426,6 +462,9 @@
         print >> buf, "                     mutate=interp2app(descr_%s_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] )," % self.name
         for attr in self.argnames:
             print >> buf, "                    %s=GetSetProperty(%s.fget_%s, %s.fset_%s )," % (attr,self.name,attr,self.name,attr)
+            if self.argprops[attr] == P_NESTED and attr == "nodes":
+                print >> buf, "                     insert_after=interp2app(%s.descr_insert_after.im_func, unwrap_spec=[ObjSpace, %s, Node, W_Root])," % (self.name, self.name)
+                print >> buf, "                     insert_before=interp2app(%s.descr_insert_before.im_func, unwrap_spec=[ObjSpace, %s, Node, W_Root])," % (self.name, self.name)
         print >> buf, "                    )"
         print >> buf, "%s.typedef.acceptable_as_base_class = False" % self.name
 
@@ -660,6 +699,7 @@
     def __init__(self, lineno = -1):
         self.lineno = lineno
         self.filename = ""
+        self.parent = None
         #self.scope = None
         
     def getChildren(self):
@@ -691,6 +731,12 @@
     def descr_repr( self, space ):
         return space.wrap( self.__repr__() )
     
+    def fget_parent(space, self):
+        return space.wrap(self.parent)
+
+    def fset_parent(space, self, w_parent):
+        self.parent = space.interp_w(Node, w_parent, can_be_None=False)
+
     def descr_getChildNodes( self, space ):
         lst = self.getChildNodes()
         return space.newlist( [ space.wrap( it ) for it in lst ] )
@@ -714,10 +760,13 @@
                        mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ),
                        lineno = interp_attrproperty('lineno', cls=Node),
                        filename = interp_attrproperty('filename', cls=Node),
+                       parent=GetSetProperty(Node.fget_parent, Node.fset_parent),
                        )
 
 Node.typedef.acceptable_as_base_class = False
         
+Node.typedef.acceptable_as_base_class = False
+        
 class EmptyNode(Node):
     def accept(self, visitor):
         return visitor.visitEmptyNode(self)

Modified: pypy/dist/pypy/interpreter/pycompiler.py
==============================================================================
--- pypy/dist/pypy/interpreter/pycompiler.py	(original)
+++ pypy/dist/pypy/interpreter/pycompiler.py	Mon Feb 26 15:06:33 2007
@@ -189,6 +189,7 @@
         warnings.warn_explicit = old_warn_explicit
 
 
+
 ########
 class PythonAstCompiler(PyCodeCompiler):
     """Uses the stdlib's python implementation of compiler
@@ -198,6 +199,13 @@
          of incomplete inputs (e.g. we shouldn't re-compile from sracth
          the whole source after having only added a new '\n')
     """
+    def __init__(self, space):
+        from pyparser.pythonparse import PYTHON_PARSER
+        PyCodeCompiler.__init__(self, space)
+        self.parser = PYTHON_PARSER
+        self.additional_rules = {}
+    
+
     def compile(self, source, filename, mode, flags):
         from pyparser.error import SyntaxError
         from pypy.interpreter import astcompiler
@@ -205,15 +213,18 @@
         from pypy.interpreter.astcompiler.pycodegen import InteractiveCodeGenerator
         from pypy.interpreter.astcompiler.pycodegen import ExpressionCodeGenerator
         from pypy.interpreter.astcompiler.ast import Node
-        from pyparser.pythonutil import AstBuilder, PYTHON_PARSER, TARGET_DICT
+        from pyparser.astbuilder import AstBuilder
         from pypy.interpreter.pycode import PyCode
+        from pypy.interpreter.function import Function
 
         flags |= stdlib___future__.generators.compiler_flag   # always on (2.2 compat)
         space = self.space
         try:
-            builder = AstBuilder(space=space)
-            target_rule = TARGET_DICT[mode]
-            PYTHON_PARSER.parse_source(source, target_rule, builder, flags)
+            builder = AstBuilder(self.parser, space=space)
+            for rulename, buildfunc in self.additional_rules.iteritems():
+                assert isinstance(buildfunc, Function)
+                builder.user_build_rules[rulename] = buildfunc
+            self.parser.parse_source(source, mode, builder, flags)
             ast_tree = builder.rule_stack[-1]
             encoding = builder.source_encoding
         except SyntaxError, e:
@@ -251,4 +262,29 @@
 def install_compiler_hook(space, w_callable):
 #       if not space.get( w_callable ):
 #           raise OperationError( space.w_TypeError( space.wrap( "must have a callable" ) )
-        space.default_compiler.w_compile_hook = w_callable
+    space.default_compiler.w_compile_hook = w_callable
+
+def insert_grammar_rule(space, w_rule, w_buildfuncs):
+    """inserts new grammar rules to the default compiler"""
+    from pypy.interpreter import function
+    rule = space.str_w(w_rule)
+    #buildfuncs_w = w_buildfuncs.content
+    buildfuncs = {}
+    #for w_name, w_func in buildfuncs_w.iteritems():
+    #    buildfuncs[space.str_w(w_name)] = space.unwrap(w_func)
+    w_iter = space.iter(w_buildfuncs)
+    while 1:
+        try:
+            w_key = space.next(w_iter)
+            w_func = space.getitem(w_buildfuncs, w_key)
+            buildfuncs[space.str_w(w_key)] = space.interp_w(function.Function, w_func)
+        except OperationError, e:
+            if not e.match(space, space.w_StopIteration):
+                raise
+            break
+    space.default_compiler.additional_rules = buildfuncs
+    space.default_compiler.parser.insert_rule(rule)
+    
+# XXX cyclic import
+#from pypy.interpreter.baseobjspace import ObjSpace
+#insert_grammar_rule.unwrap_spec = [ObjSpace, str, dict]

Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/astbuilder.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py	Mon Feb 26 15:06:33 2007
@@ -1,518 +1,18 @@
 """This module provides the astbuilder class which is to be used
-by GrammarElements to directly build the AST during parsing
+by GrammarElements to directly build the AS during parsing
 without going through the nested tuples step
 """
 
 from grammar import BaseGrammarBuilder, AbstractContext
+
+from pypy.interpreter.function import Function
 from pypy.interpreter.astcompiler import ast, consts
-from pypy.interpreter.pyparser import pythonparse
-import pypy.interpreter.pyparser.pytoken as tok
+# from pypy.interpreter.pyparser import pythonparse
+#import pypy.interpreter.pyparser.pytoken as tok
 from pypy.interpreter.pyparser.error import SyntaxError
 from pypy.interpreter.pyparser.parsestring import parsestr
-
-sym      = pythonparse.PYTHON_PARSER.symbols
-
-DEBUG_MODE = 0
-
-### Parsing utilites #################################################
-def parse_except_clause(tokens):
-    """parses 'except' [test [',' test]] ':' suite
-    and returns a 4-tuple : (tokens_read, expr1, expr2, except_body)
-    """
-    lineno = tokens[0].lineno
-    clause_length = 1
-    # Read until end of except clause (bound by following 'else',
-    # or 'except' or end of tokens)
-    while clause_length < len(tokens):
-        token = tokens[clause_length]
-        if isinstance(token, TokenObject) and \
-           (token.get_value() == 'except' or token.get_value() == 'else'):
-            break
-        clause_length += 1
-    if clause_length == 3:
-        # case 'except: body'
-        return (3, None, None, tokens[2])
-    elif clause_length == 4:
-        # case 'except Exception: body':
-        return (4, tokens[1], None, tokens[3])
-    else:
-        # case 'except Exception, exc: body'
-        return (6, tokens[1], to_lvalue(tokens[3], consts.OP_ASSIGN), tokens[5])
-
-
-def parse_dotted_names(tokens):
-    """parses NAME('.' NAME)* and returns full dotted name
-
-    this function doesn't assume that the <tokens> list ends after the
-    last 'NAME' element
-    """
-    first = tokens[0]
-    assert isinstance(first, TokenObject)
-    name = first.get_value()
-    l = len(tokens)
-    index = 1
-    for index in range(1, l, 2):
-        token = tokens[index]
-        assert isinstance(token, TokenObject)
-        if token.name != tok.DOT:
-            break
-        token = tokens[index+1]
-        assert isinstance(token, TokenObject)
-        name += '.'
-        value = token.get_value()
-        name += value
-    return (index, name)
-
-def parse_argument(tokens):
-    """parses function call arguments"""
-    l = len(tokens)
-    index = 0
-    arguments = []
-    last_token = None
-    building_kw = False
-    kw_built = False
-    stararg_token = None
-    dstararg_token = None
-    while index < l:
-        cur_token = tokens[index]
-        if not isinstance(cur_token, TokenObject):
-            index += 1
-            if not building_kw:
-                arguments.append(cur_token)
-            else:
-                last_token = arguments.pop()
-                assert isinstance(last_token, ast.Name) # used by rtyper
-                arguments.append(ast.Keyword(last_token.varname, cur_token, last_token.lineno))
-                building_kw = False
-                kw_built = True
-            continue
-        elif cur_token.name == tok.COMMA:
-            index += 1
-            continue
-        elif cur_token.name == tok.EQUAL:
-            index += 1
-            building_kw = True
-            continue
-        elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR:
-            index += 1
-            if cur_token.name == tok.STAR:
-                stararg_token = tokens[index]
-                index += 1
-                if index >= l:
-                    break
-                index += 2 # Skip COMMA and DOUBLESTAR
-            dstararg_token = tokens[index]
-            break
-        elif cur_token.get_value() == 'for':
-            if len(arguments) != 1:
-                raise SyntaxError("invalid syntax", cur_token.lineno,
-                                  cur_token.col)
-            expr = arguments[0]
-            genexpr_for = parse_genexpr_for(tokens[index:])
-            genexpr_for[0].is_outmost = True
-            gexp = ast.GenExpr(ast.GenExprInner(expr, genexpr_for, expr.lineno), expr.lineno)
-            arguments[0] = gexp
-            break
-    return arguments, stararg_token, dstararg_token
-
-
-def parse_fpdef(tokens, index):
-    """fpdef: fpdef: NAME | '(' fplist ')'
-    fplist: fpdef (',' fpdef)* [',']
-
-    This intend to be a RPYTHON compliant implementation of _parse_fpdef,
-    but it can't work with the default compiler.
-    We switched to use astcompiler module now
-    """
-    nodes = []
-    comma = False
-    while True:
-        token = tokens[index]
-        index += 1
-        assert isinstance(token, TokenObject)
-        if token.name == tok.LPAR:       # nested item
-            index, node = parse_fpdef(tokens, index)
-        elif token.name == tok.RPAR:     # end of current nesting
-            break
-        else:                            # name
-            val = token.get_value()
-            node = ast.AssName(val, consts.OP_ASSIGN, token.lineno)
-        nodes.append(node)
-
-        token = tokens[index]
-        index += 1
-        assert isinstance(token, TokenObject)
-        if token.name == tok.COMMA:
-            comma = True
-        else:
-            assert token.name == tok.RPAR
-            break
-    if len(nodes) == 1 and not comma:
-        node = nodes[0]
-    else:
-        node = ast.AssTuple(nodes, token.lineno)
-    return index, node
-
-def parse_arglist(tokens):
-    """returns names, defaults, flags"""
-    l = len(tokens)
-    index = 0
-    defaults = []
-    names = []
-    flags = 0
-    first_with_default = -1
-    while index < l:
-        cur_token = tokens[index]
-        index += 1
-        if not isinstance(cur_token, TokenObject):
-            # XXX: think of another way to write this test
-            defaults.append(cur_token)
-            if first_with_default == -1:
-                first_with_default = len(names) - 1
-        elif cur_token.name == tok.COMMA:
-            # We could skip test COMMA by incrementing index cleverly
-            # but we might do some experiment on the grammar at some point
-            continue
-        elif cur_token.name == tok.LPAR:
-            index, node = parse_fpdef(tokens, index)
-            names.append(node)
-        elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR:
-            if cur_token.name == tok.STAR:
-                cur_token = tokens[index]
-                assert isinstance(cur_token, TokenObject)
-                index += 1
-                if cur_token.name == tok.NAME:
-                    val = cur_token.get_value()
-                    names.append( ast.AssName( val, consts.OP_ASSIGN ) )
-                    flags |= consts.CO_VARARGS
-                    index += 1
-                    if index >= l:
-                        break
-                    else:
-                        # still more tokens to read
-                        cur_token = tokens[index]
-                        index += 1
-                else:
-                    raise SyntaxError("incomplete varags", cur_token.lineno,
-                                      cur_token.col)
-            assert isinstance(cur_token, TokenObject)
-            if cur_token.name != tok.DOUBLESTAR:
-                raise SyntaxError("Unexpected token", cur_token.lineno,
-                                  cur_token.col)
-            cur_token = tokens[index]
-            index += 1
-            assert isinstance(cur_token, TokenObject)
-            if cur_token.name == tok.NAME:
-                val = cur_token.get_value()
-                names.append( ast.AssName( val, consts.OP_ASSIGN ) )
-                flags |= consts.CO_VARKEYWORDS
-                index +=  1
-            else:
-                raise SyntaxError("incomplete varags", cur_token.lineno,
-                                  cur_token.col)
-            if index < l:
-                token = tokens[index]
-                raise SyntaxError("unexpected token" , token.lineno,
-                                  token.col)
-        elif cur_token.name == tok.NAME:
-            val = cur_token.get_value()
-            names.append( ast.AssName( val, consts.OP_ASSIGN ) )
-
-    if first_with_default != -1:
-        num_expected_with_default = len(names) - first_with_default
-        if flags & consts.CO_VARKEYWORDS:
-            num_expected_with_default -= 1
-        if flags & consts.CO_VARARGS:
-            num_expected_with_default -= 1
-        if len(defaults) != num_expected_with_default:
-            raise SyntaxError('non-default argument follows default argument',
-                              tokens[0].lineno, tokens[0].col)
-    return names, defaults, flags
-
-
-def parse_listcomp(tokens):
-    """parses 'for j in k for i in j if i %2 == 0' and returns
-    a GenExprFor instance
-    XXX: refactor with listmaker ?
-    """
-    list_fors = []
-    ifs = []
-    index = 0
-    if tokens:
-        lineno = tokens[0].lineno
-    else:
-        lineno = -1
-    while index < len(tokens):
-        token = tokens[index]
-        assert isinstance(token, TokenObject) # rtyper info + check
-        if token.get_value() == 'for':
-            index += 1 # skip 'for'
-            ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN)
-            index += 2 # skip 'in'
-            iterables = [tokens[index]]
-            index += 1
-            while index < len(tokens):
-                tok2 = tokens[index]
-                if not isinstance(tok2, TokenObject):
-                    break
-                if tok2.name != tok.COMMA:
-                    break
-                iterables.append(tokens[index+1])
-                index += 2
-            if len(iterables) == 1:
-                iterable = iterables[0]
-            else:
-                iterable = ast.Tuple(iterables, token.lineno)
-            while index < len(tokens):
-                token = tokens[index]
-                assert isinstance(token, TokenObject) # rtyper info
-                if token.get_value() == 'if':
-                    ifs.append(ast.ListCompIf(tokens[index+1], token.lineno))
-                    index += 2
-                else:
-                    break
-            list_fors.append(ast.ListCompFor(ass_node, iterable, ifs, lineno))
-            ifs = []
-        else:
-            assert False, 'Unexpected token: expecting for in listcomp'
-        #
-        # Original implementation:
-        #
-        # if tokens[index].get_value() == 'for':
-        #     index += 1 # skip 'for'
-        #     ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN)
-        #     index += 2 # skip 'in'
-        #     iterable = tokens[index]
-        #     index += 1
-        #     while index < len(tokens) and tokens[index].get_value() == 'if':
-        #         ifs.append(ast.ListCompIf(tokens[index+1]))
-        #         index += 2
-        #     list_fors.append(ast.ListCompFor(ass_node, iterable, ifs))
-        #     ifs = []
-        # else:
-        #     raise ValueError('Unexpected token: %s' % tokens[index])
-    return list_fors
-
-
-def parse_genexpr_for(tokens):
-    """parses 'for j in k for i in j if i %2 == 0' and returns
-    a GenExprFor instance
-    XXX: if RPYTHON supports to pass a class object to a function,
-         we could refactor parse_listcomp and parse_genexpr_for,
-         and call :
-           - parse_listcomp(tokens, forclass=ast.GenExprFor, ifclass=...)
-         or:
-           - parse_listcomp(tokens, forclass=ast.ListCompFor, ifclass=...)
-    """
-    genexpr_fors = []
-    ifs = []
-    index = 0
-    if tokens:
-        lineno = tokens[0].lineno
-    else:
-        lineno = -1
-    while index < len(tokens):
-        token = tokens[index]
-        assert isinstance(token, TokenObject) # rtyper info + check
-        if token.get_value() == 'for':
-            index += 1 # skip 'for'
-            ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN)
-            index += 2 # skip 'in'
-            iterable = tokens[index]
-            index += 1
-            while index < len(tokens):
-                token = tokens[index]
-                assert isinstance(token, TokenObject) # rtyper info
-                if token.get_value() == 'if':
-                    ifs.append(ast.GenExprIf(tokens[index+1], token.lineno))
-                    index += 2
-                else:
-                    break
-            genexpr_fors.append(ast.GenExprFor(ass_node, iterable, ifs, lineno))
-            ifs = []
-        else:
-            raise SyntaxError('invalid syntax',
-                              token.lineno, token.col)
-    return genexpr_fors
-
-
-def get_docstring(builder,stmt):
-    """parses a Stmt node.
-
-    If a docstring if found, the Discard node is **removed**
-    from <stmt> and the docstring is returned.
-
-    If no docstring is found, <stmt> is left unchanged
-    and None is returned
-    """
-    if not isinstance(stmt, ast.Stmt):
-        return None
-    doc = builder.wrap_none()
-    if len(stmt.nodes):
-        first_child = stmt.nodes[0]
-        if isinstance(first_child, ast.Discard):
-            expr = first_child.expr
-            if builder.is_basestring_const(expr):
-                # This *is* a docstring, remove it from stmt list
-                assert isinstance(expr, ast.Const)
-                del stmt.nodes[0]
-                doc = expr.value
-    return doc
-
-
-def to_lvalue(ast_node, flags):
-    lineno = ast_node.lineno
-    if isinstance( ast_node, ast.Name ):
-        return ast.AssName(ast_node.varname, flags, lineno)
-        # return ast.AssName(ast_node.name, flags)
-    elif isinstance(ast_node, ast.Tuple):
-        nodes = []
-        # FIXME: should ast_node.getChildren() but it's not annotable
-        #        because of flatten()
-        for node in ast_node.nodes:
-            nodes.append(to_lvalue(node, flags))
-        return ast.AssTuple(nodes, lineno)
-    elif isinstance(ast_node, ast.List):
-        nodes = []
-        # FIXME: should ast_node.getChildren() but it's not annotable
-        #        because of flatten()
-        for node in ast_node.nodes:
-            nodes.append(to_lvalue(node, flags))
-        return ast.AssList(nodes, lineno)
-    elif isinstance(ast_node, ast.Getattr):
-        expr = ast_node.expr
-        assert isinstance(ast_node, ast.Getattr)
-        attrname = ast_node.attrname
-        return ast.AssAttr(expr, attrname, flags, lineno)
-    elif isinstance(ast_node, ast.Subscript):
-        ast_node.flags = flags
-        return ast_node
-    elif isinstance(ast_node, ast.Slice):
-        ast_node.flags = flags
-        return ast_node
-    else:
-        if isinstance(ast_node, ast.GenExpr):
-            raise SyntaxError("assign to generator expression not possible",
-                             lineno, 0, '')
-        elif isinstance(ast_node, ast.ListComp):
-            raise SyntaxError("can't assign to list comprehension",
-                             lineno, 0, '')
-        elif isinstance(ast_node, ast.CallFunc):
-            if flags == consts.OP_DELETE:
-                raise SyntaxError("can't delete function call",
-                                 lineno, 0, '')
-            else:
-                raise SyntaxError("can't assign to function call",
-                                 lineno, 0, '')
-        else:
-            raise SyntaxError("can't assign to non-lvalue",
-                             lineno, 0, '')
-
-def is_augassign( ast_node ):
-    if ( isinstance( ast_node, ast.Name ) or
-         isinstance( ast_node, ast.Slice ) or
-         isinstance( ast_node, ast.Subscript ) or
-         isinstance( ast_node, ast.Getattr ) ):
-        return True
-    return False
-
-def get_atoms(builder, nb):
-    atoms = []
-    i = nb
-    while i>0:
-        obj = builder.pop()
-        if isinstance(obj, BaseRuleObject):
-            i += obj.count
-        else:
-            atoms.append( obj )
-        i -= 1
-    atoms.reverse()
-    return atoms
-
-#def eval_string(value):
-#    """temporary implementation
-#
-#    FIXME: need to be finished (check compile.c (parsestr) and
-#    stringobject.c (PyString_DecodeEscape()) for complete implementation)
-#    """
-#    # return eval(value)
-#    if len(value) == 2:
-#        return ''
-#    result = ''
-#    length = len(value)
-#    quotetype = value[0]
-#    index = 1
-#    while index < length and value[index] == quotetype:
-#        index += 1
-#    if index == 6:
-#        # empty strings like """""" or ''''''
-#        return ''
-#    # XXX: is it RPYTHON to do this value[index:-index]
-#    chars = [char for char in value[index:len(value)-index]]
-#    result = ''.join(chars)
-#    result = result.replace('\\\\', '\\')
-#    d = {'\\b' : '\b', '\\f' : '\f', '\\t' : '\t', '\\n' : '\n',
-#         '\\r' : '\r', '\\v' : '\v', '\\a' : '\a',
-#         }
-#    for escaped, value in d.items():
-#        result = result.replace(escaped, value)
-#    return result
-
-
-## misc utilities, especially for power: rule
-def reduce_callfunc(obj, arglist):
-    """generic factory for CallFunc nodes"""
-    assert isinstance(arglist, ArglistObject)
-    return ast.CallFunc(obj, arglist.arguments,
-                        arglist.stararg, arglist.dstararg, arglist.lineno)
-
-def reduce_subscript(obj, subscript):
-    """generic factory for Subscript nodes"""
-    assert isinstance(subscript, SubscriptObject)
-    return ast.Subscript(obj, consts.OP_APPLY, subscript.value, subscript.lineno)
-
-def reduce_slice(obj, sliceobj):
-    """generic factory for Slice nodes"""
-    assert isinstance(sliceobj, SlicelistObject)
-    if sliceobj.fake_rulename == 'slice':
-        start = sliceobj.value[0]
-        end = sliceobj.value[1]
-        return ast.Slice(obj, consts.OP_APPLY, start, end, sliceobj.lineno)
-    else:
-        return ast.Subscript(obj, consts.OP_APPLY, ast.Sliceobj(sliceobj.value,
-                                                                sliceobj.lineno), sliceobj.lineno)
-
-def parse_attraccess(tokens):
-    """parses token list like ['a', '.', 'b', '.', 'c', ...]
-
-    and returns an ast node : ast.Getattr(Getattr(Name('a'), 'b'), 'c' ...)
-    """
-    token = tokens[0]
-    # XXX HACK for when parse_attraccess is called from build_decorator
-    if isinstance(token, TokenObject):
-        val = token.get_value()
-        result = ast.Name(val, token.lineno)
-    else:
-        result = token
-    index = 1
-    while index < len(tokens):
-        token = tokens[index]
-        if isinstance(token, TokenObject) and token.name == tok.DOT:
-            index += 1
-            token = tokens[index]
-            assert isinstance(token, TokenObject)
-            result = ast.Getattr(result, token.get_value(), token.lineno)
-        elif isinstance(token, ArglistObject):
-            result = reduce_callfunc(result, token)
-        elif isinstance(token, SubscriptObject):
-            result = reduce_subscript(result, token)
-        elif isinstance(token, SlicelistObject):
-            result = reduce_slice(result, token)
-        else:
-            assert False, "Don't know how to handle index %s of %s" % (index, len(tokens))
-        index += 1
-    return result
-
+from pypy.interpreter.gateway import interp2app
+from asthelper import *
 
 ## building functions helpers
 ## --------------------------
@@ -546,31 +46,31 @@
     top = atoms[0]
     if isinstance(top, TokenObject):
         # assert isinstance(top, TokenObject) # rtyper
-        if top.name == tok.LPAR:
+        if top.name == builder.parser.tokens['LPAR']:
             if len(atoms) == 2:
                 builder.push(ast.Tuple([], top.lineno))
             else:
                 builder.push( atoms[1] )
-        elif top.name == tok.LSQB:
+        elif top.name == builder.parser.tokens['LSQB']:
             if len(atoms) == 2:
                 builder.push(ast.List([], top.lineno))
             else:
                 list_node = atoms[1]
                 list_node.lineno = top.lineno
                 builder.push(list_node)
-        elif top.name == tok.LBRACE:
+        elif top.name == builder.parser.tokens['LBRACE']:
             items = []
             for index in range(1, len(atoms)-1, 4):
                 # a   :   b   ,   c : d
                 # ^  +1  +2  +3  +4
                 items.append((atoms[index], atoms[index+2]))
             builder.push(ast.Dict(items, top.lineno))
-        elif top.name == tok.NAME:
+        elif top.name == builder.parser.tokens['NAME']:
             val = top.get_value()
             builder.push( ast.Name(val, top.lineno) )
-        elif top.name == tok.NUMBER:
+        elif top.name == builder.parser.tokens['NUMBER']:
             builder.push(ast.Const(builder.eval_number(top.get_value()), top.lineno))
-        elif top.name == tok.STRING:
+        elif top.name == builder.parser.tokens['STRING']:
             # need to concatenate strings in atoms
             s = ''
             if len(atoms) == 1:
@@ -586,7 +86,7 @@
                     accum.append(parsestr(builder.space, builder.source_encoding, token.get_value()))
                 w_s = space.call_method(empty, 'join', space.newlist(accum))
                 builder.push(ast.Const(w_s, top.lineno))
-        elif top.name == tok.BACKQUOTE:
+        elif top.name == builder.parser.tokens['BACKQUOTE']:
             builder.push(ast.Backquote(atoms[1], atoms[1].lineno))
         else:
             raise SyntaxError("unexpected tokens", top.lineno, top.col)
@@ -607,11 +107,11 @@
     else:
         lineno = atoms[0].lineno
         token = atoms[-2]
-        if isinstance(token, TokenObject) and token.name == tok.DOUBLESTAR:
-            obj = parse_attraccess(slicecut(atoms, 0, -2))
+        if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOUBLESTAR']:
+            obj = parse_attraccess(slicecut(atoms, 0, -2), builder)
             builder.push(ast.Power( obj, atoms[-1], lineno))
         else:
-            obj = parse_attraccess(atoms)
+            obj = parse_attraccess(atoms, builder)
             builder.push(obj)
 
 def build_factor(builder, nb):
@@ -622,11 +122,11 @@
         token = atoms[0]
         lineno = token.lineno
         if isinstance(token, TokenObject):
-            if token.name == tok.PLUS:
+            if token.name == builder.parser.tokens['PLUS']:
                 builder.push( ast.UnaryAdd( atoms[1], lineno) )
-            if token.name == tok.MINUS:
+            if token.name == builder.parser.tokens['MINUS']:
                 builder.push( ast.UnarySub( atoms[1], lineno) )
-            if token.name == tok.TILDE:
+            if token.name == builder.parser.tokens['TILDE']:
                 builder.push( ast.Invert( atoms[1], lineno) )
 
 def build_term(builder, nb):
@@ -637,13 +137,13 @@
         right = atoms[i]
         op_node = atoms[i-1]
         assert isinstance(op_node, TokenObject)
-        if op_node.name == tok.STAR:
+        if op_node.name == builder.parser.tokens['STAR']:
             left = ast.Mul( left, right, left.lineno )
-        elif op_node.name == tok.SLASH:
+        elif op_node.name == builder.parser.tokens['SLASH']:
             left = ast.Div( left, right, left.lineno )
-        elif op_node.name == tok.PERCENT:
+        elif op_node.name == builder.parser.tokens['PERCENT']:
             left = ast.Mod( left, right, left.lineno )
-        elif op_node.name == tok.DOUBLESLASH:
+        elif op_node.name == builder.parser.tokens['DOUBLESLASH']:
             left = ast.FloorDiv( left, right, left.lineno )
         else:
             token = atoms[i-1]
@@ -658,9 +158,9 @@
         right = atoms[i]
         op_node = atoms[i-1]
         assert isinstance(op_node, TokenObject)
-        if op_node.name == tok.PLUS:
+        if op_node.name == builder.parser.tokens['PLUS']:
             left = ast.Add( left, right, left.lineno)
-        elif op_node.name == tok.MINUS:
+        elif op_node.name == builder.parser.tokens['MINUS']:
             left = ast.Sub( left, right, left.lineno)
         else:
             token = atoms[i-1]
@@ -676,9 +176,9 @@
         right = atoms[i]
         op_node = atoms[i-1]
         assert isinstance(op_node, TokenObject)
-        if op_node.name == tok.LEFTSHIFT:
+        if op_node.name == builder.parser.tokens['LEFTSHIFT']:
             left = ast.LeftShift( left, right, lineno )
-        elif op_node.name == tok.RIGHTSHIFT:
+        elif op_node.name == builder.parser.tokens['RIGHTSHIFT']:
             left = ast.RightShift( left, right, lineno )
         else:
             token = atoms[i-1]
@@ -727,7 +227,7 @@
             # 'is', 'is not', 'not' or 'not in' => tok.get_value()
             token = atoms[i]
             assert isinstance(token, TokenObject)
-            op_name = tok.tok_rpunct.get(token.name, token.get_value())
+            op_name = builder.parser.tok_rvalues.get(token.name, token.get_value())
             ops.append((op_name, atoms[i+1]))
         builder.push(ast.Compare(atoms[0], ops, atoms[0].lineno))
 
@@ -755,9 +255,9 @@
         lineno = token.lineno
         assert isinstance(token, TokenObject)
         if token.get_value() == 'not':
-            builder.push(TokenObject(tok.NAME, 'not in', lineno))
+            builder.push(TokenObject(builder.parser.tokens['NAME'], 'not in', lineno, builder.parser))
         else:
-            builder.push(TokenObject(tok.NAME, 'is not', lineno))
+            builder.push(TokenObject(builder.parser.tokens['NAME'], 'is not', lineno, builder.parser))
     else:
         assert False, "TODO" # uh ?
 
@@ -811,7 +311,7 @@
         return
     op = atoms[1]
     assert isinstance(op, TokenObject)
-    if op.name == tok.EQUAL:
+    if op.name == builder.parser.tokens['EQUAL']:
         nodes = []
         for i in range(0,l-2,2):
             lvalue = to_lvalue(atoms[i], consts.OP_ASSIGN)
@@ -845,7 +345,7 @@
         lineno = -1
     for n in range(0,l,2):
         node = atoms[n]
-        if isinstance(node, TokenObject) and node.name == tok.NEWLINE:
+        if isinstance(node, TokenObject) and node.name == builder.parser.tokens['NEWLINE']:
             nodes.append(ast.Discard(ast.Const(builder.wrap_none()), node.lineno))
         else:
             nodes.append(node)
@@ -871,10 +371,10 @@
     for node in atoms:
         if isinstance(node, ast.Stmt):
             stmts.extend(node.nodes)
-        elif isinstance(node, TokenObject) and node.name == tok.ENDMARKER:
+        elif isinstance(node, TokenObject) and node.name == builder.parser.tokens['ENDMARKER']:
             # XXX Can't we just remove the last element of the list ?
             break
-        elif isinstance(node, TokenObject) and node.name == tok.NEWLINE:
+        elif isinstance(node, TokenObject) and node.name == builder.parser.tokens['NEWLINE']:
             continue
         else:
             stmts.append(node)
@@ -894,11 +394,12 @@
     l = len(atoms)
     if l == 1 or l==2:
         atom0 = atoms[0]
-        if isinstance(atom0, TokenObject) and atom0.name == tok.NEWLINE:
-            atom0 = ast.Pass(atom0.lineno)
+        if isinstance(atom0, TokenObject) and atom0.name == builder.parser.tokens['NEWLINE']:
+            # atom0 = ast.Pass(atom0.lineno) # break test_astcompiler
+            atom0 = ast.Stmt([], atom0.lineno) # break test_astbuilder
         elif not isinstance(atom0, ast.Stmt):
             atom0 = ast.Stmt([atom0], atom0.lineno)
-        builder.push(ast.Module(builder.wrap_none(), atom0, atom0.lineno))
+        builder.push(ast.Module(builder.space.w_None, atom0, atom0.lineno))
     else:
         assert False, "Forbidden path"
 
@@ -914,7 +415,7 @@
         return
     items = []
     token = atoms[1]
-    if isinstance(token, TokenObject) and token.name == tok.COMMA:
+    if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COMMA']:
         for i in range(0, l, 2): # this is atoms not 1
             items.append(atoms[i])
     else:
@@ -944,7 +445,7 @@
     atoms = get_atoms(builder, nb)
     lineno = atoms[0].lineno
     code = atoms[-1]
-    names, defaults, flags = parse_arglist(slicecut(atoms, 1, -2))
+    names, defaults, flags = parse_arglist(slicecut(atoms, 1, -2), builder)
     builder.push(ast.Lambda(names, defaults, flags, code, lineno))
 
 def build_trailer(builder, nb):
@@ -953,13 +454,13 @@
     atoms = get_atoms(builder, nb)
     first_token = atoms[0]
     # Case 1 : '(' ...
-    if isinstance(first_token, TokenObject) and first_token.name == tok.LPAR:
-        if len(atoms) == 2: # and atoms[1].token == tok.RPAR:
+    if isinstance(first_token, TokenObject) and first_token.name == builder.parser.tokens['LPAR']:
+        if len(atoms) == 2: # and atoms[1].token == builder.parser.tokens['RPAR']:
             builder.push(ArglistObject([], None, None, first_token.lineno))
         elif len(atoms) == 3: # '(' Arglist ')'
             # push arglist on the stack
             builder.push(atoms[1])
-    elif isinstance(first_token, TokenObject) and first_token.name == tok.LSQB:
+    elif isinstance(first_token, TokenObject) and first_token.name == builder.parser.tokens['LSQB']:
         if len(atoms) == 3 and isinstance(atoms[1], SlicelistObject):
             builder.push(atoms[1])
         else:
@@ -994,6 +495,7 @@
     else:
         assert False, "Trailer reducing implementation incomplete !"
 
+
 def build_arglist(builder, nb):
     """
     arglist: (argument ',')* ( '*' test [',' '**' test] |
@@ -1002,7 +504,7 @@
                                 [argument ','] )
     """
     atoms = get_atoms(builder, nb)
-    arguments, stararg, dstararg = parse_argument(atoms)
+    arguments, stararg, dstararg = parse_argument(atoms, builder)
     if atoms:
         lineno = atoms[0].lineno
     else:
@@ -1010,16 +512,17 @@
     builder.push(ArglistObject(arguments, stararg, dstararg, lineno))
 
 
+
 def build_subscript(builder, nb):
     """'.' '.' '.' | [test] ':' [test] [':' [test]] | test"""
     atoms = get_atoms(builder, nb)
     token = atoms[0]
     lineno = token.lineno
-    if isinstance(token, TokenObject) and token.name == tok.DOT:
+    if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOT']:
         # Ellipsis:
         builder.push(ast.Ellipsis(lineno))
     elif len(atoms) == 1:
-        if isinstance(token, TokenObject) and token.name == tok.COLON:
+        if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COLON']:
             sliceinfos = [None, None, None]
             builder.push(SlicelistObject('slice', sliceinfos, lineno))
         else:
@@ -1029,7 +532,7 @@
         sliceinfos = [None, None, None]
         infosindex = 0
         for token in atoms:
-            if isinstance(token, TokenObject) and token.name == tok.COLON:
+            if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COLON']:
                 infosindex += 1
             else:
                 sliceinfos[infosindex] = token
@@ -1044,7 +547,6 @@
         else:
             builder.push(SlicelistObject('slice', sliceinfos, lineno))
 
-
 def build_listmaker(builder, nb):
     """listmaker: test ( list_for | (',' test)* [','] )"""
     atoms = get_atoms(builder, nb)
@@ -1055,7 +557,7 @@
             if token.get_value() == 'for':
                 # list comp
                 expr = atoms[0]
-                list_for = parse_listcomp(atoms[1:])
+                list_for = parse_listcomp(atoms[1:], builder)
                 builder.push(ast.ListComp(expr, list_for, lineno))
                 return
     # regular list building (like in [1, 2, 3,])
@@ -1077,13 +579,15 @@
     nodes = []
     # remove '@', '(' and ')' from atoms and use parse_attraccess
     for token in atoms[1:]:
-        if isinstance(token, TokenObject) and \
-               token.name in (tok.LPAR, tok.RPAR, tok.NEWLINE):
+        if isinstance(token, TokenObject) and (
+               token.name == builder.parser.tokens['LPAR']
+               or token.name == builder.parser.tokens['RPAR']
+               or token.name == builder.parser.tokens['NEWLINE']):
             # skip those ones
             continue
         else:
             nodes.append(token)
-    obj = parse_attraccess(nodes)
+    obj = parse_attraccess(nodes, builder)
     builder.push(obj)
 
 def build_funcdef(builder, nb):
@@ -1112,7 +616,7 @@
     arglist = []
     index = 3
     arglist = slicecut(atoms, 3, -3)
-    names, default, flags = parse_arglist(arglist)
+    names, default, flags = parse_arglist(arglist, builder)
     funcname_token = atoms[1]
     assert isinstance(funcname_token, TokenObject)
     funcname = funcname_token.get_value()
@@ -1293,7 +797,7 @@
     while index < l:
         as_name = None
         # dotted name (a.b.c)
-        incr, name = parse_dotted_names(atoms[index:])
+        incr, name = parse_dotted_names(atoms[index:], builder)
         index += incr
         # 'as' value
         if index < l:
@@ -1310,11 +814,11 @@
         while index<l:
             atom = atoms[index]
 #        for atom in atoms[index:]:
-            if isinstance(atom, TokenObject) and atom.name == tok.COMMA:
+            if isinstance(atom, TokenObject) and atom.name == builder.parser.tokens['COMMA']:
                 break
             index += 1
 ##         while index < l and isinstance(atoms[index], TokenObject) and \
-##                 atoms[index].name != tok.COMMA:
+##                 atoms[index].name != builder.parser.tokens['COMMA']:
 ##             index += 1
         index += 1
     builder.push(ast.Import(names, atoms[0].lineno))
@@ -1329,14 +833,14 @@
     """
     atoms = get_atoms(builder, nb)
     index = 1
-    incr, from_name = parse_dotted_names(atoms[index:])
+    incr, from_name = parse_dotted_names(atoms[index:], builder)
     index += (incr + 1) # skip 'import'
     token = atoms[index]
     assert isinstance(token, TokenObject) # XXX
-    if token.name == tok.STAR:
+    if token.name == builder.parser.tokens['STAR']:
         names = [('*', None)]
     else:
-        if token.name == tok.LPAR:
+        if token.name == builder.parser.tokens['LPAR']:
             # mutli-line imports
             tokens = slicecut( atoms, index+1, -1 )
         else:
@@ -1417,14 +921,14 @@
     start = 1
     if l > 1:
         token = atoms[1]
-        if isinstance(token, TokenObject) and token.name == tok.RIGHTSHIFT:
+        if isinstance(token, TokenObject) and token.name == builder.parser.tokens['RIGHTSHIFT']:
             dest = atoms[2]
             # skip following comma
             start = 4
     for index in range(start, l, 2):
         items.append(atoms[index])
     last_token = atoms[-1]
-    if isinstance(last_token, TokenObject) and last_token.name == tok.COMMA:
+    if isinstance(last_token, TokenObject) and last_token.name == builder.parser.tokens['COMMA']:
         builder.push(ast.Print(items, dest, atoms[0].lineno))
     else:
         builder.push(ast.Printnl(items, dest, atoms[0].lineno))
@@ -1464,8 +968,8 @@
 
     """
     atoms = get_atoms(builder, nb)
-    l = len(atoms)
     handlers = []
+    l = len(atoms)
     else_ = None
     body = atoms[2]
     token = atoms[3]
@@ -1545,133 +1049,6 @@
     'with_stmt' : build_with_stmt,
     }
 
-# Build two almost identical ASTRULES dictionaries
-ASTRULES      = dict([(sym[key], value) for (key, value) in
-                      ASTRULES_Template.iteritems() if key in sym])
-del ASTRULES_Template
-
-## Stack elements definitions ###################################
-
-class BaseRuleObject(ast.Node):
-    """Base class for unnamed rules"""
-    def __init__(self, count, lineno):
-        self.count = count
-        self.lineno = lineno # src.getline()
-        self.col = 0  # src.getcol()
-
-
-class RuleObject(BaseRuleObject):
-    """A simple object used to wrap a rule or token"""
-    def __init__(self, name, count, lineno):
-        BaseRuleObject.__init__(self, count, lineno)
-        self.rulename = name
-
-    def __str__(self):
-        return "<Rule: %s/%d>" % (sym.sym_name[self.rulename], self.count)
-
-    def __repr__(self):
-        return "<Rule: %s/%d>" % (sym.sym_name[self.rulename], self.count)
-
-
-class TempRuleObject(BaseRuleObject):
-    """used to keep track of how many items get_atom() should pop"""
-
-    def __init__(self, name, count, lineno):
-        BaseRuleObject.__init__(self, count, lineno)
-        self.temp_rulename = name
-
-    def __str__(self):
-        return "<Rule: %s/%d>" % (self.temp_rulename, self.count)
-
-    def __repr__(self):
-        return "<Rule: %s/%d>" % (self.temp_rulename, self.count)
-
-
-class TokenObject(ast.Node):
-    """A simple object used to wrap a rule or token"""
-    def __init__(self, name, value, lineno):
-        self.name = name
-        self.value = value
-        self.count = 0
-        # self.line = 0 # src.getline()
-        self.col = 0  # src.getcol()
-        self.lineno = lineno
-
-    def get_name(self):
-        return tok.tok_rpunct.get(self.name,
-                                  tok.tok_name.get(self.name, str(self.name)))
-
-    def get_value(self):
-        value = self.value
-        if value is None:
-            value = ''
-        return value
-
-    def __str__(self):
-        return "<Token: (%s,%s)>" % (self.get_name(), self.value)
-
-    def __repr__(self):
-        return "<Token: (%r,%s)>" % (self.get_name(), self.value)
-
-
-class ObjectAccessor(ast.Node):
-    """base class for ArglistObject, SubscriptObject and SlicelistObject
-
-    FIXME: think about a more appropriate name
-    """
-
-class ArglistObject(ObjectAccessor):
-    """helper class to build function's arg list
-    """
-    def __init__(self, arguments, stararg, dstararg, lineno):
-        self.fake_rulename = 'arglist'
-        self.arguments = arguments
-        self.stararg = stararg
-        self.dstararg = dstararg
-        self.lineno = lineno
-
-    def __str__(self):
-        return "<ArgList: (%s, %s, %s)>" % self.value
-
-    def __repr__(self):
-        return "<ArgList: (%s, %s, %s)>" % self.value
-
-class SubscriptObject(ObjectAccessor):
-    """helper class to build subscript list
-
-    self.value represents the __getitem__ argument
-    """
-    def __init__(self, name, value, lineno):
-        self.fake_rulename = name
-        self.value = value
-        self.lineno = lineno
-
-    def __str__(self):
-        return "<SubscriptList: (%s)>" % self.value
-
-    def __repr__(self):
-        return "<SubscriptList: (%s)>" % self.value
-
-class SlicelistObject(ObjectAccessor):
-    """helper class to build slice objects
-
-    self.value is a list [start, end, step]
-    self.fake_rulename can either be 'slice' or 'sliceobj' depending
-    on if a step is specfied or not (see Python's AST
-    for more information on that)
-    """
-    def __init__(self, name, value, lineno):
-        self.fake_rulename = name
-        self.value = value
-        self.lineno = lineno
-
-    def __str__(self):
-        return "<SliceList: (%s)>" % self.value
-
-    def __repr__(self):
-        return "<SliceList: (%s)>" % self.value
-
-
 class AstBuilderContext(AbstractContext):
     """specific context management for AstBuidler"""
     def __init__(self, rule_stack):
@@ -1681,97 +1058,87 @@
 class AstBuilder(BaseGrammarBuilder):
     """A builder that directly produce the AST"""
 
-    def __init__(self, rules=None, debug=0, space=None):
-        BaseGrammarBuilder.__init__(self, rules, debug)
+    def __init__(self, parser, debug=0, space=None):
+        BaseGrammarBuilder.__init__(self, parser, debug)
         self.rule_stack = []
         self.space = space
         self.source_encoding = None
         self.with_enabled = False
+        self.build_rules = ASTRULES_Template
+        self.user_build_rules = {}
 
     def enable_with(self):
         if self.with_enabled:
             return
         self.with_enabled = True
-        self.keywords.update({'with':None, 'as': None})
-
+        # XXX
+        # self.keywords.update({'with':None, 'as': None})
+        
     def context(self):
         return AstBuilderContext(self.rule_stack)
 
     def restore(self, ctx):
-##         if DEBUG_MODE:
-##             print "Restoring context (%s)" % (len(ctx.rule_stack))
         assert isinstance(ctx, AstBuilderContext)
         assert len(self.rule_stack) >= ctx.d
         del self.rule_stack[ctx.d:]
-        #self.rule_stack = ctx.rule_stack
 
     def pop(self):
         return self.rule_stack.pop(-1)
 
     def push(self, obj):
         self.rule_stack.append(obj)
-        if not isinstance(obj, RuleObject) and not isinstance(obj, TokenObject):
-##             if DEBUG_MODE:
-##                 print "Pushed:", str(obj), len(self.rule_stack)
-            pass
-        elif isinstance(obj, TempRuleObject):
-##             if DEBUG_MODE:
-##                 print "Pushed:", str(obj), len(self.rule_stack)
-            pass
-        # print "\t", self.rule_stack
 
     def push_tok(self, name, value, src ):
-        self.push( TokenObject( name, value, src._token_lnum ) )
+        self.push( TokenObject( name, value, src._token_lnum, self.parser ) )
 
     def push_rule(self, name, count, src ):
-        self.push( RuleObject( name, count, src._token_lnum ) )
+        self.push( RuleObject( name, count, src._token_lnum, self.parser ) )
 
     def alternative( self, rule, source ):
         # Do nothing, keep rule on top of the stack
-##        rule_stack = self.rule_stack[:]
         if rule.is_root():
-##             if DEBUG_MODE:
-##                 print "ALT:", sym.sym_name[rule.codename], self.rule_stack
-            builder_func = ASTRULES.get(rule.codename, None)
-            if builder_func:
-                builder_func(self, 1)
+            rulename = self.parser.sym_name[rule.codename]
+            # builder_func = ASTRULES.get(rule.codename, None)
+            w_func = self.user_build_rules.get(rulename, None)
+            # user defined (applevel) function
+            if w_func:
+                w_items = self.space.newlist( [self.space.wrap( it ) for it in get_atoms(self, 1)] )
+                w_astnode = self.space.call_function(w_func, w_items)
+                astnode = self.space.interp_w(ast.Node, w_astnode, can_be_None=False)
+                self.push(astnode)
             else:
-##                 if DEBUG_MODE:
-##                     print "No reducing implementation for %s, just push it on stack" % (
-##                         sym.sym_name[rule.codename])
-                self.push_rule(rule.codename, 1, source)
+                builder_func = self.build_rules.get(rulename, None)
+                if builder_func:
+                    builder_func(self, 1)
+                else:
+                    self.push_rule(rule.codename, 1, source)
         else:
             self.push_rule(rule.codename, 1, source)
-##         if DEBUG_MODE > 1:
-##             show_stack(rule_stack, self.rule_stack)
-##             x = raw_input("Continue ?")
         return True
 
     def sequence(self, rule, source, elts_number):
         """ """
-##        rule_stack = self.rule_stack[:]
         if rule.is_root():
-##             if DEBUG_MODE:
-##                 print "SEQ:", sym.sym_name[rule.codename]
-            builder_func = ASTRULES.get(rule.codename, None)
-            if builder_func:
-                # print "REDUCING SEQUENCE %s" % sym.sym_name[rule.codename]
-                builder_func(self, elts_number)
+            rulename = self.parser.sym_name[rule.codename]
+            # builder_func = ASTRULES.get(rule.codename, None)
+            w_func = self.user_build_rules.get(rulename, None)
+            # user defined (applevel) function
+            if w_func:
+                w_items = self.space.newlist( [self.space.wrap( it ) for it in get_atoms(self, elts_number)] )
+                w_astnode = self.space.call_function(w_func, w_items)
+                astnode = self.space.interp_w(ast.Node, w_astnode, can_be_None=False)
+                self.push(astnode)
             else:
-##                 if DEBUG_MODE:
-##                     print "No reducing implementation for %s, just push it on stack" % (
-##                         sym.sym_name[rule.codename])
-                self.push_rule(rule.codename, elts_number, source)
+                builder_func = self.build_rules.get(rulename, None)
+                if builder_func:
+                    builder_func(self, elts_number)
+                else:
+                    self.push_rule(rule.codename, elts_number, source)
         else:
             self.push_rule(rule.codename, elts_number, source)
-##         if DEBUG_MODE > 1:
-##             show_stack(rule_stack, self.rule_stack)
-##             raw_input("Continue ?")
         return True
 
     def token(self, name, value, source):
-##         if DEBUG_MODE:
-##             print "TOK:", tok.tok_name[name], name, value
         self.push_tok(name, value, source)
         return True
 
@@ -1799,7 +1166,7 @@
             return space.call_function(f, space.wrap(value))
 
     def is_basestring_const(self, expr):
-        if not isinstance(expr,ast.Const):
+        if not isinstance(expr, ast.Const):
             return False
         space = self.space
         return space.is_true(space.isinstance(expr.value,space.w_basestring))

Modified: pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py	Mon Feb 26 15:06:33 2007
@@ -1,47 +1,18 @@
 # This module contains the grammar parser
 # and the symbol mappings
 
-from grammar import BaseGrammarBuilder, Alternative, Sequence, Token, \
-     KleeneStar, GrammarElement, build_first_sets, EmptyToken
+from grammar import Alternative, Sequence, Token, KleeneStar, \
+     GrammarElement, Parser
 
+class GrammarParser(Parser):
+    pass
 
-sym_map = {}
-sym_rmap = {}
-_count = 0
-
-def g_add_symbol( name ):
-    global _count
-    if name in sym_rmap:
-        return sym_rmap[name]
-    val = _count
-    _count += 1
-    sym_map[val] = name
-    sym_rmap[name] = val
-    return val
-
-
-tok_map = {}
-tok_rmap = {}
-
-def g_add_token( **kwargs ):
-    global _count
-    assert len(kwargs) == 1
-    sym, name = kwargs.popitem()
-    if name in tok_rmap:
-        return tok_rmap[name]
-    val = _count
-    _count += 1
-    tok_map[val] = name
-    tok_rmap[name] = val
-    sym_map[val] = sym
-    sym_rmap[sym] = val
-    return val
-
-g_add_token( EOF='EOF' )
+GRAMMAR_GRAMMAR = GrammarParser()
 
 
 def grammar_grammar():
-    """NOT RPYTHON  (mostly because of g_add_token I suppose)
+    """
+    (mostly because of g_add_token I suppose)
     Builds the grammar for the grammar file
 
     Here's the description of the grammar's grammar ::
@@ -51,59 +22,56 @@
       
       alternative: sequence ( '|' sequence )+
       star: '*' | '+'
-      sequence: (SYMBOL star? | STRING | option | group star? )+
+      sequence: (SYMBOL star? | STRING | option | group )+
       option: '[' alternative ']'
       group: '(' alternative ')' star?
     """
-    global sym_map
-    S = g_add_symbol
-    T = g_add_token
+    p = GRAMMAR_GRAMMAR
+    p.add_token('EOF','EOF')
+
     # star: '*' | '+'
-    star          = Alternative( S("star"), [Token(T(TOK_STAR='*')), Token(T(TOK_ADD='+'))] )
-    star_opt      = KleeneStar ( S("star_opt"), 0, 1, rule=star )
+    star          = p.Alternative_n( "star", [p.Token_n('TOK_STAR', '*'), p.Token_n('TOK_ADD', '+')] )
+    star_opt      = p.KleeneStar_n( "star_opt", 0, 1, rule=star )
 
     # rule: SYMBOL ':' alternative
-    symbol        = Sequence(    S("symbol"), [Token(T(TOK_SYMBOL='SYMBOL')), star_opt] )
-    symboldef     = Token(       T(TOK_SYMDEF="SYMDEF") )
-    alternative   = Sequence(    S("alternative"), [])
-    rule          = Sequence(    S("rule"), [symboldef, alternative] )
+    symbol        = p.Sequence_n(    "symbol", [p.Token_n('TOK_SYMBOL'), star_opt] )
+    symboldef     = p.Token_n(       'TOK_SYMDEF' )
+    alternative   = p.Sequence_n(    "alternative", [])
+    rule          = p.Sequence_n(    "rule", [symboldef, alternative] )
 
     # grammar: rule+
-    grammar       = KleeneStar(   S("grammar"), _min=1, rule=rule )
+    grammar       = p.KleeneStar_n(  "grammar", _min=1, rule=rule )
 
     # alternative: sequence ( '|' sequence )*
-    sequence      = KleeneStar(   S("sequence"), 1 )
-    seq_cont_list = Sequence(    S("seq_cont_list"), [Token(T(TOK_BAR='|')), sequence] )
-    sequence_cont = KleeneStar(   S("sequence_cont"),0, rule=seq_cont_list )
-    
+    sequence      = p.KleeneStar_n(  "sequence", 1 )
+    seq_cont_list = p.Sequence_n(    "seq_cont_list", [p.Token_n('TOK_BAR', '|'), sequence] )
+    sequence_cont = p.KleeneStar_n(  "sequence_cont",0, rule=seq_cont_list )
+
     alternative.args = [ sequence, sequence_cont ]
 
     # option: '[' alternative ']'
-    option        = Sequence(    S("option"), [Token(T(TOK_LBRACKET='[')), alternative, Token(T(TOK_RBRACKET=']'))] )
+    option        = p.Sequence_n(    "option", [p.Token_n('TOK_LBRACKET', '['), alternative, p.Token_n('TOK_RBRACKET', ']')] )
 
     # group: '(' alternative ')'
-    group         = Sequence(    S("group"),  [Token(T(TOK_LPAR='(')), alternative, Token(T(TOK_RPAR=')')), star_opt] )
+    group         = p.Sequence_n(    "group",  [p.Token_n('TOK_LPAR', '('), alternative, p.Token_n('TOK_RPAR', ')'), star_opt] )
 
     # sequence: (SYMBOL | STRING | option | group )+
-    string = Token(T(TOK_STRING='STRING'))
-    alt           = Alternative( S("sequence_alt"), [symbol, string, option, group] ) 
+    string = p.Token_n('TOK_STRING')
+    alt           = p.Alternative_n( "sequence_alt", [symbol, string, option, group] )
     sequence.args = [ alt ]
 
+    p.root_rules['grammar'] = grammar
+    p.build_first_sets()
+    return p
 
-    rules = [ star, star_opt, symbol, alternative, rule, grammar, sequence,
-              seq_cont_list, sequence_cont, option, group, alt ]
-    build_first_sets( rules )
-    return grammar
-
-
-GRAMMAR_GRAMMAR = grammar_grammar()
 
-for _sym, _value in sym_rmap.items():
-    globals()[_sym] = _value
+grammar_grammar()
+for _sym, _value in GRAMMAR_GRAMMAR.symbols.items():
+    assert not hasattr( GRAMMAR_GRAMMAR, _sym ), _sym
+    setattr(GRAMMAR_GRAMMAR, _sym, _value )
+
+for _sym, _value in GRAMMAR_GRAMMAR.tokens.items():
+    assert not hasattr( GRAMMAR_GRAMMAR, _sym )
+    setattr(GRAMMAR_GRAMMAR, _sym, _value )
 
-# cleanup
-del _sym
-del _value
 del grammar_grammar
-del g_add_symbol
-del g_add_token

Modified: pypy/dist/pypy/interpreter/pyparser/ebnflexer.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/ebnflexer.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/ebnflexer.py	Mon Feb 26 15:06:33 2007
@@ -3,8 +3,8 @@
 analyser in grammar.py
 """
 
-from grammar import TokenSource, Token
-from ebnfgrammar import *
+from grammar import TokenSource, Token, AbstractContext
+from ebnfgrammar import GRAMMAR_GRAMMAR as G
 
 
 def match_symbol( input, start, stop ):
@@ -15,6 +15,12 @@
         idx+=1
     return idx
 
+
+class GrammarSourceContext(AbstractContext):
+    def __init__(self, pos, peek):
+        self.pos = pos
+        self.peek = peek
+
 class GrammarSource(TokenSource):
     """Fully RPython - see targetebnflexer.py
     The grammar tokenizer
@@ -25,8 +31,9 @@
     SYMBOL: a rule symbol usually appearing right of a SYMDEF
     tokens: '[', ']', '(' ,')', '*', '+', '|'
     """
-    def __init__(self, inpstring ):
-        TokenSource.__init__(self)
+    def __init__(self, parser, inpstring):
+        # TokenSource.__init__(self)
+        self.parser = parser
         self.input = inpstring
         self.pos = 0
         self.begin = 0
@@ -36,7 +43,7 @@
     def context(self):
         """returns an opaque context object, used to backtrack
         to a well known position in the parser"""
-        return self.pos, self._peeked
+        return GrammarSourceContext( self.pos, self._peeked )
 
     def offset(self, ctx=None):
         """Returns the current parsing position from the start
@@ -44,14 +51,16 @@
         if ctx is None:
             return self.pos
         else:
-            assert type(ctx)==int
-            return ctx
+            assert isinstance(ctx, GrammarSourceContext)
+            return ctx.pos
 
     def restore(self, ctx):
         """restore the context provided by context()"""
-        self.pos, self._peeked = ctx
+        assert isinstance( ctx, GrammarSourceContext )
+        self.pos = ctx.pos
+        self._peeked = ctx.peek
 
-    def current_line(self):
+    def current_linesource(self):
         pos = idx = self.begin
         inp = self.input
         end = len(inp)
@@ -65,7 +74,6 @@
     def current_lineno(self):
         return self.current_line
 
-
     def skip_empty_lines(self, input, start, end ):
         idx = start
         # assume beginning of a line
@@ -117,17 +125,18 @@
         # means backtracking more than one token
         # will re-tokenize the stream (but this is the
         # grammar lexer so we don't care really!)
+        _p = self.parser
         if self._peeked is not None:
             peeked = self._peeked
             self._peeked = None
             return peeked
-        
+
         pos = self.pos
         inp = self.input
         end = len(self.input)
         pos = self.skip_empty_lines(inp,pos,end)
         if pos==end:
-            return Token(EOF, None)
+            return _p.build_token( _p.EOF, None)
 
         # at this point nextchar is not a white space nor \n
         nextchr = inp[pos]
@@ -139,22 +148,22 @@
             self.pos = npos
             _endpos = npos - 1
             assert _endpos>=0
-            return Token(TOK_STRING,inp[pos+1:_endpos])
+            return _p.build_token( _p.TOK_STRING, inp[pos+1:_endpos])
         else:
             npos = match_symbol( inp, pos, end)
             if npos!=pos:
                 self.pos = npos
                 if npos!=end and inp[npos]==":":
                     self.pos += 1
-                    return Token(TOK_SYMDEF,inp[pos:npos])
+                    return _p.build_token( _p.TOK_SYMDEF, inp[pos:npos])
                 else:
-                    return Token(TOK_SYMBOL,inp[pos:npos])
-        
+                    return _p.build_token( _p.TOK_SYMBOL, inp[pos:npos])
+
         # we still have pos!=end here
         chr = inp[pos]
         if chr in "[]()*+|":
             self.pos = pos+1
-            return Token(tok_rmap[chr], chr)
+            return _p.build_token( _p.tok_values[chr], chr)
         self.RaiseError( "Unknown token" )
 
     def peek(self):

Modified: pypy/dist/pypy/interpreter/pyparser/ebnfparse.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/ebnfparse.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/ebnfparse.py	Mon Feb 26 15:06:33 2007
@@ -1,15 +1,31 @@
-#!/usr/bin/env python
-from grammar import BaseGrammarBuilder, Alternative, Sequence, Token, \
-     KleeneStar, GrammarElement, build_first_sets, EmptyToken
-from ebnflexer import GrammarSource
-import ebnfgrammar
-from ebnfgrammar import GRAMMAR_GRAMMAR, sym_map
-from syntaxtree import AbstractSyntaxVisitor
-import pytoken
-import pysymbol
+from grammar import Token, GrammarProxy
+from grammar import AbstractBuilder, AbstractContext
+
+
+ORDA = ord("A")
+ORDZ = ord("Z")
+ORDa = ord("a")
+ORDz = ord("z")
+ORD0 = ord("0")
+ORD9 = ord("9")
+ORD_ = ord("_")
+
+def is_py_name( name ):
+    if len(name)<1:
+        return False
+    v = ord(name[0])
+    if not (ORDA <= v <= ORDZ or
+            ORDa <= v <= ORDz or v == ORD_):
+        return False
+    for c in name:
+        v = ord(c)
+        if not (ORDA <= v <= ORDZ or
+                ORDa <= v <= ORDz or
+                ORD0 <= v <= ORD9 or
+                v == ORD_):
+            return False
+    return True
 
-import re
-py_name = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*", re.M)
 
 punct=['>=', '<>', '!=', '<', '>', '<=', '==', '\\*=',
        '//=', '%=', '^=', '<<=', '\\*\\*=', '\\', '=',
@@ -18,19 +34,14 @@
        '%', '<<', '//', '\\', '', '\n\\)', '\\(', ';', ':',
        '@', '\\[', '\\]', '`', '\\{', '\\}']
 
+TERMINALS = ['NAME', 'NUMBER', 'STRING', 'NEWLINE', 'ENDMARKER',
+             'INDENT', 'DEDENT' ]
 
-TERMINALS = [
-    'NAME', 'NUMBER', 'STRING', 'NEWLINE', 'ENDMARKER',
-    'INDENT', 'DEDENT' ]
-
-
-## Grammar Visitors ##################################################
-# FIXME: parsertools.py ? parser/__init__.py ?
 
 class NameToken(Token):
     """A token that is not a keyword"""
-    def __init__(self, keywords=None ):
-        Token.__init__(self, pytoken.NAME)
+    def __init__(self, parser, keywords=None):
+        Token.__init__(self, parser, parser.tokens['NAME'])
         self.keywords = keywords
 
     def match(self, source, builder, level=0):
@@ -47,224 +58,225 @@
         
         ctx = source.context()
         tk = source.next()
-        if tk.codename==self.codename:
-            if tk.value not in builder.keywords:
+        if tk.codename == self.codename:
+            # XXX (adim): this is trunk's keyword management
+            # if tk.value not in builder.keywords:
+            if tk.value not in self.keywords:
                 ret = builder.token( tk.codename, tk.value, source )
-                return self.debug_return( ret, tk.codename, tk.value )
+                return ret
         source.restore( ctx )
         return 0
-        
+
     def match_token(self, builder, other):
         """special case of match token for tokens which are really keywords
         """
         if not isinstance(other, Token):
-            raise RuntimeError("Unexpected token type %r" % other)
-        if other is EmptyToken:
+            raise RuntimeError("Unexpected token type")
+        if other is self.parser.EmptyToken:
             return False
         if other.codename != self.codename:
             return False
-        if other.value in builder.keywords:
+        # XXX (adim): this is trunk's keyword management
+        # if other.value in builder.keywords:
+        if other.value in self.keywords:
             return False
         return True
 
 
-
-def ebnf_handle_grammar(self, node):
-    for rule in node.nodes:
-        rule.visit(self)
-    # the rules are registered already
-    # we do a pass through the variables to detect
-    # terminal symbols from non terminals
-    for r in self.items:
-        for i,a in enumerate(r.args):
-            if a.codename in self.rules:
-                assert isinstance(a,Token)
-                r.args[i] = self.rules[a.codename]
-                if a.codename in self.terminals:
-                    del self.terminals[a.codename]
-    # XXX .keywords also contains punctuations
-    self.terminals['NAME'].keywords = self.keywords
-
-def ebnf_handle_rule(self, node):
-    symdef = node.nodes[0].value
-    self.current_rule = symdef
-    self.current_subrule = 0
-    alt = node.nodes[1]
-    rule = alt.visit(self)
-    if not isinstance(rule, Token):
-        rule.codename = self.symbols.add_symbol( symdef )
-    self.rules[rule.codename] = rule
-
-def ebnf_handle_alternative(self, node):
-    items = [node.nodes[0].visit(self)]
-    items += node.nodes[1].visit(self)        
-    if len(items) == 1 and not items[0].is_root():
-        return items[0]
-    alt = Alternative(self.new_symbol(), items)
-    return self.new_item(alt)
-
-def ebnf_handle_sequence( self, node ):
-    """ """
-    items = []
-    for n in node.nodes:
-        items.append( n.visit(self) )
-    if len(items)==1:
-        return items[0]
-    elif len(items)>1:
-        return self.new_item( Sequence( self.new_symbol(), items) )
-    raise RuntimeError("Found empty sequence")
-
-def ebnf_handle_sequence_cont( self, node ):
-    """Returns a list of sequences (possibly empty)"""
-    return [n.visit(self) for n in node.nodes]
-
-def ebnf_handle_seq_cont_list(self, node):
-    return node.nodes[1].visit(self)
-
-
-def ebnf_handle_symbol(self, node):
-    star_opt = node.nodes[1]
-    sym = node.nodes[0].value
-    terminal = self.terminals.get( sym, None )
-    if not terminal:
-        tokencode = pytoken.tok_values.get( sym, None )
-        if tokencode is None:
-            tokencode = self.symbols.add_symbol( sym )
-            terminal = Token( tokencode )
-        else:
-            terminal = Token( tokencode )
-            self.terminals[sym] = terminal
-
-    return self.repeat( star_opt, terminal )
-
-def ebnf_handle_option( self, node ):
-    rule = node.nodes[1].visit(self)
-    return self.new_item( KleeneStar( self.new_symbol(), 0, 1, rule ) )
-
-def ebnf_handle_group( self, node ):
-    rule = node.nodes[1].visit(self)
-    return self.repeat( node.nodes[3], rule )
-
-def ebnf_handle_TOK_STRING( self, node ):
-    value = node.value
-    tokencode = pytoken.tok_punct.get( value, None )
-    if tokencode is None:
-        if not py_name.match( value ):
-            raise RuntimeError("Unknown STRING value ('%s')" % value )
-        # assume a keyword
-        tok = Token( pytoken.NAME, value )
-        if value not in self.keywords:
-            self.keywords.append( value )
-    else:
-        # punctuation
-        tok = Token( tokencode )
-    return tok
-
-def ebnf_handle_sequence_alt( self, node ):
-    res = node.nodes[0].visit(self)
-    assert isinstance( res, GrammarElement )
-    return res
-
-# This will setup a mapping between
-# ebnf_handle_xxx functions and ebnfgrammar.xxx
-ebnf_handles = {}
-for name, value in globals().items():
-    if name.startswith("ebnf_handle_"):
-        name = name[12:]
-        key = getattr(ebnfgrammar, name )
-        ebnf_handles[key] = value
-
-def handle_unknown( self, node ):
-    raise RuntimeError("Unknown Visitor for %r" % node.name)
-    
-
-class EBNFVisitor(AbstractSyntaxVisitor):
-    
-    def __init__(self):
-        self.rules = {}
-        self.terminals = {}
-        self.current_rule = None
+class EBNFBuilderContext(AbstractContext):
+    def __init__(self, stackpos, seqcounts, altcounts):
+        self.stackpos = stackpos
+        self.seqcounts = seqcounts
+        self.altcounts = altcounts
+
+
+class EBNFBuilder(AbstractBuilder):
+    """Build a grammar tree"""
+    def __init__(self, gram_parser, dest_parser):
+        AbstractBuilder.__init__(self, dest_parser)
+        self.gram = gram_parser
+        self.rule_stack = []
+        self.seqcounts = [] # number of items in the current sequence
+        self.altcounts = [] # number of sequence in the current alternative
+        self.curaltcount = 0
+        self.curseqcount = 0
         self.current_subrule = 0
+        self.current_rule = -1
+        self.current_rule_name = ""
+        self.tokens = {}
         self.keywords = []
-        self.items = []
-        self.terminals['NAME'] = NameToken()
-        self.symbols = pysymbol.SymbolMapper( pysymbol._cpython_symbols.sym_name )
+        NAME = dest_parser.add_token('NAME')
+        # NAME = dest_parser.tokens['NAME']
+        self.tokens[NAME] = NameToken(dest_parser, keywords=self.keywords)
+
+    def context(self):
+        return EBNFBuilderContext(len(self.rule_stack), self.seqcounts, self.altcounts)
+
+    def restore(self, ctx):
+        del self.rule_stack[ctx.stackpos:]
+        self.seqcounts = ctx.seqcounts
+        self.altcounts = ctx.altcounts
 
     def new_symbol(self):
-        rule_name = ":%s_%s" % (self.current_rule, self.current_subrule)
+        """Allocate and return a new (anonymous) grammar symbol whose
+        name is based on the current grammar rule being parsed"""
+        rule_name = ":" + self.current_rule_name + "_%d" % self.current_subrule
         self.current_subrule += 1
-        symval = self.symbols.add_anon_symbol( rule_name )
-        return symval
+        name_id = self.parser.add_anon_symbol( rule_name )
+