/*
 * DO NOT EDIT THIS FILE!
 *
 * Parser generated by BisonGen on Wed Apr  6 15:55:07 2005.
 */

#include "Python.h"
#include "structmember.h"

#define PROJECT_NAME "Ft.Rdf.Parsers.Versa"
#define PARSER_NAME "VersaParser"

/* modules required for action routines */
static PyObject *ResourceExpressions;
static PyObject *BooleanExpressions;
static PyObject *Traversal;
static PyObject *Literals;
static PyObject *DataTypes;
static PyObject *NamedExpressions;
static PyObject *boolean;

/* token definitions */
#define QNAME 257
#define PURE_QNAME 258
#define ASTERISK 259
#define COMMA 260
#define SEMICOLON 261
#define DOT 262
#define DASH 263
#define FORWARD_ARROW 264
#define BACKWARD_ARROW 265
#define RIGHT_PAREN 266
#define LEFT_PAREN 267
#define LEFT_SQUARE 268
#define RIGHT_SQUARE 269
#define LEFT_CURLY 270
#define RIGHT_CURLY 271
#define STRING_LITERAL 272
#define NUMBER_LITERAL 273
#define TRUE 274
#define FALSE 275
#define AT 276
#define NOT 277
#define DOLLAR 278
#define PIPE 279

/* vector mapping lexer token numbers into internal token numbers */
static const int token_translations[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 
18, 19, 20, 21, 22, 23, 24, 25};

#define YYTRANSLATE(x) ((unsigned)(x) <= 279 ? token_translations[x] : 35)

/* vector of items of all rules. */
static const int rhs_tokens[] = {0, 33, 0, 33, 7, 0, 33, 9, 33, 10, 33, 0, 
33, 25, 9, 33, 10, 33, 0, 33, 11, 33, 9, 33, 0, 27, 0, 28, 0, 29, 0, 22, 
18, 0, 16, 18, 17, 0, 4, 0, 18, 0, 19, 0, 20, 0, 21, 0, 8, 0, 5, 0, 13, 
33, 12, 0, 32, 0, 31, 0, 3, 13, 34, 12, 0, 3, 13, 12, 0, 24, 3, 0, 30, 
0, 33, 0, 34, 6, 33, 0};

/* vector of line numbers and filename of all rules */
static const char* const rule_info[] = {
    ": line 0",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 48",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 51",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 67",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 84",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 111",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 133",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 136",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 139",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 147",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 159",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 172",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 181",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 203",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 225",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 236",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 253",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 262",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 292",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 304",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 307",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 310",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 322",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 333",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 343",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 351",
    "Ft/Rdf/Parsers/Versa/Versa.bgen: line 363",
};

/* vector of string-names indexed by token number */
static const char* const token_names[] = {
    "<EOF>",
    "error",
    "$undefined.",
    "QNAME",
    "PURE_QNAME",
    "ASTERISK",
    "COMMA",
    "SEMICOLON",
    "DOT",
    "DASH",
    "FORWARD_ARROW",
    "BACKWARD_ARROW",
    "RIGHT_PAREN",
    "LEFT_PAREN",
    "LEFT_SQUARE",
    "RIGHT_SQUARE",
    "LEFT_CURLY",
    "RIGHT_CURLY",
    "STRING_LITERAL",
    "NUMBER_LITERAL",
    "TRUE",
    "FALSE",
    "AT",
    "NOT",
    "DOLLAR",
    "PIPE",
    "Query",
    "ForwardTraversal",
    "ForwardFilter",
    "BackwardTraversal",
    "Traversal",
    "Literal",
    "Particle",
    "Expression",
    "ExpressionList",
    "0",
};

/* symbol number of symbol that rule derives. */
static const int derives[] = {0, 26, 26, 27, 28, 29, 30, 30, 30, 31, 31, 
31, 31, 31, 31, 31, 32, 32, 33, 33, 33, 33, 33, 33, 33, 34, 34};

/* number of symbols composing right hand side of rule. */
static const int rhs_size[] = {0, 1, 2, 5, 6, 5, 1, 1, 1, 2, 3, 1, 1, 1, 
1, 1, 1, 1, 3, 1, 1, 4, 3, 2, 1, 1, 3};

/* default rule to reduce with in state. 0 means the default is an error.
   indexed by state number */
static const int default_action[] = {0, 0, 11, 17, 16, 0, 0, 12, 13, 14, 
15, 0, 0, 6, 7, 8, 24, 20, 19, 1, 0, 0, 0, 9, 23, 2, 0, 0, 0, 22, 25, 0, 
18, 10, 0, 0, 0, 0, 21, 0, 0, 0, 26, 3, 5, 0, 4, 0, 0, 0};

/* default state to go to after a reduction of a rule.
   indexed by variable number (lhs token) */
static const int default_goto[] = {47, 13, 14, 15, 16, 17, 18, 19, 31};

/* index in yytable of the portion describing state (indexed by state number)
   If the value in yytable is positive, we shift the token and go to that state.
   If the value is negative, it is minus a rule number to reduce by.
   If the value is zero, the default action from yydefact[s] is used. */
static const int action_idx[] = {25, 3, -32768, -32768, -32768, 25, -12, 
-32768, -32768, -32768, -32768, -10, 14, -32768, -32768, -32768, -32768, 
-32768, -32768, -6, 47, -2, 7, -32768, -32768, -32768, 69, 69, 16, -32768, 
-7, 8, -32768, -32768, 2, 28, 69, 69, -32768, 69, 69, 70, 45, 45, 87, 69, 
53, 26, 36, -32768};

/* The index in yytable of the portion describing what to do after reducing a rule.
   The value from yytable is the state to go to. */
static const int goto_idx[] = {-32768, -32768, -32768, -32768, -32768, -32768, 
-32768, -5, -32768};

/* A vector filled with portions for different uses.
   (using action_idx and goto_idx) */
static const int yytable[] = {21, 25, 26, 26, 27, 27, 22, 26, 23, 27, 32, 
26, 39, 27, 37, 30, 20, 24, 28, 28, 38, 34, 35, 28, 33, 36, 48, 28, 1, 
2, 3, 41, 42, 4, 43, 44, 49, 40, 5, 27, 46, 6, 0, 7, 8, 9, 10, 11, 0, 12, 
1, 2, 3, 28, 26, 4, 27, 0, 0, 29, 5, 0, 26, 6, 27, 7, 8, 9, 10, 11, 28, 
12, 1, 2, 3, 0, 0, 4, 28, 26, 45, 27, 5, 0, 0, 6, 0, 7, 8, 9, 10, 11, 0, 
12, 0, 28, 26, 39, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28};

/* a vector indexed in parallel with yytable.
   It indicates the bounds of the portion you are trying to examine. */
static const int yycheck[] = {5, 7, 9, 9, 11, 11, 18, 9, 18, 11, 12, 9, 10, 
11, 6, 20, 13, 3, 25, 25, 12, 26, 27, 25, 17, 9, 0, 25, 3, 4, 5, 36, 37, 
8, 39, 40, 0, 9, 13, 11, 45, 16, -1, 18, 19, 20, 21, 22, -1, 24, 3, 4, 
5, 25, 9, 8, 11, -1, -1, 12, 13, -1, 9, 16, 11, 18, 19, 20, 21, 22, 25, 
24, 3, 4, 5, -1, -1, 8, 25, 9, 10, 11, 13, -1, -1, 16, -1, 18, 19, 20, 
21, 22, -1, 24, -1, 25, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, 25};

#define YYLAST 112
#define YYFINAL 49
#define YYFLAG -32768
#define YYNTBASE 26

#define LEXER_OP_FAILURE 0
#define LEXER_OP_SUCCESS 1
#define LEXER_OP_BOL 2
#define LEXER_OP_EOL 3
#define LEXER_OP_EOF 4
#define LEXER_OP_ANY 5
#define LEXER_OP_LITERAL 6
#define LEXER_OP_NOT_LITERAL 7
#define LEXER_OP_CHARSET 8
#define LEXER_OP_NOT_CHARSET 9
#define LEXER_OP_ASSERT 10
#define LEXER_OP_BRANCH 11
#define LEXER_OP_REPEAT 12
#define LEXER_OP_REPEAT_RANGE 13

#define LEXER_CHARSET_FAILURE 0
#define LEXER_CHARSET_LITERAL 1
#define LEXER_CHARSET_RANGE 2
#define LEXER_CHARSET_SMALL 3
#define LEXER_CHARSET_BIG 4

#define LEXER_INITIAL 1

static unsigned char lexer_charsets[7][32] = {
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x87,
    0xFE, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87,
    0xFE, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87,
    0xFE, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
    0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  { 0x00, 0x26, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
};

static unsigned char lexer_blockmaps[0][256] = {
};

static const Py_UCS4 lexer_INITIAL_pattern_0[] = { 6, 36, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_1[] = { 6, 45, 6, 62, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_2[] = { 6, 60, 6, 45, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_3[] = { 6, 45, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_4[] = { 6, 124, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_5[] = { 6, 40, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_6[] = { 6, 41, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_7[] = { 6, 91, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_8[] = { 6, 93, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_9[] = { 6, 123, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_10[] = { 6, 125, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_11[] = { 6, 42, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_12[] = { 6, 46, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_13[] = { 6, 64, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_14[] = { 6, 44, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_15[] = { 6, 59, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_16[] = { 8, 4, 3, 0, 0, 13, 
  18, 0, 1, 12, 8, 0, 8, 4, 3, 1, 0, 1, 8, 4, 3, 2, 0, 1, 6, 58, 8, 4, 
  3, 0, 0, 13, 18, 0, 1, 12, 8, 0, 8, 4, 3, 1, 0, 1, 8, 4, 3, 2, 0, 1, 
  1 };

static const Py_UCS4 lexer_INITIAL_pattern_17[] = { 13, 30, 0, 1, 8, 4, 
  3, 0, 0, 13, 18, 0, 1, 12, 8, 0, 8, 4, 3, 1, 0, 1, 8, 4, 3, 2, 0, 1, 
  6, 58, 1, 8, 4, 3, 0, 0, 13, 18, 0, 1, 12, 8, 0, 8, 4, 3, 1, 0, 1, 8, 
  4, 3, 2, 0, 1, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_18[] = { 11, 22, 6, 39, 12, 
  15, 0, 11, 6, 6, 92, 6, 39, 1, 4, 7, 39, 1, 0, 1, 6, 39, 1, 22, 6, 34, 
  12, 15, 0, 11, 6, 6, 92, 6, 34, 1, 4, 7, 34, 1, 0, 1, 6, 34, 1, 0, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_19[] = { 12, 8, 1, 8, 4, 3, 
  3, 0, 1, 13, 15, 0, 1, 6, 46, 12, 8, 1, 8, 4, 3, 3, 0, 1, 1, 13, 28, 
  0, 1, 8, 4, 3, 4, 0, 13, 9, 0, 1, 8, 4, 3, 5, 0, 1, 12, 8, 1, 8, 4, 3, 
  3, 0, 1, 1, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_20[] = { 6, 116, 6, 114, 6, 
  117, 6, 101, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_21[] = { 6, 102, 6, 97, 6, 108, 
  6, 115, 6, 101, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_22[] = { 12, 8, 1, 8, 4, 3, 
  6, 0, 1, 1 };

static const Py_UCS4 lexer_INITIAL_pattern_23[] = { 5, 1 };

static const Py_UCS4 *lexer_INITIAL_patterns[] = {
  lexer_INITIAL_pattern_0,
  lexer_INITIAL_pattern_1,
  lexer_INITIAL_pattern_2,
  lexer_INITIAL_pattern_3,
  lexer_INITIAL_pattern_4,
  lexer_INITIAL_pattern_5,
  lexer_INITIAL_pattern_6,
  lexer_INITIAL_pattern_7,
  lexer_INITIAL_pattern_8,
  lexer_INITIAL_pattern_9,
  lexer_INITIAL_pattern_10,
  lexer_INITIAL_pattern_11,
  lexer_INITIAL_pattern_12,
  lexer_INITIAL_pattern_13,
  lexer_INITIAL_pattern_14,
  lexer_INITIAL_pattern_15,
  lexer_INITIAL_pattern_16,
  lexer_INITIAL_pattern_17,
  lexer_INITIAL_pattern_18,
  lexer_INITIAL_pattern_19,
  lexer_INITIAL_pattern_20,
  lexer_INITIAL_pattern_21,
  lexer_INITIAL_pattern_22,
  lexer_INITIAL_pattern_23,
  NULL
};

static const Py_UCS4 **lexer_patterns[] = {
  NULL,
  lexer_INITIAL_patterns
};

static const int lexer_INITIAL_actions[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 
  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };

static const int *lexer_actions[] = {
  NULL,
  lexer_INITIAL_actions
};

#if PY_VERSION_HEX < 0x02020000 || !defined(Py_USING_UNICODE)
#error "Python 2.2+ with unicode support required"
#endif

/* Static Definitions */
#define YYEMPTY -2
#define YYERROR -1
#define YYEOF 0
#define YYINITDEPTH 1000
#define LEXER_INITIAL_BACKTRACKS 20

/* Parsing objects */
typedef struct {
  PyObject_HEAD
  int verbose;
  PyObject *dict;
} parserobject;

typedef struct {
  PyObject *text;
  int last;
  int state;
  Py_UNICODE *end;
  Py_UNICODE *position;

  /* backtracking stack */
  int backtracks;
  Py_UNICODE **positions;
  int allocated;
} lexerobject;

static int parser_yylex(parserobject *, lexerobject *, PyObject **);
static lexerobject *lexer_new(PyObject *);
static void lexer_free(lexerobject *);
static int lexer_save_position(lexerobject *);
static Py_UNICODE *lexer_restore_position(lexerobject *);
static int lexer_charset(parserobject *, Py_UCS4 *, Py_UCS4, int);
static int lexer_match(parserobject *, lexerobject *, Py_UCS4 *);
static void lexer_error(lexerobject *);

static char *unicode_escape(Py_UNICODE *, int);
static PyObject *report_error(int state, PyObject *lval, lexerobject *lexer);
static void print_reduce(int ruleno);
static void print_state_stack(int *stack, int *end);


/* Parser Methods */


#define TRACE(...) if (self->verbose) PySys_WriteStderr(__VA_ARGS__)

#ifdef LEXER_DEBUG
#define REGEX_TRACE(...) TRACE(__VA_ARGS__)
#else
#define REGEX_TRACE(...)
#endif

static char parser_parse_doc[] = "\
parse(string) -> object\n\
Converts the given string to a parse tree and return the top-most\n\
element of the tree.";

static PyObject* parser_parse(register parserobject *self, PyObject *args)
{
  PyObject *text;

  register int yystate;
  register int yyn;

  PyObject *yylval = NULL;
  PyObject *yyval = NULL;

  int state_stack[YYINITDEPTH];
  int *state_ptr;
  PyObject *value_stack[YYINITDEPTH];
  PyObject **value_ptr;

  int yylen;
  int yychar = YYEMPTY;         /* cause a token to be read */
  int yychar1 = 0;

  lexerobject *lexer;

  if (!PyArg_ParseTuple(args, "O:parse", &text))
    return NULL;

  lexer = lexer_new(text);
  if (lexer == NULL)
    return NULL;

  TRACE("Starting parse\n");

  /* Initialize stack pointers
     Waste one element of value and location stack
     so that they stay on the same level as the state stack.
     The wasted elements are never initialized. */
  state_ptr = state_stack - 1;
  value_ptr = value_stack;

  yystate = 0;

  while (1) {
    /* Push a new state, which is found in yystate. */
    /* In all cases, when you get here, the value and location stacks
       have just been pushed.  So pushing a state here evens the stacks. */
    *++state_ptr = yystate;

    TRACE("Entering state %d\n", yystate);

    /* Do appropriate processing given the current state. */
    /* Read a lookahead token if we need one and don't already have one. */

    /* First try to decide what to do without reference to lookahead token. */
    yyn = action_idx[yystate];
    if (yyn == YYFLAG) {
      yyn = default_action[yystate];
      if (yyn == 0) {
        return report_error(yystate, yylval, lexer);
      }

      /* Do a reduction. yyn is the number of a rule to reduce with. */
      if (self->verbose) print_reduce(yyn);

      yylen = rhs_size[yyn];
      state_ptr -= yylen;
      value_ptr -= yylen;
      if (yylen > 0) yyval = value_ptr[1];

      /* Action routines */
      switch (yyn) {
case 3: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 67
   * ForwardTraversal: Expression DASH Expression FORWARD_ARROW Expression
   */
  yyval = PyObject_CallMethod(Traversal, "ForwardTraversal", "OOO", value_ptr[1], value_ptr[3], value_ptr[5]);
  if (self->verbose) {
    fprintf(stderr, "--ForwardTraversal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[5], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  Py_DECREF(value_ptr[5]);
  break;
}
case 4: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 84
   * ForwardFilter: Expression PIPE DASH Expression FORWARD_ARROW Expression
   */
  yyval = PyObject_CallMethod(Traversal, "ForwardTraversal", "OOOi", value_ptr[1], value_ptr[4], value_ptr[6], 1);
  if (self->verbose) {
    fprintf(stderr, "--ForwardFilter(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[5], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[6], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  Py_DECREF(value_ptr[5]);
  Py_DECREF(value_ptr[6]);
  break;
}
case 5: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 111
   * BackwardTraversal: Expression BACKWARD_ARROW Expression DASH Expression
   */
  yyval = PyObject_CallMethod(Traversal, "BackwardTraversal", "OOO", value_ptr[1], value_ptr[3], value_ptr[5]);
  if (self->verbose) {
    fprintf(stderr, "--BackwardTraversal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[5], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  Py_DECREF(value_ptr[5]);
  break;
}
case 9: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 147
   * Literal: AT STRING_LITERAL
   */
  PyObject *str = PySequence_GetSlice(value_ptr[2], 1, PyString_GET_SIZE(value_ptr[2]) -1);
  yyval = PyObject_CallMethod(Literals, "ResourceLiteral", "O", str);
  Py_XDECREF(str);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  break;
}
case 10: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 159
   * Literal: LEFT_CURLY STRING_LITERAL RIGHT_CURLY
   */
  PyObject *str = PySequence_GetSlice(value_ptr[2], 1, PyString_GET_SIZE(value_ptr[2]) -1);
  yyval = PyObject_CallMethod(Literals, "ResourceLiteral", "O", str);
  Py_XDECREF(str);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
case 11: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 172
   * Literal: PURE_QNAME
   */
  yyval = PyObject_CallMethod(ResourceExpressions, "PureQNameExpression", "O", value_ptr[1]);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 12: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 181
   * Literal: STRING_LITERAL
   */
         PyObject *str = PySequence_GetSlice(value_ptr[1], 1, PyString_GET_SIZE(value_ptr[1]) - 1);
         yyval = PyObject_CallMethod(Literals, "StringLiteral", "O", str);
  Py_XDECREF(str);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 13: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 203
   * Literal: NUMBER_LITERAL
   */
  PyObject *num = PyNumber_Float(value_ptr[1]);
  yyval = PyObject_CallMethod(Literals, "NumberLiteral", "O", num);
  Py_XDECREF(num);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 14: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 225
   * Literal: TRUE
   */
  PyObject *t = PyObject_GetAttrString(boolean, "true");
  yyval = PyObject_CallMethod(Literals, "BooleanLiteral", "O", t);
  Py_XDECREF(t);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 15: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 236
   * Literal: FALSE
   */
  PyObject *t = PyObject_GetAttrString(boolean, "false");
  yyval = PyObject_CallMethod(Literals, "BooleanLiteral", "O", t);
  Py_XDECREF(t);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 16: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 253
   * Particle: DOT
   */
  yyval = PyObject_CallMethod(ResourceExpressions, "CurrentExpression", "");
  if (self->verbose) {
    fprintf(stderr, "--Particle(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 17: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 262
   * Particle: ASTERISK
   */
  PyObject *t = PyObject_GetAttrString(boolean, "true");
  yyval = PyObject_CallMethod(ResourceExpressions, "LiteralExpression", "O", t);
  Py_XDECREF(t);
  if (self->verbose) {
    fprintf(stderr, "--Particle(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 18: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 292
   * Expression: LEFT_PAREN Expression RIGHT_PAREN
   */
  yyval = value_ptr[2];
  Py_INCREF(value_ptr[2]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
case 21: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 310
   * Expression: QNAME LEFT_PAREN ExpressionList RIGHT_PAREN
   */
  yyval = PyObject_CallMethod(NamedExpressions, "FunctionCallExprConstructor", "OO", value_ptr[1], value_ptr[3]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  break;
}
case 22: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 322
   * Expression: QNAME LEFT_PAREN RIGHT_PAREN
   */
  yyval = PyObject_CallMethod(NamedExpressions, "FunctionCallExprConstructor", "O", value_ptr[1]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
case 23: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 333
   * Expression: DOLLAR QNAME
   */
  yyval = PyObject_CallMethod(NamedExpressions, "VariableReference", "O", value_ptr[2]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  break;
}
case 25: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 351
   * ExpressionList: Expression
   */
  yyval = PyList_New(1);
  /* Steals a reference */
  PyList_SET_ITEM(yyval, 0, value_ptr[1]);
  Py_INCREF(value_ptr[1]);
  if (self->verbose) {
    fprintf(stderr, "--ExpressionList(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 26: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 363
   * ExpressionList: ExpressionList COMMA Expression
   */
  PyList_Append(value_ptr[1], value_ptr[3]);
  Py_INCREF(value_ptr[1]);
  yyval = value_ptr[1];
  if (self->verbose) {
    fprintf(stderr, "--ExpressionList(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
      }
      if (!yyval) {
        lexer_free(lexer);
        return NULL;
      }
      *++value_ptr = yyval;

      if (self->verbose) print_state_stack(state_stack, state_ptr);


      /* Now "shift" the result of the reduction. */
      /* Determine what state that goes to, based on the state
         we popped back to and the rule number reduced by. */

      yyn = derives[yyn] - YYNTBASE;
      yystate = goto_idx[yyn] + *state_ptr;
      if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *state_ptr) {
        yystate = yytable[yystate];
      } else {
        yystate = default_goto[yyn];
      }
      continue;
    } /* if (yyn == YYFLAG) */

    /* Not known => get a lookahead token if don't already have one. */

    /* yychar is either YYEMPTY, YYEOF or a valid token in external form */
    if (yychar == YYEMPTY) {
      TRACE("Reading a token: ");
      yychar = parser_yylex(self, lexer, &yylval);
    }

    /* Convert token to internal form (in yychar1) for indexing tables with */

    if (yychar <= 0) {
      if (yychar == YYERROR) {
        lexer_free(lexer);
        return NULL;
      }
      /* This means end-of-input. */
      yychar1 = 0;
      TRACE("Now at end of input.\n");
    } else {
      yychar1 = YYTRANSLATE(yychar);
      TRACE("Next token is %d (%s)\n", yychar, token_names[yychar1]);
      yyn += yychar1;
    }
    if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) {
      /* comes here after end of input */
      yyn = default_action[yystate];
      if (yyn == 0) {
        return report_error(yystate, NULL, lexer);
      }

      /* Do a reduction. yyn is the number of a rule to reduce with. */
      if (self->verbose) print_reduce(yyn);

      yylen = rhs_size[yyn];
      state_ptr -= yylen;
      value_ptr -= yylen;
      if (yylen > 0) yyval = value_ptr[1];

      /* Action routines */
      switch (yyn) {
case 3: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 67
   * ForwardTraversal: Expression DASH Expression FORWARD_ARROW Expression
   */
  yyval = PyObject_CallMethod(Traversal, "ForwardTraversal", "OOO", value_ptr[1], value_ptr[3], value_ptr[5]);
  if (self->verbose) {
    fprintf(stderr, "--ForwardTraversal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[5], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  Py_DECREF(value_ptr[5]);
  break;
}
case 4: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 84
   * ForwardFilter: Expression PIPE DASH Expression FORWARD_ARROW Expression
   */
  yyval = PyObject_CallMethod(Traversal, "ForwardTraversal", "OOOi", value_ptr[1], value_ptr[4], value_ptr[6], 1);
  if (self->verbose) {
    fprintf(stderr, "--ForwardFilter(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[5], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[6], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  Py_DECREF(value_ptr[5]);
  Py_DECREF(value_ptr[6]);
  break;
}
case 5: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 111
   * BackwardTraversal: Expression BACKWARD_ARROW Expression DASH Expression
   */
  yyval = PyObject_CallMethod(Traversal, "BackwardTraversal", "OOO", value_ptr[1], value_ptr[3], value_ptr[5]);
  if (self->verbose) {
    fprintf(stderr, "--BackwardTraversal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[5], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  Py_DECREF(value_ptr[5]);
  break;
}
case 9: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 147
   * Literal: AT STRING_LITERAL
   */
  PyObject *str = PySequence_GetSlice(value_ptr[2], 1, PyString_GET_SIZE(value_ptr[2]) -1);
  yyval = PyObject_CallMethod(Literals, "ResourceLiteral", "O", str);
  Py_XDECREF(str);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  break;
}
case 10: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 159
   * Literal: LEFT_CURLY STRING_LITERAL RIGHT_CURLY
   */
  PyObject *str = PySequence_GetSlice(value_ptr[2], 1, PyString_GET_SIZE(value_ptr[2]) -1);
  yyval = PyObject_CallMethod(Literals, "ResourceLiteral", "O", str);
  Py_XDECREF(str);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
case 11: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 172
   * Literal: PURE_QNAME
   */
  yyval = PyObject_CallMethod(ResourceExpressions, "PureQNameExpression", "O", value_ptr[1]);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 12: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 181
   * Literal: STRING_LITERAL
   */
         PyObject *str = PySequence_GetSlice(value_ptr[1], 1, PyString_GET_SIZE(value_ptr[1]) - 1);
         yyval = PyObject_CallMethod(Literals, "StringLiteral", "O", str);
  Py_XDECREF(str);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 13: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 203
   * Literal: NUMBER_LITERAL
   */
  PyObject *num = PyNumber_Float(value_ptr[1]);
  yyval = PyObject_CallMethod(Literals, "NumberLiteral", "O", num);
  Py_XDECREF(num);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 14: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 225
   * Literal: TRUE
   */
  PyObject *t = PyObject_GetAttrString(boolean, "true");
  yyval = PyObject_CallMethod(Literals, "BooleanLiteral", "O", t);
  Py_XDECREF(t);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 15: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 236
   * Literal: FALSE
   */
  PyObject *t = PyObject_GetAttrString(boolean, "false");
  yyval = PyObject_CallMethod(Literals, "BooleanLiteral", "O", t);
  Py_XDECREF(t);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 16: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 253
   * Particle: DOT
   */
  yyval = PyObject_CallMethod(ResourceExpressions, "CurrentExpression", "");
  if (self->verbose) {
    fprintf(stderr, "--Particle(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 17: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 262
   * Particle: ASTERISK
   */
  PyObject *t = PyObject_GetAttrString(boolean, "true");
  yyval = PyObject_CallMethod(ResourceExpressions, "LiteralExpression", "O", t);
  Py_XDECREF(t);
  if (self->verbose) {
    fprintf(stderr, "--Particle(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 18: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 292
   * Expression: LEFT_PAREN Expression RIGHT_PAREN
   */
  yyval = value_ptr[2];
  Py_INCREF(value_ptr[2]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
case 21: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 310
   * Expression: QNAME LEFT_PAREN ExpressionList RIGHT_PAREN
   */
  yyval = PyObject_CallMethod(NamedExpressions, "FunctionCallExprConstructor", "OO", value_ptr[1], value_ptr[3]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  break;
}
case 22: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 322
   * Expression: QNAME LEFT_PAREN RIGHT_PAREN
   */
  yyval = PyObject_CallMethod(NamedExpressions, "FunctionCallExprConstructor", "O", value_ptr[1]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
case 23: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 333
   * Expression: DOLLAR QNAME
   */
  yyval = PyObject_CallMethod(NamedExpressions, "VariableReference", "O", value_ptr[2]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  break;
}
case 25: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 351
   * ExpressionList: Expression
   */
  yyval = PyList_New(1);
  /* Steals a reference */
  PyList_SET_ITEM(yyval, 0, value_ptr[1]);
  Py_INCREF(value_ptr[1]);
  if (self->verbose) {
    fprintf(stderr, "--ExpressionList(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 26: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 363
   * ExpressionList: ExpressionList COMMA Expression
   */
  PyList_Append(value_ptr[1], value_ptr[3]);
  Py_INCREF(value_ptr[1]);
  yyval = value_ptr[1];
  if (self->verbose) {
    fprintf(stderr, "--ExpressionList(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
      }
      if (!yyval) {
        lexer_free(lexer);
        return NULL;
      }
      *++value_ptr = yyval;

      if (self->verbose) print_state_stack(state_stack, state_ptr);

      /* Now "shift" the result of the reduction. */
      /* Determine what state that goes to, based on the state
         we popped back to and the rule number reduced by. */

      yyn = derives[yyn] - YYNTBASE;
      yystate = goto_idx[yyn] + *state_ptr;
      if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *state_ptr) {
        yystate = yytable[yystate];
      } else {
        yystate = default_goto[yyn];
      }
      continue;
    }

    yyn = yytable[yyn];

    /* yyn is what to do for this token type in this state.
       Negative => reduce, -yyn is rule number.
       Positive => shift, yyn is new state.
         New state is final state => don't bother to shift
         just return success.
       0, or max negative number => error. */

    if (yyn > YYFLAG && yyn < 0) {
      yyn = -yyn;

      /* Do a reduction. yyn is the number of a rule to reduce with. */
      if (self->verbose) print_reduce(yyn);

      yylen = rhs_size[yyn];
      state_ptr -= yylen;
      value_ptr -= yylen;
      if (yylen > 0) yyval = value_ptr[1];

      /* Action routines */
      switch (yyn) {
case 3: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 67
   * ForwardTraversal: Expression DASH Expression FORWARD_ARROW Expression
   */
  yyval = PyObject_CallMethod(Traversal, "ForwardTraversal", "OOO", value_ptr[1], value_ptr[3], value_ptr[5]);
  if (self->verbose) {
    fprintf(stderr, "--ForwardTraversal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[5], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  Py_DECREF(value_ptr[5]);
  break;
}
case 4: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 84
   * ForwardFilter: Expression PIPE DASH Expression FORWARD_ARROW Expression
   */
  yyval = PyObject_CallMethod(Traversal, "ForwardTraversal", "OOOi", value_ptr[1], value_ptr[4], value_ptr[6], 1);
  if (self->verbose) {
    fprintf(stderr, "--ForwardFilter(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[5], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[6], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  Py_DECREF(value_ptr[5]);
  Py_DECREF(value_ptr[6]);
  break;
}
case 5: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 111
   * BackwardTraversal: Expression BACKWARD_ARROW Expression DASH Expression
   */
  yyval = PyObject_CallMethod(Traversal, "BackwardTraversal", "OOO", value_ptr[1], value_ptr[3], value_ptr[5]);
  if (self->verbose) {
    fprintf(stderr, "--BackwardTraversal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[5], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  Py_DECREF(value_ptr[5]);
  break;
}
case 9: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 147
   * Literal: AT STRING_LITERAL
   */
  PyObject *str = PySequence_GetSlice(value_ptr[2], 1, PyString_GET_SIZE(value_ptr[2]) -1);
  yyval = PyObject_CallMethod(Literals, "ResourceLiteral", "O", str);
  Py_XDECREF(str);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  break;
}
case 10: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 159
   * Literal: LEFT_CURLY STRING_LITERAL RIGHT_CURLY
   */
  PyObject *str = PySequence_GetSlice(value_ptr[2], 1, PyString_GET_SIZE(value_ptr[2]) -1);
  yyval = PyObject_CallMethod(Literals, "ResourceLiteral", "O", str);
  Py_XDECREF(str);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
case 11: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 172
   * Literal: PURE_QNAME
   */
  yyval = PyObject_CallMethod(ResourceExpressions, "PureQNameExpression", "O", value_ptr[1]);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 12: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 181
   * Literal: STRING_LITERAL
   */
         PyObject *str = PySequence_GetSlice(value_ptr[1], 1, PyString_GET_SIZE(value_ptr[1]) - 1);
         yyval = PyObject_CallMethod(Literals, "StringLiteral", "O", str);
  Py_XDECREF(str);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 13: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 203
   * Literal: NUMBER_LITERAL
   */
  PyObject *num = PyNumber_Float(value_ptr[1]);
  yyval = PyObject_CallMethod(Literals, "NumberLiteral", "O", num);
  Py_XDECREF(num);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 14: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 225
   * Literal: TRUE
   */
  PyObject *t = PyObject_GetAttrString(boolean, "true");
  yyval = PyObject_CallMethod(Literals, "BooleanLiteral", "O", t);
  Py_XDECREF(t);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 15: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 236
   * Literal: FALSE
   */
  PyObject *t = PyObject_GetAttrString(boolean, "false");
  yyval = PyObject_CallMethod(Literals, "BooleanLiteral", "O", t);
  Py_XDECREF(t);
  if (self->verbose) {
    fprintf(stderr, "--Literal(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 16: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 253
   * Particle: DOT
   */
  yyval = PyObject_CallMethod(ResourceExpressions, "CurrentExpression", "");
  if (self->verbose) {
    fprintf(stderr, "--Particle(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 17: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 262
   * Particle: ASTERISK
   */
  PyObject *t = PyObject_GetAttrString(boolean, "true");
  yyval = PyObject_CallMethod(ResourceExpressions, "LiteralExpression", "O", t);
  Py_XDECREF(t);
  if (self->verbose) {
    fprintf(stderr, "--Particle(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 18: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 292
   * Expression: LEFT_PAREN Expression RIGHT_PAREN
   */
  yyval = value_ptr[2];
  Py_INCREF(value_ptr[2]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
case 21: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 310
   * Expression: QNAME LEFT_PAREN ExpressionList RIGHT_PAREN
   */
  yyval = PyObject_CallMethod(NamedExpressions, "FunctionCallExprConstructor", "OO", value_ptr[1], value_ptr[3]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[4], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  Py_DECREF(value_ptr[4]);
  break;
}
case 22: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 322
   * Expression: QNAME LEFT_PAREN RIGHT_PAREN
   */
  yyval = PyObject_CallMethod(NamedExpressions, "FunctionCallExprConstructor", "O", value_ptr[1]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
case 23: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 333
   * Expression: DOLLAR QNAME
   */
  yyval = PyObject_CallMethod(NamedExpressions, "VariableReference", "O", value_ptr[2]);
  if (self->verbose) {
    fprintf(stderr, "--Expression(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  break;
}
case 25: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 351
   * ExpressionList: Expression
   */
  yyval = PyList_New(1);
  /* Steals a reference */
  PyList_SET_ITEM(yyval, 0, value_ptr[1]);
  Py_INCREF(value_ptr[1]);
  if (self->verbose) {
    fprintf(stderr, "--ExpressionList(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  break;
}
case 26: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 363
   * ExpressionList: ExpressionList COMMA Expression
   */
  PyList_Append(value_ptr[1], value_ptr[3]);
  Py_INCREF(value_ptr[1]);
  yyval = value_ptr[1];
  if (self->verbose) {
    fprintf(stderr, "--ExpressionList(");
    PyObject_Print(value_ptr[1], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[2], stderr, Py_PRINT_RAW);
    fprintf(stderr, ", ");
    PyObject_Print(value_ptr[3], stderr, Py_PRINT_RAW);
    fprintf(stderr, ")\n");
  }
  Py_DECREF(value_ptr[1]);
  Py_DECREF(value_ptr[2]);
  Py_DECREF(value_ptr[3]);
  break;
}
      }
      if (!yyval) {
        lexer_free(lexer);
        return NULL;
      }
      *++value_ptr = yyval;

      if (self->verbose) print_state_stack(state_stack, state_ptr);

      /* Now "shift" the result of the reduction. */
      /* Determine what state that goes to, based on the state
         we popped back to and the rule number reduced by. */

      yyn = derives[yyn] - YYNTBASE;
      yystate = goto_idx[yyn] + *state_ptr;
      if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *state_ptr) {
        yystate = yytable[yystate];
      } else {
        yystate = default_goto[yyn];
      }
      continue;
    } else if (yyn == YYFINAL) {
      /* Hooray!  Process complete. */
      lexer_free(lexer);
      return value_ptr[-1];
    } else if (yyn <= 0) {
      /* Now it is either 0 or YYFLAG */
      return report_error(yystate, yylval, lexer);
    }

    /* Shift the lookahead token. */

    TRACE("Shifting token %d (%s), ", yychar, token_names[yychar1]);

    if (yychar != YYEOF) {
      yychar = YYEMPTY;
    }

    *++value_ptr = yylval;

    yystate = yyn;
    continue;
  }

  /* should never get here */
  Py_INCREF(Py_None);
  lexer_free(lexer);
  return Py_None;
}

/** lexer routines ****************************************************/

static lexerobject *lexer_new(PyObject *text)
{
  lexerobject *lexer;

  lexer = PyMem_New(lexerobject, 1);
  if (lexer == NULL) {
    PyErr_NoMemory();
    return NULL;
  }

  /* attempt to coerce given object to unicode using default rules */
  lexer->text = PyUnicode_FromObject(text);
  if (lexer->text == NULL) {
    PyMem_Free(lexer);
    return NULL;
  }
  lexer->position = PyUnicode_AS_UNICODE(lexer->text);
  lexer->end = lexer->position + PyUnicode_GET_SIZE(lexer->text);
  lexer->state = LEXER_INITIAL;

  /* create initial backtracking stack */
  lexer->positions = PyMem_New(Py_UNICODE *, LEXER_INITIAL_BACKTRACKS);
  if (lexer->positions == NULL) {
    PyErr_NoMemory();
    Py_DECREF(lexer->text);
    PyMem_Free(lexer);
    return NULL;
  }
  lexer->allocated = LEXER_INITIAL_BACKTRACKS;
  lexer->backtracks = 0;
  return lexer;
}

static void lexer_free(lexerobject *lexer)
{
  PyMem_Free(lexer->positions);
  Py_DECREF(lexer->text);
  PyMem_Free(lexer);
}

static int lexer_save_position(lexerobject *lexer) {
  Py_UNICODE **positions;
  size_t new_allocated;
  int allocated, newsize;

  /* Bypass realloc() when a previous overallocation is large enough
     to accommodate the newsize.
  */
  newsize = lexer->backtracks + 1;
  allocated = lexer->allocated;
  positions = lexer->positions;
  if (newsize >= allocated) {
    /* This over-allocates proportional to the list size, making room
     * for additional growth.  The over-allocation is mild, but is
     * enough to give linear-time amortized behavior over a long
     * sequence of appends() in the presence of a poorly-performing
     * system realloc().
     * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
     */
    new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
    if (PyMem_Resize(positions, Py_UNICODE *, new_allocated) == NULL) {
      PyErr_NoMemory();
      return -1;
    }
    lexer->allocated = new_allocated;
    lexer->positions = positions;
  }
  lexer->positions[lexer->backtracks] = lexer->position;
  lexer->backtracks = newsize;
  return 0;
}

static Py_UNICODE *lexer_restore_position(lexerobject *lexer) {
  assert(lexer->backtracks > 0);
  lexer->position = lexer->positions[--lexer->backtracks];
  return lexer->position;
}

static int lexer_charset(parserobject *self, Py_UCS4 *set, Py_UCS4 ch,
			 int ok)
{
  unsigned char *charset;

  /* check if character is a member of the given set */
  /* Note, the tests are stored sorted to allow for quick exits */

  for (;;) {
    switch (*set++) {

    case LEXER_CHARSET_LITERAL:
      /* <LITERAL> <code> */
      REGEX_TRACE("CHARSET_LITERAL, %d == %d\n", ch, set[0]);
      if (ch < set[0])
        return !ok;
      else if ((Py_UCS4)ch == set[0])
        return ok;
      set++;
      break;

    case LEXER_CHARSET_RANGE:
      /* <RANGE> <lower> <upper> */
      REGEX_TRACE("CHARSET_RANGE, %d <= %d <= %d\n", set[0], ch, set[1]);
      if (ch < set[0])
        return !ok;
      else if (ch <= set[1])
        return ok;
      set += 2;
      break;

    case LEXER_CHARSET_SMALL:
      /* <SMALL> <charset index> */
      REGEX_TRACE("CHARSET_SMALL, index=%d\n", set[0]);
      charset = lexer_charsets[*set++];
      if (ch < 256 && (charset[ch >> 3] & (1 << (ch & 7))))
        return ok;
      break;

    case LEXER_CHARSET_BIG:
      /* <BIG> <blockmap index> */
      REGEX_TRACE("CHARSET_BIG, index=%d\n", set[0]);
      charset = lexer_charsets[lexer_blockmaps[*set++][ch >> 8]];
      if (ch < 65536 && charset[(ch & 255) >> 3] & (1 << (ch & 7)))
        return ok;
      break;

    case LEXER_CHARSET_FAILURE:
      /* nothing matched in charset */
      REGEX_TRACE("CHARSET_FAILURE\n");
      return !ok;

    default:
      REGEX_TRACE("**INTERNAL CHARSET ERROR**\n");
      return -1;
    }
  }
}

/* return values:
   1 -> sucessful match,
   0 -> no match,
   -1 -> error,
*/

#ifdef Py_UNICODE_WIDE
#define GET_CHAR_AND_ADVANCE() ch = *ptr++;
#else
#define GET_CHAR_AND_ADVANCE()                                          \
  if ((0xD800 <= ptr[0] && ptr[0] <= 0xDBFF) &&                         \
      (0xDC00 <= ptr[1] && ptr[1] <= 0xDFFF)) {                         \
    ch = (((ptr[0] & 0x03FF) << 10) | (ptr[1] & 0x03FF)) + 0x00010000;  \
    ptr += 2;                                                           \
  } else {                                                              \
    ch = *ptr++;                                                        \
  }
#endif  
    
static int lexer_match(parserobject *self, lexerobject *lexer, 
		       Py_UCS4 *pattern)
{
  Py_UNICODE *ptr = lexer->position;
  Py_UNICODE *end;
  Py_UCS4 ch;
  int i, count;

  REGEX_TRACE("LEXER_MATCH, position %d\n",
              lexer->position - PyUnicode_AS_UNICODE(lexer->text));

  while (1) {
    switch (*pattern++) {

    case LEXER_OP_FAILURE:
      /* immediate failure */
      REGEX_TRACE("OP_FAILURE\n");
      return 0;

    case LEXER_OP_SUCCESS:
      /* end of pattern */
      REGEX_TRACE("OP_SUCCESS\n");
      lexer->position = ptr;
      return 1;
        
    case LEXER_OP_BOL:
      /* beginning of line */
      /* <BOL> */
      REGEX_TRACE("OP_BOL\n");
      if (ptr == PyUnicode_AS_UNICODE(lexer->text) || ptr[-1] == '\n') 
        break;
      return 0;

    case LEXER_OP_EOL:
      /* end of line */
      /* <EOL> */
      REGEX_TRACE("OP_EOL\n");
      if (ptr >= lexer->end || ptr[0] == '\n') break;
      return 0;
            
    case LEXER_OP_EOF:
      /* end of file */
      /* <EOF> */
      REGEX_TRACE("OP_EOF\n");
      if (ptr >= lexer->end) break;
      return 0;

    case LEXER_OP_ANY:
      /* match anything (except a newline) */
      /* <ANY> */
      REGEX_TRACE("OP_ANY\n");
      if (ptr >= lexer->end || ptr[0] == '\n')
        return 0;
      ptr++;
      break;

    case LEXER_OP_LITERAL:
      /* match literal character */
      /* <LITERAL> <code> */
      if (ptr >= lexer->end)
        return 0;
      GET_CHAR_AND_ADVANCE();
      REGEX_TRACE("OP_LITERAL, %d == %d\n", ch, pattern[0]);
      if (ch != pattern[0])
        return 0;
      pattern++;
      break;

    case LEXER_OP_NOT_LITERAL:
      /* match anything that is not literal character */
      /* <NOT_LITERAL> <code> */
      if (ptr >= lexer->end)
        return 0;
      GET_CHAR_AND_ADVANCE();
      REGEX_TRACE("OP_NOT_LITERAL, %d != %d\n", ch, pattern[0]);
      if (ch == pattern[0])
        return 0;
      pattern++;
      break;

    case LEXER_OP_CHARSET:
      /* match set member */
      /* <CHARSET> <skip> <set> */
      if (ptr >= lexer->end)
        return 0;
      GET_CHAR_AND_ADVANCE();
      REGEX_TRACE("OP_CHARSET, skip %d\n", pattern[0]);
      i = lexer_charset(self, pattern + 1, ch, 1);
      if (i <= 0)
        return i;

      pattern += pattern[0];
      break;
            
    case LEXER_OP_NOT_CHARSET:
      /* match set non-member */
      /* <NOT_CHARSET> <skip> <set> */
      if (ptr >= lexer->end)
        return 0;
      GET_CHAR_AND_ADVANCE();
      REGEX_TRACE("OP_NOT_CHARSET, skip %d\n", pattern[0]);
      i = lexer_charset(self, pattern + 1, ch, 0);
      if (i <= 0)
        return i;

      pattern += pattern[0];
      break;
            
    case LEXER_OP_ASSERT:
      /* lookahead assertion */
      /* <ASSERT> <skip> <pattern> */
      REGEX_TRACE("OP_ASSERT, skip %d\n", pattern[0]);
      lexer->position = ptr;
      i = lexer_match(self, lexer, pattern + 1);
      if (i <= 0)
        return i;

      pattern += pattern[0];
      break;

    case LEXER_OP_BRANCH:
      /* alternation */
      /* <BRANCH> <skip0> <code0> <skip1> <code1> ... <NULL> */

      end = NULL;
      count = 0;
      while (pattern[0]) {
        /* reset start position each time through */
	REGEX_TRACE("OP_BRANCH %d, skip %d\n", count++, pattern[0]);
        lexer->position = ptr;
        
        i = lexer_match(self, lexer, pattern + 1);
        if (i < 0)
          return i;
        else if (i && lexer->position > end) 
          /* successful match which is longer than the current best matched */
          end = lexer->position;
        
        /* advance to the next pattern */
        pattern += pattern[0];
      }

      /* advance pattern past NULL */
      pattern++;

      /* advance to the best matching position if there was a match */
      if (end) {
        lexer->position = ptr = end;
        break;
      }

      return 0;

    case LEXER_OP_REPEAT:
      /* repetition */
      /* <REPEAT> <skip> <1=min> item */
      {
        Py_UCS4 *item = pattern + 2;
        Py_UCS4 *next = pattern + pattern[0];
        int minimum = pattern[1];
        int backtracks;

        lexer->position = ptr;
        for (count = 0, i = 1; i == 1 && count < minimum; count++) {
          REGEX_TRACE("OP_REPEAT<stage 1>, min %d, now %d\n",
                      minimum, count);
          i = lexer_match(self, lexer, item);
        }
        
        /* either internal error or failed minimum matches */
        if (i <= 0) 
          return i;

        backtracks = lexer->backtracks;

        /* match as many items as possible */
        for (; i == 1; count++) {
          REGEX_TRACE("OP_REPEAT<stage 2>, now %d\n", count);
          if (lexer_save_position(lexer) < 0)
            return -1;
          i = lexer_match(self, lexer, item);
        }
          
        if (i < 0) {
          /* internal error */
          lexer->backtracks = backtracks;
          return i;
        }
          
        /* backtracking assert of tail match until success */
        do {
          REGEX_TRACE("OP_REPEAT<stage 3>, now %d\n", count);
          /* update position to previous successful match */
          ptr = lexer_restore_position(lexer);
          if (ptr == NULL)
            return -1;
          i = lexer_match(self, lexer, next);
        } while (i == 0 && --count > minimum);

        /* discard remaining backtrack positions */
        lexer->backtracks = backtracks;

        if (i <= 0) {
          return i;
        }
        pattern = next;
      }
      break;

    case LEXER_OP_REPEAT_RANGE:
      /* repetition */
      /* <REPEAT_RANGE> <skip> <1=min> <2=max> item */
      {
        Py_UCS4 *item = pattern + 3;
        Py_UCS4 *next = pattern + pattern[0];
        int minimum = pattern[1];
        int maximum = pattern[2];
        int backtracks;

        lexer->position = ptr;
        for (count = 0, i = 1; i == 1 && count < minimum; count++) {
          REGEX_TRACE("OP_REPEAT_RANGE<stage 1>, min %d, now %d\n",
                      minimum, count);
          i = lexer_match(self, lexer, item);
        }
        
        /* either internal error or failed minimum matches */
        if (i <= 0) 
          return i;

        backtracks = lexer->backtracks;

        /* consume up to 'maximum' matches */
        for (; i == 1 && count < maximum; count++) {
          REGEX_TRACE("OP_REPEAT_RANGE<stage 2>, max %d, now %d\n",
                      maximum, count);
          if (lexer_save_position(lexer) < 0)
            return -1;
          i = lexer_match(self, lexer, item);
        }

        if (i < 0) {
          /* internal error */
          lexer->backtracks = backtracks;
          return i;
        }

        /* maximum matches reached, update saved position */
        if (i == 1)
          ptr = lexer->position;

        /* backtracking assert of tail match until success */
        do {
          REGEX_TRACE("OP_REPEAT_RANGE<stage 3>, now %d\n", count);
          if (i == 0) {
            /* update position to last successful match */
            ptr = lexer_restore_position(lexer);
            if (ptr == NULL)
              return -1;
          }
          i = lexer_match(self, lexer, next);
        } while (i == 0 && --count > minimum);

        /* discard remaining backtrack positions */
        lexer->backtracks = backtracks;

        if (i <= 0)
          return i;

        pattern = next;
      }
      break;

    default:
      REGEX_TRACE("**INTERNAL MATCH ERROR**\n");
      return -1;
    }
  }
}
static int parser_yylex(parserobject *self, lexerobject *lexer, PyObject **yylval)
{
  int yychar = YYEMPTY;
  int yylen;
  Py_UNICODE *yytext = lexer->position;
  
  while (yytext < lexer->end && yychar == YYEMPTY) {
    Py_UNICODE *best_end = NULL;
    int yyaccept = 0;
    int i;
    Py_UCS4 **patterns = (Py_UCS4 **)lexer_patterns[lexer->state];
    const int *actions = lexer_actions[lexer->state];

    REGEX_TRACE("Using patterns from lexer state %d\n", lexer->state);
    for (i = 0; patterns[i]; i++) {
      int matched;
      /* reset position each time through */
      lexer->position = yytext;

      REGEX_TRACE("--- pattern %d...\n", i);
      matched = lexer_match(self, lexer, patterns[i]);
      
      if (matched > 0 && lexer->position > best_end) {
        /* successful match which is longer than the current best matched */
        best_end = lexer->position;
        yyaccept = i;
      } else if (matched < 0) {
        /* internal error */
	REGEX_TRACE("--- pattern %d internal error\n", i);
        PyErr_SetString(PyExc_RuntimeError,
                        "internal error in regular expression engine");
        return -1;
      }
      REGEX_TRACE("--- pattern %d %s\n", i, matched ? "success" : "failed");
    }
      
    if (best_end == NULL) {
      /* no matches */
      lexer->position = yytext;
      lexer_error(lexer);
      return -1;
    }

    lexer->position = best_end;
    yylen = best_end - yytext;

    /* get the action block for this match */
    switch (actions[yyaccept]) {
case 0: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 399 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[399], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = DOLLAR;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 1: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 402 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[402], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = FORWARD_ARROW;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 2: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 405 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[405], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = BACKWARD_ARROW;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 3: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 408 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[408], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = DASH;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 4: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 411 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[411], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = PIPE;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 5: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 414 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[414], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = LEFT_PAREN;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 6: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 417 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[417], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = RIGHT_PAREN;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 7: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 420 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[420], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = LEFT_SQUARE;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 8: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 423 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[423], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = RIGHT_SQUARE;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 9: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 426 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[426], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = LEFT_CURLY;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 10: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 429 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[429], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = RIGHT_CURLY;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 11: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 433 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[433], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = ASTERISK;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 12: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 437 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[437], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = DOT;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 13: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 441 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[441], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = AT;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 14: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 445 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[445], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = COMMA;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 15: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 449 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[449], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = SEMICOLON;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 16: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 453 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[453], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = PURE_QNAME;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 17: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 457 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[457], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = QNAME;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 18: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 461 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[461], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = STRING_LITERAL;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 19: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 465 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[465], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = NUMBER_LITERAL;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 20: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 469 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[469], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = TRUE;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 21: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 473 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[473], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = FALSE;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
case 22: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 478 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[478], ");
  /* skip over the matched text */
  yytext = lexer->position;
  break;
}
case 23: {
  /* from Ft/Rdf/Parsers/Versa/Versa.bgen, line 480 */
  TRACE("using rule from Ft/Rdf/Parsers/Versa/Versa.bgen[480], ");
  /* create the Python object for the matched text */
  *yylval = PyUnicode_FromUnicode(yytext, yylen);
  if (*yylval == NULL) {
    PyErr_NoMemory();
    return -1;
  }

  yychar = (int)*yytext;

  if (self->verbose) {
    char *repr = unicode_escape(yytext, yylen);
    TRACE("accepting '%s' (%d)\n", repr, yychar);
    PyMem_Del(repr);
  }

  /* update the saved position */
  yytext = lexer->position;
  break;
}
    }
  }

  if (yychar == YYEMPTY) {
    /* Reached end of input */
    yychar = YYEOF;
  }

  return yychar;
}

/** Type Object *******************************************************/

static int parser_traverse(parserobject *self, visitproc visit, void *arg)
{
  int rv;

  if (self->dict) {
    rv = visit(self->dict, arg);
    if (rv != 0) return rv;
  }
  return 0;
}

static int parser_clear(parserobject *self)
{
  PyObject *tmp;

  if (self->dict) {
    tmp = self->dict;
    self->dict = NULL;
    Py_DECREF(tmp);
  }
  return 0;
}

static void parser_dealloc(parserobject *self)
{
  parser_clear(self);
  self->ob_type->tp_free((PyObject *) self);
}

static int parser_init(parserobject *self, PyObject *args, PyObject *kwds)
{
  PyObject *debug=NULL;
  static char *kwlist[] = { "debug", NULL };

  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:" PARSER_NAME, kwlist,
                                   &debug))
    return -1;

  if (debug) {
    self->verbose = PyObject_IsTrue(debug);
  }

  return 0;
}

static PyObject *parser_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
  parserobject *self;

  self = (parserobject *) type->tp_alloc(type, 0);
  if (self != NULL) {
    self->dict = PyDict_New();
    if (self->dict == NULL) {
      Py_DECREF(self);
      return NULL;
    }
    self->verbose = 0;
  }
  return (PyObject *) self;
}

static PyMethodDef parser_methods[] = {
  { "parse", (PyCFunction) parser_parse, METH_VARARGS, parser_parse_doc },
  { NULL, NULL }
};

static PyMemberDef parser_members[] = {
  { "debug", T_INT, offsetof(parserobject, verbose) },
  { NULL }
};

static char parser_doc[] = PARSER_NAME "\
([debug]) -> parser\n\
Create a new parser object.\n\
\n\
The optional debug argument, when true, enables the builtin trace facility.\n\
The trace facility uses stderr to display each step taken by the parser.";

static PyTypeObject Parser_Type = {
  /* PyObject_HEAD     */ PyObject_HEAD_INIT(NULL)
  /* ob_size           */ 0,
  /* tp_name           */ PROJECT_NAME "." PARSER_NAME,
  /* tp_basicsize      */ sizeof(parserobject),
  /* tp_itemsize       */ 0,
  /* tp_dealloc        */ (destructor) parser_dealloc,
  /* tp_print          */ (printfunc) 0,
  /* tp_getattr        */ (getattrfunc) 0,
  /* tp_setattr        */ (setattrfunc) 0,
  /* tp_compare        */ (cmpfunc) 0,
  /* tp_repr           */ (reprfunc) 0,
  /* tp_as_number      */ (PyNumberMethods *) 0,
  /* tp_as_sequence    */ (PySequenceMethods *) 0,
  /* tp_as_mapping     */ (PyMappingMethods *) 0,
  /* tp_hash           */ (hashfunc) 0,
  /* tp_call           */ (ternaryfunc) 0,
  /* tp_str            */ (reprfunc) 0,
  /* tp_getattro       */ (getattrofunc) 0,
  /* tp_setattro       */ (setattrofunc) 0,
  /* tp_as_buffer      */ (PyBufferProcs *) 0,
  /* tp_flags          */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
  /* tp_doc            */ (char *) parser_doc,
  /* tp_traverse       */ (traverseproc) parser_traverse,
  /* tp_clear          */ (inquiry) parser_clear,
  /* tp_richcompare    */ (richcmpfunc) 0,
  /* tp_weaklistoffset */ 0,
  /* tp_iter           */ (getiterfunc) 0,
  /* tp_iternext       */ (iternextfunc) 0,
  /* tp_methods        */ (PyMethodDef *) parser_methods,
  /* tp_members        */ (PyMemberDef *) parser_members,
  /* tp_getset         */ (PyGetSetDef *) 0,
  /* tp_base           */ (PyTypeObject *) 0,
  /* tp_dict           */ (PyObject *) 0,
  /* tp_descr_get      */ (descrgetfunc) 0,
  /* tp_descr_set      */ (descrsetfunc) 0,
  /* tp_dictoffset     */ offsetof(parserobject, dict),
  /* tp_init           */ (initproc) parser_init,
  /* tp_alloc          */ (allocfunc) 0,
  /* tp_new            */ (newfunc) parser_new,
  /* tp_free           */ 0,
};

/* Helper functions */

/* caller is responsible for releasing the memory */
static char *unicode_escape(Py_UNICODE *s, int len)
{
  static const char *hexdigit = "0123456789ABCDEF";
  char *repr, *p;
  int i, size;

  /* Do one pass to get the repr'ed size */
  size = 1;  /* zero terminator */
  for (i = 0; i < len; i++) {
#ifdef Py_UNICODE_WIDE
    if (s[i] >= 65536) size += 10;  /* \UHHHHHHHH */
    else
#endif
    if (s[i] >= 256) size += 6;  /* \uHHHH */
    else if (s[i] == 9 || s[i] == 10 || s[i] == 13) size += 2;  /* \t \n \r */
    else if (s[i] < 32 || s[i] >= 128) size += 4;  /* \xHH */
    else size++; /* printable US-ASCII */
  }
  
  repr = p = PyMem_New(char, size + 1);
  if (repr == NULL) return NULL;

  while (len-- > 0) {
    Py_UNICODE ch = *s++;
#ifdef Py_UNICODE_WIDE
    /* Map 32-bit characters to '\Uxxxxxxxx' */
    if (ch >= 65536) {
      *p++ = '\\';
      *p++ = 'U';
      *p++ = hexdigit[(ch >> 28) & 0xf];
      *p++ = hexdigit[(ch >> 24) & 0xf];
      *p++ = hexdigit[(ch >> 20) & 0xf];
      *p++ = hexdigit[(ch >> 16) & 0xf];
      *p++ = hexdigit[(ch >> 12) & 0xf];
      *p++ = hexdigit[(ch >> 8) & 0xf];
      *p++ = hexdigit[(ch >> 4) & 0xf];
      *p++ = hexdigit[ch & 15];
    }
    /* Map 16-bit characters to '\uxxxx' */
    else 
#endif
    if (ch >= 256) {
      *p++ = '\\';
      *p++ = 'u';
      *p++ = hexdigit[(ch >> 12) & 0xf];
      *p++ = hexdigit[(ch >> 8) & 0xf];
      *p++ = hexdigit[(ch >> 4) & 0xf];
      *p++ = hexdigit[ch & 15];
    }
    /* Map special whitespace to '\t', \n', '\r' */
    else if (ch == 9) {
      *p++ = '\\';
      *p++ = 't';
    }
    else if (ch == 10) {
      *p++ = '\\';
      *p++ = 'n';
    }
    else if (ch == 13) {
      *p++ = '\\';
      *p++ = 'r';
    }
    /* Map non-printable US ASCII to '\xhh' */
    else if (ch < 32 || ch >= 128) {
      *p++ = '\\';
      *p++ = 'x';
      *p++ = hexdigit[(ch >> 4) & 0xf];
      *p++ = hexdigit[ch & 15];
    }
    /* Copy everything else as-is */
    else
      *p++ = (char) ch;
  }

  *p = '\0';

  return repr;
}

static void calculate_position(lexerobject *lexer, int *line, int *column) {
  /* Determine line and column numbers */
  Py_UNICODE *p;

  *line = 1;
  *column = 1;

  for (p = PyUnicode_AS_UNICODE(lexer->text); p < lexer->end; p++) {
    if ((char)*p == '\n') {
      *line += 1;
      *column = 1;
    } else {
      *column += 1;
    }
  }
}

static const char error_format_str[] = "parse error at line %d, column %d: matched '%s'";
static const char error_format_eof_str[] = "parse error at line %d, column %d: reached end-of-input";

static PyObject *report_error(int state, PyObject* lval, lexerobject *lexer) {
  int line, column;
  int ruleno = action_idx[state];
  char *matched = NULL;

  if (lval) {
    matched = unicode_escape(PyUnicode_AS_UNICODE(lval), 
                             PyUnicode_GET_SIZE(lval));
    if (matched == NULL) return NULL;
  }

  calculate_position(lexer, &line, &column);
  Py_DECREF(lexer->text);

  if (ruleno > YYFLAG && ruleno < YYLAST) {
    /* There are expected tokens */
    int x, count;
    int size = 60;  /* Initial format string */
    char *msg;

    /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
    for (x = (ruleno < 0 ? -ruleno : 0);
         x < (sizeof(token_names) / sizeof(char *)); x++) {
      if (yycheck[x + ruleno] == x) {
        size += strlen(token_names[x]) + 15;
      }
    }

    msg = PyMem_New(char, size);
    if (msg == NULL) {
      PyMem_Del(matched);
      return NULL;
    }

    if (lval) {
      strcpy(msg, error_format_str);
    } else {
      strcpy(msg, error_format_eof_str);
    }

    count = 0;
    for (x = (ruleno < 0 ? -ruleno : 0);
         x < (sizeof(token_names) / sizeof(char *)); x++) {
      if (yycheck[x + ruleno] == x) {
        strcat(msg, count == 0 ? ", expecting '" : " or '");
        strcat(msg, token_names[x]);
        strcat(msg, "'");
        count++;
      }
    }
    if (matched) {
      PyErr_Format(PyExc_SyntaxError, msg, line, column, matched);
    } else {
      PyErr_Format(PyExc_SyntaxError, msg, line, column);
    }
    PyMem_Del(msg);
  } else {
    if (matched) {
      PyErr_Format(PyExc_SyntaxError, error_format_str, line, column, matched);
    } else {
      PyErr_Format(PyExc_SyntaxError, error_format_eof_str, line, column);
    }
  }

  if (matched) {
    PyMem_Del(matched);
  }

  return NULL;
}

static const char lexer_error_str[] = "lexical error at line %d, column %d: no action found for '%s'";

static void lexer_error(lexerobject *lexer)
{
  int line, column;
  char *repr = unicode_escape(lexer->position, (lexer->end - lexer->position));
  if (repr == NULL) return;

  calculate_position(lexer, &line, &column);

  PyErr_Format(PyExc_SyntaxError, lexer_error_str, line, column, repr);

  PyMem_Del(repr);
  return;
}

static void print_reduce(int ruleno) {
  int count;
  const int *token;

  PySys_WriteStderr("Reducing via rule %d (%s), ", ruleno, rule_info[ruleno]);
  /* print the symbols being reduced and their result. */

  count = ruleno;
  token = rhs_tokens;
  while (--count) while (*++token);

  while (*++token) {
    PySys_WriteStderr("%s ", token_names[*token]);
  }
  PySys_WriteStderr("-> %s\n", token_names[derives[ruleno]]);
}

static void print_state_stack(int *stack, int *end) {
  int *curr = stack;

  PySys_WriteStderr("state stack now");
  while (curr <= end) {
    PySys_WriteStderr(" %d", *curr++);
  }
  PySys_WriteStderr("\n");
}

static PyObject *import_from(char *modulename, char *fromname) {
  PyObject *fromlist, *name, *module;

  fromlist = PyTuple_New(1);
  if (fromlist == NULL) return NULL;

  name = PyString_FromString(fromname);
  if (name == NULL) {
    Py_DECREF(fromlist);
    return NULL;
  }
  Py_INCREF(name);
  PyTuple_SET_ITEM(fromlist, 0, name);

  module = PyImport_ImportModuleEx(modulename, NULL, NULL, fromlist);
  Py_DECREF(fromlist);
  if (module == NULL) {
    Py_DECREF(name);
    return NULL;
  }

  fromlist = PyObject_GetAttr(module, name);
  Py_DECREF(module);
  Py_DECREF(name);
  return fromlist;
}

static PyMethodDef module_methods[] = {
  { NULL }
};

DL_EXPORT(void) initVersaParserc(void) {
  PyObject *module;

  if (PyType_Ready(&Parser_Type) < 0) return;

  module = Py_InitModule("VersaParserc", module_methods);
  if (module == NULL) return;

  Py_INCREF(&Parser_Type);
  PyModule_AddObject(module, "VersaParser",
                     (PyObject *) &Parser_Type);
  Py_INCREF(&Parser_Type);
  PyModule_AddObject(module, "new",
                     (PyObject *) &Parser_Type);

  /* import the modules required for action routines */
  /* from Ft.Rdf.Parsers.Versa import ResourceExpressions */
  ResourceExpressions = import_from("Ft.Rdf.Parsers.Versa", "ResourceExpressions");
  if (ResourceExpressions == NULL) return;

  /* from Ft.Rdf.Parsers.Versa import BooleanExpressions */
  BooleanExpressions = import_from("Ft.Rdf.Parsers.Versa", "BooleanExpressions");
  if (BooleanExpressions == NULL) return;

  /* from Ft.Rdf.Parsers.Versa import Traversal */
  Traversal = import_from("Ft.Rdf.Parsers.Versa", "Traversal");
  if (Traversal == NULL) return;

  /* from Ft.Rdf.Parsers.Versa import Literals */
  Literals = import_from("Ft.Rdf.Parsers.Versa", "Literals");
  if (Literals == NULL) return;

  /* from Ft.Rdf.Parsers.Versa import DataTypes */
  DataTypes = import_from("Ft.Rdf.Parsers.Versa", "DataTypes");
  if (DataTypes == NULL) return;

  /* from Ft.Rdf.Parsers.Versa import NamedExpressions */
  NamedExpressions = import_from("Ft.Rdf.Parsers.Versa", "NamedExpressions");
  if (NamedExpressions == NULL) return;

  /* from Ft.Lib import boolean */
  boolean = import_from("Ft.Lib", "boolean");
  if (boolean == NULL) return;

}
