summaryrefslogtreecommitdiff
path: root/ext/ply/test
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ply/test')
-rw-r--r--ext/ply/test/README9
-rw-r--r--ext/ply/test/calclex.py46
-rw-r--r--ext/ply/test/lex_doc1.exp1
-rw-r--r--ext/ply/test/lex_doc1.py27
-rw-r--r--ext/ply/test/lex_dup1.exp2
-rw-r--r--ext/ply/test/lex_dup1.py27
-rw-r--r--ext/ply/test/lex_dup2.exp2
-rw-r--r--ext/ply/test/lex_dup2.py31
-rw-r--r--ext/ply/test/lex_dup3.exp2
-rw-r--r--ext/ply/test/lex_dup3.py29
-rw-r--r--ext/ply/test/lex_empty.exp1
-rw-r--r--ext/ply/test/lex_empty.py18
-rw-r--r--ext/ply/test/lex_error1.exp1
-rw-r--r--ext/ply/test/lex_error1.py22
-rw-r--r--ext/ply/test/lex_error2.exp1
-rw-r--r--ext/ply/test/lex_error2.py24
-rw-r--r--ext/ply/test/lex_error3.exp2
-rw-r--r--ext/ply/test/lex_error3.py25
-rw-r--r--ext/ply/test/lex_error4.exp2
-rw-r--r--ext/ply/test/lex_error4.py25
-rw-r--r--ext/ply/test/lex_hedit.exp3
-rw-r--r--ext/ply/test/lex_hedit.py44
-rw-r--r--ext/ply/test/lex_ignore.exp2
-rw-r--r--ext/ply/test/lex_ignore.py29
-rw-r--r--ext/ply/test/lex_re1.exp2
-rw-r--r--ext/ply/test/lex_re1.py25
-rw-r--r--ext/ply/test/lex_rule1.exp2
-rw-r--r--ext/ply/test/lex_rule1.py25
-rw-r--r--ext/ply/test/lex_token1.exp1
-rw-r--r--ext/ply/test/lex_token1.py19
-rw-r--r--ext/ply/test/lex_token2.exp1
-rw-r--r--ext/ply/test/lex_token2.py21
-rw-r--r--ext/ply/test/lex_token3.exp2
-rw-r--r--ext/ply/test/lex_token3.py24
-rw-r--r--ext/ply/test/lex_token4.exp2
-rw-r--r--ext/ply/test/lex_token4.py26
-rw-r--r--ext/ply/test/lex_token5.exp1
-rw-r--r--ext/ply/test/lex_token5.py31
-rwxr-xr-xext/ply/test/testlex.py57
-rw-r--r--ext/ply/test/testyacc.py58
-rw-r--r--ext/ply/test/yacc_badargs.exp3
-rw-r--r--ext/ply/test/yacc_badargs.py67
-rw-r--r--ext/ply/test/yacc_badprec.exp1
-rw-r--r--ext/ply/test/yacc_badprec.py63
-rw-r--r--ext/ply/test/yacc_badprec2.exp3
-rw-r--r--ext/ply/test/yacc_badprec2.py67
-rw-r--r--ext/ply/test/yacc_badrule.exp5
-rw-r--r--ext/ply/test/yacc_badrule.py67
-rw-r--r--ext/ply/test/yacc_badtok.exp1
-rw-r--r--ext/ply/test/yacc_badtok.py68
-rw-r--r--ext/ply/test/yacc_dup.exp4
-rw-r--r--ext/ply/test/yacc_dup.py67
-rw-r--r--ext/ply/test/yacc_error1.exp1
-rw-r--r--ext/ply/test/yacc_error1.py67
-rw-r--r--ext/ply/test/yacc_error2.exp1
-rw-r--r--ext/ply/test/yacc_error2.py67
-rw-r--r--ext/ply/test/yacc_error3.exp1
-rw-r--r--ext/ply/test/yacc_error3.py66
-rw-r--r--ext/ply/test/yacc_inf.exp5
-rw-r--r--ext/ply/test/yacc_inf.py55
-rw-r--r--ext/ply/test/yacc_missing1.exp2
-rw-r--r--ext/ply/test/yacc_missing1.py67
-rw-r--r--ext/ply/test/yacc_nodoc.exp2
-rw-r--r--ext/ply/test/yacc_nodoc.py66
-rw-r--r--ext/ply/test/yacc_noerror.exp2
-rw-r--r--ext/ply/test/yacc_noerror.py64
-rw-r--r--ext/ply/test/yacc_nop.exp2
-rw-r--r--ext/ply/test/yacc_nop.py67
-rw-r--r--ext/ply/test/yacc_notfunc.exp4
-rw-r--r--ext/ply/test/yacc_notfunc.py65
-rw-r--r--ext/ply/test/yacc_notok.exp1
-rw-r--r--ext/ply/test/yacc_notok.py66
-rw-r--r--ext/ply/test/yacc_rr.exp2
-rw-r--r--ext/ply/test/yacc_rr.py71
-rw-r--r--ext/ply/test/yacc_simple.exp1
-rw-r--r--ext/ply/test/yacc_simple.py67
-rw-r--r--ext/ply/test/yacc_sr.exp2
-rw-r--r--ext/ply/test/yacc_sr.py62
-rw-r--r--ext/ply/test/yacc_term1.exp2
-rw-r--r--ext/ply/test/yacc_term1.py67
-rw-r--r--ext/ply/test/yacc_unused.exp4
-rw-r--r--ext/ply/test/yacc_unused.py76
-rw-r--r--ext/ply/test/yacc_uprec.exp2
-rw-r--r--ext/ply/test/yacc_uprec.py62
84 files changed, 2177 insertions, 0 deletions
diff --git a/ext/ply/test/README b/ext/ply/test/README
new file mode 100644
index 000000000..bca748497
--- /dev/null
+++ b/ext/ply/test/README
@@ -0,0 +1,9 @@
+This directory mostly contains tests for various types of error
+conditions. To run:
+
+ $ python testlex.py .
+ $ python testyacc.py .
+
+(make sure lex.py and yacc.py exist in this directory before
+running the tests).
+
diff --git a/ext/ply/test/calclex.py b/ext/ply/test/calclex.py
new file mode 100644
index 000000000..f8eb91a09
--- /dev/null
+++ b/ext/ply/test/calclex.py
@@ -0,0 +1,46 @@
+# -----------------------------------------------------------------------------
+# calclex.py
+# -----------------------------------------------------------------------------
+
+tokens = (
+ 'NAME','NUMBER',
+ 'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
+ 'LPAREN','RPAREN',
+ )
+
+# Tokens
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_TIMES = r'\*'
+t_DIVIDE = r'/'
+t_EQUALS = r'='
+t_LPAREN = r'\('
+t_RPAREN = r'\)'
+t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
+
+def t_NUMBER(t):
+ r'\d+'
+ try:
+ t.value = int(t.value)
+ except ValueError:
+ print "Integer value too large", t.value
+ t.value = 0
+ return t
+
+t_ignore = " \t"
+
+def t_newline(t):
+ r'\n+'
+ t.lineno += t.value.count("\n")
+
+def t_error(t):
+ print "Illegal character '%s'" % t.value[0]
+ t.skip(1)
+
+# Build the lexer
+import lex
+lex.lex()
+
+
+
diff --git a/ext/ply/test/lex_doc1.exp b/ext/ply/test/lex_doc1.exp
new file mode 100644
index 000000000..29381911d
--- /dev/null
+++ b/ext/ply/test/lex_doc1.exp
@@ -0,0 +1 @@
+./lex_doc1.py:15: No regular expression defined for rule 't_NUMBER'
diff --git a/ext/ply/test/lex_doc1.py b/ext/ply/test/lex_doc1.py
new file mode 100644
index 000000000..fb0fb885e
--- /dev/null
+++ b/ext/ply/test/lex_doc1.py
@@ -0,0 +1,27 @@
+# lex_token.py
+#
+# Missing documentation string
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+def t_NUMBER(t):
+ pass
+
+def t_error(t):
+ pass
+
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_dup1.exp b/ext/ply/test/lex_dup1.exp
new file mode 100644
index 000000000..22bca3190
--- /dev/null
+++ b/ext/ply/test/lex_dup1.exp
@@ -0,0 +1,2 @@
+./lex_dup1.py:17: Rule t_NUMBER redefined. Previously defined on line 15
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_dup1.py b/ext/ply/test/lex_dup1.py
new file mode 100644
index 000000000..88bbe00e9
--- /dev/null
+++ b/ext/ply/test/lex_dup1.py
@@ -0,0 +1,27 @@
+# lex_token.py
+#
+# Duplicated rule specifiers
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+t_NUMBER = r'\d+'
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_dup2.exp b/ext/ply/test/lex_dup2.exp
new file mode 100644
index 000000000..883bdad46
--- /dev/null
+++ b/ext/ply/test/lex_dup2.exp
@@ -0,0 +1,2 @@
+./lex_dup2.py:19: Rule t_NUMBER redefined. Previously defined on line 15
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_dup2.py b/ext/ply/test/lex_dup2.py
new file mode 100644
index 000000000..65e0b21a2
--- /dev/null
+++ b/ext/ply/test/lex_dup2.py
@@ -0,0 +1,31 @@
+# lex_token.py
+#
+# Duplicated rule specifiers
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+def t_NUMBER(t):
+ r'\d+'
+ pass
+
+def t_NUMBER(t):
+ r'\d+'
+ pass
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_dup3.exp b/ext/ply/test/lex_dup3.exp
new file mode 100644
index 000000000..916612aa1
--- /dev/null
+++ b/ext/ply/test/lex_dup3.exp
@@ -0,0 +1,2 @@
+./lex_dup3.py:17: Rule t_NUMBER redefined. Previously defined on line 15
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_dup3.py b/ext/ply/test/lex_dup3.py
new file mode 100644
index 000000000..424101823
--- /dev/null
+++ b/ext/ply/test/lex_dup3.py
@@ -0,0 +1,29 @@
+# lex_token.py
+#
+# Duplicated rule specifiers
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+def t_NUMBER(t):
+ r'\d+'
+ pass
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_empty.exp b/ext/ply/test/lex_empty.exp
new file mode 100644
index 000000000..af38602d5
--- /dev/null
+++ b/ext/ply/test/lex_empty.exp
@@ -0,0 +1 @@
+SyntaxError: lex: no rules of the form t_rulename are defined.
diff --git a/ext/ply/test/lex_empty.py b/ext/ply/test/lex_empty.py
new file mode 100644
index 000000000..6472832f1
--- /dev/null
+++ b/ext/ply/test/lex_empty.py
@@ -0,0 +1,18 @@
+# lex_token.py
+#
+# No rules defined
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_error1.exp b/ext/ply/test/lex_error1.exp
new file mode 100644
index 000000000..baa19e5b3
--- /dev/null
+++ b/ext/ply/test/lex_error1.exp
@@ -0,0 +1 @@
+lex: Warning. no t_error rule is defined.
diff --git a/ext/ply/test/lex_error1.py b/ext/ply/test/lex_error1.py
new file mode 100644
index 000000000..ed7980346
--- /dev/null
+++ b/ext/ply/test/lex_error1.py
@@ -0,0 +1,22 @@
+# lex_token.py
+#
+# Missing t_error() rule
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_error2.exp b/ext/ply/test/lex_error2.exp
new file mode 100644
index 000000000..fb1b55c8b
--- /dev/null
+++ b/ext/ply/test/lex_error2.exp
@@ -0,0 +1 @@
+SyntaxError: lex: Rule 't_error' must be defined as a function
diff --git a/ext/ply/test/lex_error2.py b/ext/ply/test/lex_error2.py
new file mode 100644
index 000000000..80020f72b
--- /dev/null
+++ b/ext/ply/test/lex_error2.py
@@ -0,0 +1,24 @@
+# lex_token.py
+#
+# t_error defined, but not function
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+t_error = "foo"
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_error3.exp b/ext/ply/test/lex_error3.exp
new file mode 100644
index 000000000..936828f93
--- /dev/null
+++ b/ext/ply/test/lex_error3.exp
@@ -0,0 +1,2 @@
+./lex_error3.py:17: Rule 't_error' requires an argument.
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_error3.py b/ext/ply/test/lex_error3.py
new file mode 100644
index 000000000..46facf589
--- /dev/null
+++ b/ext/ply/test/lex_error3.py
@@ -0,0 +1,25 @@
+# lex_token.py
+#
+# t_error defined as function, but with wrong # args
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+def t_error():
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_error4.exp b/ext/ply/test/lex_error4.exp
new file mode 100644
index 000000000..242516576
--- /dev/null
+++ b/ext/ply/test/lex_error4.exp
@@ -0,0 +1,2 @@
+./lex_error4.py:17: Rule 't_error' has too many arguments.
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_error4.py b/ext/ply/test/lex_error4.py
new file mode 100644
index 000000000..d777fee84
--- /dev/null
+++ b/ext/ply/test/lex_error4.py
@@ -0,0 +1,25 @@
+# lex_token.py
+#
+# t_error defined as function, but too many args
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+def t_error(t,s):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_hedit.exp b/ext/ply/test/lex_hedit.exp
new file mode 100644
index 000000000..0b09827c6
--- /dev/null
+++ b/ext/ply/test/lex_hedit.exp
@@ -0,0 +1,3 @@
+(H_EDIT_DESCRIPTOR,'abc',1)
+(H_EDIT_DESCRIPTOR,'abcdefghij',1)
+(H_EDIT_DESCRIPTOR,'xy',1)
diff --git a/ext/ply/test/lex_hedit.py b/ext/ply/test/lex_hedit.py
new file mode 100644
index 000000000..68f9fcbd1
--- /dev/null
+++ b/ext/ply/test/lex_hedit.py
@@ -0,0 +1,44 @@
+# -----------------------------------------------------------------------------
+# hedit.py
+#
+# Paring of Fortran H Edit descriptions (Contributed by Pearu Peterson)
+#
+# These tokens can't be easily tokenized because they are of the following
+# form:
+#
+# nHc1...cn
+#
+# where n is a positive integer and c1 ... cn are characters.
+#
+# This example shows how to modify the state of the lexer to parse
+# such tokens
+# -----------------------------------------------------------------------------
+
+tokens = (
+ 'H_EDIT_DESCRIPTOR',
+ )
+
+# Tokens
+t_ignore = " \t\n"
+
+def t_H_EDIT_DESCRIPTOR(t):
+ r"\d+H.*" # This grabs all of the remaining text
+ i = t.value.index('H')
+ n = eval(t.value[:i])
+
+ # Adjust the tokenizing position
+ t.lexer.lexpos -= len(t.value) - (i+1+n)
+ t.value = t.value[i+1:i+1+n]
+ return t
+
+def t_error(t):
+ print "Illegal character '%s'" % t.value[0]
+ t.skip(1)
+
+# Build the lexer
+import lex
+lex.lex()
+lex.runmain(data="3Habc 10Habcdefghij 2Hxy")
+
+
+
diff --git a/ext/ply/test/lex_ignore.exp b/ext/ply/test/lex_ignore.exp
new file mode 100644
index 000000000..c3b04a154
--- /dev/null
+++ b/ext/ply/test/lex_ignore.exp
@@ -0,0 +1,2 @@
+./lex_ignore.py:17: Rule 't_ignore' must be defined as a string.
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_ignore.py b/ext/ply/test/lex_ignore.py
new file mode 100644
index 000000000..49c303f81
--- /dev/null
+++ b/ext/ply/test/lex_ignore.py
@@ -0,0 +1,29 @@
+# lex_token.py
+#
+# Improperly specific ignore declaration
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+def t_ignore(t):
+ ' \t'
+ pass
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_re1.exp b/ext/ply/test/lex_re1.exp
new file mode 100644
index 000000000..634eefefe
--- /dev/null
+++ b/ext/ply/test/lex_re1.exp
@@ -0,0 +1,2 @@
+lex: Invalid regular expression for rule 't_NUMBER'. unbalanced parenthesis
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_re1.py b/ext/ply/test/lex_re1.py
new file mode 100644
index 000000000..4a055ad72
--- /dev/null
+++ b/ext/ply/test/lex_re1.py
@@ -0,0 +1,25 @@
+# lex_token.py
+#
+# Bad regular expression in a string
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'(\d+'
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_rule1.exp b/ext/ply/test/lex_rule1.exp
new file mode 100644
index 000000000..0c23ca294
--- /dev/null
+++ b/ext/ply/test/lex_rule1.exp
@@ -0,0 +1,2 @@
+lex: t_NUMBER not defined as a function or string
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_rule1.py b/ext/ply/test/lex_rule1.py
new file mode 100644
index 000000000..ff3764ea1
--- /dev/null
+++ b/ext/ply/test/lex_rule1.py
@@ -0,0 +1,25 @@
+# lex_token.py
+#
+# Rule defined as some other type
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = 1
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_token1.exp b/ext/ply/test/lex_token1.exp
new file mode 100644
index 000000000..3792831fa
--- /dev/null
+++ b/ext/ply/test/lex_token1.exp
@@ -0,0 +1 @@
+SyntaxError: lex: module does not define 'tokens'
diff --git a/ext/ply/test/lex_token1.py b/ext/ply/test/lex_token1.py
new file mode 100644
index 000000000..e8eca2b63
--- /dev/null
+++ b/ext/ply/test/lex_token1.py
@@ -0,0 +1,19 @@
+# lex_token.py
+#
+# Tests for absence of tokens variable
+
+import lex
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_token2.exp b/ext/ply/test/lex_token2.exp
new file mode 100644
index 000000000..3f98fe51d
--- /dev/null
+++ b/ext/ply/test/lex_token2.exp
@@ -0,0 +1 @@
+SyntaxError: lex: tokens must be a list or tuple.
diff --git a/ext/ply/test/lex_token2.py b/ext/ply/test/lex_token2.py
new file mode 100644
index 000000000..38b34dabe
--- /dev/null
+++ b/ext/ply/test/lex_token2.py
@@ -0,0 +1,21 @@
+# lex_token.py
+#
+# Tests for tokens of wrong type
+
+import lex
+
+tokens = "PLUS MINUS NUMBER"
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_token3.exp b/ext/ply/test/lex_token3.exp
new file mode 100644
index 000000000..d991d3c37
--- /dev/null
+++ b/ext/ply/test/lex_token3.exp
@@ -0,0 +1,2 @@
+lex: Rule 't_MINUS' defined for an unspecified token MINUS.
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_token3.py b/ext/ply/test/lex_token3.py
new file mode 100644
index 000000000..909f9180d
--- /dev/null
+++ b/ext/ply/test/lex_token3.py
@@ -0,0 +1,24 @@
+# lex_token.py
+#
+# tokens is right type, but is missing a token for one rule
+
+import lex
+
+tokens = [
+ "PLUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_token4.exp b/ext/ply/test/lex_token4.exp
new file mode 100644
index 000000000..3dd88e05a
--- /dev/null
+++ b/ext/ply/test/lex_token4.exp
@@ -0,0 +1,2 @@
+lex: Bad token name '-'
+SyntaxError: lex: Unable to build lexer.
diff --git a/ext/ply/test/lex_token4.py b/ext/ply/test/lex_token4.py
new file mode 100644
index 000000000..d77d1662c
--- /dev/null
+++ b/ext/ply/test/lex_token4.py
@@ -0,0 +1,26 @@
+# lex_token.py
+#
+# Bad token name
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "-",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+t_NUMBER = r'\d+'
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+
+
diff --git a/ext/ply/test/lex_token5.exp b/ext/ply/test/lex_token5.exp
new file mode 100644
index 000000000..d7bcb2e7c
--- /dev/null
+++ b/ext/ply/test/lex_token5.exp
@@ -0,0 +1 @@
+lex.LexError: ./lex_token5.py:16: Rule 't_NUMBER' returned an unknown token type 'NUM'
diff --git a/ext/ply/test/lex_token5.py b/ext/ply/test/lex_token5.py
new file mode 100644
index 000000000..d9b0c96aa
--- /dev/null
+++ b/ext/ply/test/lex_token5.py
@@ -0,0 +1,31 @@
+# lex_token.py
+#
+# Return a bad token name
+
+import lex
+
+tokens = [
+ "PLUS",
+ "MINUS",
+ "NUMBER",
+ ]
+
+t_PLUS = r'\+'
+t_MINUS = r'-'
+
+def t_NUMBER(t):
+ r'\d+'
+ t.type = "NUM"
+ return t
+
+def t_error(t):
+ pass
+
+import sys
+sys.tracebacklimit = 0
+
+lex.lex()
+lex.input("1234")
+t = lex.token()
+
+
diff --git a/ext/ply/test/testlex.py b/ext/ply/test/testlex.py
new file mode 100755
index 000000000..df000b83d
--- /dev/null
+++ b/ext/ply/test/testlex.py
@@ -0,0 +1,57 @@
+#!/usr/local/bin
+# ----------------------------------------------------------------------
+# testlex.py
+#
+# Run tests for the lexing module
+# ----------------------------------------------------------------------
+
+import sys,os,glob
+
+if len(sys.argv) < 2:
+ print "Usage: python testlex.py directory"
+ raise SystemExit
+
+dirname = None
+make = 0
+
+for o in sys.argv[1:]:
+ if o == '-make':
+ make = 1
+ else:
+ dirname = o
+ break
+
+if not dirname:
+ print "Usage: python testlex.py [-make] directory"
+ raise SystemExit
+
+f = glob.glob("%s/%s" % (dirname,"lex_*.py"))
+
+print "**** Running tests for lex ****"
+
+for t in f:
+ name = t[:-3]
+ print "Testing %-32s" % name,
+ if make:
+ if not os.path.exists("%s.exp" % name):
+ os.system("python %s.py >%s.exp 2>&1" % (name,name))
+ passed = 1
+ else:
+ os.system("python %s.py >%s.out 2>&1" % (name,name))
+ a = os.system("diff %s.out %s.exp >%s.dif" % (name,name,name))
+ if a == 0:
+ passed = 1
+ else:
+ passed = 0
+
+ if passed:
+ print "Passed"
+ else:
+ print "Failed. See %s.dif" % name
+
+
+
+
+
+
+
diff --git a/ext/ply/test/testyacc.py b/ext/ply/test/testyacc.py
new file mode 100644
index 000000000..a185cbb29
--- /dev/null
+++ b/ext/ply/test/testyacc.py
@@ -0,0 +1,58 @@
+#!/usr/local/bin
+# ----------------------------------------------------------------------
+# testyacc.py
+#
+# Run tests for the yacc module
+# ----------------------------------------------------------------------
+
+import sys,os,glob
+
+if len(sys.argv) < 2:
+ print "Usage: python testyacc.py directory"
+ raise SystemExit
+
+dirname = None
+make = 0
+
+for o in sys.argv[1:]:
+ if o == '-make':
+ make = 1
+ else:
+ dirname = o
+ break
+
+if not dirname:
+ print "Usage: python testyacc.py [-make] directory"
+ raise SystemExit
+
+f = glob.glob("%s/%s" % (dirname,"yacc_*.py"))
+
+print "**** Running tests for yacc ****"
+
+for t in f:
+ name = t[:-3]
+ print "Testing %-32s" % name,
+ os.system("rm -f %s/parsetab.*" % dirname)
+ if make:
+ if not os.path.exists("%s.exp" % name):
+ os.system("python %s.py >%s.exp 2>&1" % (name,name))
+ passed = 1
+ else:
+ os.system("python %s.py >%s.out 2>&1" % (name,name))
+ a = os.system("diff %s.out %s.exp >%s.dif" % (name,name,name))
+ if a == 0:
+ passed = 1
+ else:
+ passed = 0
+
+ if passed:
+ print "Passed"
+ else:
+ print "Failed. See %s.dif" % name
+
+
+
+
+
+
+
diff --git a/ext/ply/test/yacc_badargs.exp b/ext/ply/test/yacc_badargs.exp
new file mode 100644
index 000000000..b145c51f2
--- /dev/null
+++ b/ext/ply/test/yacc_badargs.exp
@@ -0,0 +1,3 @@
+./yacc_badargs.py:21: Rule 'p_statement_assign' has too many arguments.
+./yacc_badargs.py:25: Rule 'p_statement_expr' requires an argument.
+yacc.YaccError: Unable to construct parser.
diff --git a/ext/ply/test/yacc_badargs.py b/ext/ply/test/yacc_badargs.py
new file mode 100644
index 000000000..12075efcc
--- /dev/null
+++ b/ext/ply/test/yacc_badargs.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_badargs.py
+#
+# Rules with wrong # args
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t,s):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr():
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_badprec.exp b/ext/ply/test/yacc_badprec.exp
new file mode 100644
index 000000000..7764b0246
--- /dev/null
+++ b/ext/ply/test/yacc_badprec.exp
@@ -0,0 +1 @@
+yacc.YaccError: precedence must be a list or tuple.
diff --git a/ext/ply/test/yacc_badprec.py b/ext/ply/test/yacc_badprec.py
new file mode 100644
index 000000000..55bf7720d
--- /dev/null
+++ b/ext/ply/test/yacc_badprec.py
@@ -0,0 +1,63 @@
+# -----------------------------------------------------------------------------
+# yacc_badprec.py
+#
+# Bad precedence specifier
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = "blah"
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_badprec2.exp b/ext/ply/test/yacc_badprec2.exp
new file mode 100644
index 000000000..1df1427b2
--- /dev/null
+++ b/ext/ply/test/yacc_badprec2.exp
@@ -0,0 +1,3 @@
+yacc: Invalid precedence table.
+yacc: Generating SLR parsing table...
+yacc: 4 shift/reduce conflicts
diff --git a/ext/ply/test/yacc_badprec2.py b/ext/ply/test/yacc_badprec2.py
new file mode 100644
index 000000000..9cbc99827
--- /dev/null
+++ b/ext/ply/test/yacc_badprec2.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_badprec2.py
+#
+# Bad precedence
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ 42,
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_badrule.exp b/ext/ply/test/yacc_badrule.exp
new file mode 100644
index 000000000..553779778
--- /dev/null
+++ b/ext/ply/test/yacc_badrule.exp
@@ -0,0 +1,5 @@
+./yacc_badrule.py:22: Syntax error. Expected ':'
+./yacc_badrule.py:26: Syntax error in rule 'statement'
+./yacc_badrule.py:31: Syntax error. Expected ':'
+./yacc_badrule.py:40: Syntax error. Expected ':'
+yacc.YaccError: Unable to construct parser.
diff --git a/ext/ply/test/yacc_badrule.py b/ext/ply/test/yacc_badrule.py
new file mode 100644
index 000000000..cad3a967e
--- /dev/null
+++ b/ext/ply/test/yacc_badrule.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_badrule.py
+#
+# Syntax problems in the rule strings
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression: MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_badtok.exp b/ext/ply/test/yacc_badtok.exp
new file mode 100644
index 000000000..f6e64726c
--- /dev/null
+++ b/ext/ply/test/yacc_badtok.exp
@@ -0,0 +1 @@
+yacc.YaccError: tokens must be a list or tuple.
diff --git a/ext/ply/test/yacc_badtok.py b/ext/ply/test/yacc_badtok.py
new file mode 100644
index 000000000..a17d26aaa
--- /dev/null
+++ b/ext/ply/test/yacc_badtok.py
@@ -0,0 +1,68 @@
+# -----------------------------------------------------------------------------
+# yacc_badtok.py
+#
+# A grammar, but tokens is a bad datatype
+# -----------------------------------------------------------------------------
+
+import sys
+sys.tracebacklimit = 0
+
+tokens = "Hello"
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_dup.exp b/ext/ply/test/yacc_dup.exp
new file mode 100644
index 000000000..99f3fe22c
--- /dev/null
+++ b/ext/ply/test/yacc_dup.exp
@@ -0,0 +1,4 @@
+./yacc_dup.py:25: Function p_statement redefined. Previously defined on line 21
+yacc: Warning. Token 'EQUALS' defined, but not used.
+yacc: Warning. There is 1 unused token.
+yacc: Generating SLR parsing table...
diff --git a/ext/ply/test/yacc_dup.py b/ext/ply/test/yacc_dup.py
new file mode 100644
index 000000000..557cd0ae1
--- /dev/null
+++ b/ext/ply/test/yacc_dup.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_dup.py
+#
+# Duplicated rule name
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_error1.exp b/ext/ply/test/yacc_error1.exp
new file mode 100644
index 000000000..980fc905c
--- /dev/null
+++ b/ext/ply/test/yacc_error1.exp
@@ -0,0 +1 @@
+yacc.YaccError: ./yacc_error1.py:59: p_error() requires 1 argument.
diff --git a/ext/ply/test/yacc_error1.py b/ext/ply/test/yacc_error1.py
new file mode 100644
index 000000000..413004520
--- /dev/null
+++ b/ext/ply/test/yacc_error1.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_error1.py
+#
+# Bad p_error() function
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t,s):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_error2.exp b/ext/ply/test/yacc_error2.exp
new file mode 100644
index 000000000..d0573b4dd
--- /dev/null
+++ b/ext/ply/test/yacc_error2.exp
@@ -0,0 +1 @@
+yacc.YaccError: ./yacc_error2.py:59: p_error() requires 1 argument.
diff --git a/ext/ply/test/yacc_error2.py b/ext/ply/test/yacc_error2.py
new file mode 100644
index 000000000..d4fd1d219
--- /dev/null
+++ b/ext/ply/test/yacc_error2.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_error1.py
+#
+# Bad p_error() function
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error():
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_error3.exp b/ext/ply/test/yacc_error3.exp
new file mode 100644
index 000000000..31eaee754
--- /dev/null
+++ b/ext/ply/test/yacc_error3.exp
@@ -0,0 +1 @@
+yacc.YaccError: 'p_error' defined, but is not a function.
diff --git a/ext/ply/test/yacc_error3.py b/ext/ply/test/yacc_error3.py
new file mode 100644
index 000000000..7093fab48
--- /dev/null
+++ b/ext/ply/test/yacc_error3.py
@@ -0,0 +1,66 @@
+# -----------------------------------------------------------------------------
+# yacc_error1.py
+#
+# Bad p_error() function
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+p_error = "blah"
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_inf.exp b/ext/ply/test/yacc_inf.exp
new file mode 100644
index 000000000..a7f47dada
--- /dev/null
+++ b/ext/ply/test/yacc_inf.exp
@@ -0,0 +1,5 @@
+yacc: Warning. Token 'NUMBER' defined, but not used.
+yacc: Warning. There is 1 unused token.
+yacc: Infinite recursion detected for symbol 'statement'.
+yacc: Infinite recursion detected for symbol 'expression'.
+yacc.YaccError: Unable to construct parser.
diff --git a/ext/ply/test/yacc_inf.py b/ext/ply/test/yacc_inf.py
new file mode 100644
index 000000000..885e2c4df
--- /dev/null
+++ b/ext/ply/test/yacc_inf.py
@@ -0,0 +1,55 @@
+# -----------------------------------------------------------------------------
+# yacc_inf.py
+#
+# Infinite recursion
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_missing1.exp b/ext/ply/test/yacc_missing1.exp
new file mode 100644
index 000000000..065d6a54a
--- /dev/null
+++ b/ext/ply/test/yacc_missing1.exp
@@ -0,0 +1,2 @@
+./yacc_missing1.py:22: Symbol 'location' used, but not defined as a token or a rule.
+yacc.YaccError: Unable to construct parser.
diff --git a/ext/ply/test/yacc_missing1.py b/ext/ply/test/yacc_missing1.py
new file mode 100644
index 000000000..e63904d0e
--- /dev/null
+++ b/ext/ply/test/yacc_missing1.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_missing1.py
+#
+# Grammar with a missing rule
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : location EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_nodoc.exp b/ext/ply/test/yacc_nodoc.exp
new file mode 100644
index 000000000..3f52a3287
--- /dev/null
+++ b/ext/ply/test/yacc_nodoc.exp
@@ -0,0 +1,2 @@
+./yacc_nodoc.py:25: No documentation string specified in function 'p_statement_expr'
+yacc: Generating SLR parsing table...
diff --git a/ext/ply/test/yacc_nodoc.py b/ext/ply/test/yacc_nodoc.py
new file mode 100644
index 000000000..e3941bdaa
--- /dev/null
+++ b/ext/ply/test/yacc_nodoc.py
@@ -0,0 +1,66 @@
+# -----------------------------------------------------------------------------
+# yacc_nodoc.py
+#
+# Rule with a missing doc-string
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_noerror.exp b/ext/ply/test/yacc_noerror.exp
new file mode 100644
index 000000000..986fa31fa
--- /dev/null
+++ b/ext/ply/test/yacc_noerror.exp
@@ -0,0 +1,2 @@
+yacc: Warning. no p_error() function is defined.
+yacc: Generating SLR parsing table...
diff --git a/ext/ply/test/yacc_noerror.py b/ext/ply/test/yacc_noerror.py
new file mode 100644
index 000000000..d92f48ea6
--- /dev/null
+++ b/ext/ply/test/yacc_noerror.py
@@ -0,0 +1,64 @@
+# -----------------------------------------------------------------------------
+# yacc_noerror.py
+#
+# No p_error() rule defined.
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_nop.exp b/ext/ply/test/yacc_nop.exp
new file mode 100644
index 000000000..062878b9e
--- /dev/null
+++ b/ext/ply/test/yacc_nop.exp
@@ -0,0 +1,2 @@
+./yacc_nop.py:25: Warning. Possible grammar rule 'statement_expr' defined without p_ prefix.
+yacc: Generating SLR parsing table...
diff --git a/ext/ply/test/yacc_nop.py b/ext/ply/test/yacc_nop.py
new file mode 100644
index 000000000..c599ffd5d
--- /dev/null
+++ b/ext/ply/test/yacc_nop.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_nop.py
+#
+# Possible grammar rule defined without p_ prefix
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_notfunc.exp b/ext/ply/test/yacc_notfunc.exp
new file mode 100644
index 000000000..271167341
--- /dev/null
+++ b/ext/ply/test/yacc_notfunc.exp
@@ -0,0 +1,4 @@
+yacc: Warning. 'p_statement_assign' not defined as a function
+yacc: Warning. Token 'EQUALS' defined, but not used.
+yacc: Warning. There is 1 unused token.
+yacc: Generating SLR parsing table...
diff --git a/ext/ply/test/yacc_notfunc.py b/ext/ply/test/yacc_notfunc.py
new file mode 100644
index 000000000..f61663d60
--- /dev/null
+++ b/ext/ply/test/yacc_notfunc.py
@@ -0,0 +1,65 @@
+# -----------------------------------------------------------------------------
+# yacc_notfunc.py
+#
+# p_rule not defined as a function
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+p_statement_assign = "Blah"
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_notok.exp b/ext/ply/test/yacc_notok.exp
new file mode 100644
index 000000000..708f6f597
--- /dev/null
+++ b/ext/ply/test/yacc_notok.exp
@@ -0,0 +1 @@
+yacc.YaccError: module does not define a list 'tokens'
diff --git a/ext/ply/test/yacc_notok.py b/ext/ply/test/yacc_notok.py
new file mode 100644
index 000000000..dfa0059be
--- /dev/null
+++ b/ext/ply/test/yacc_notok.py
@@ -0,0 +1,66 @@
+# -----------------------------------------------------------------------------
+# yacc_notok.py
+#
+# A grammar, but we forgot to import the tokens list
+# -----------------------------------------------------------------------------
+
+import sys
+sys.tracebacklimit = 0
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_rr.exp b/ext/ply/test/yacc_rr.exp
new file mode 100644
index 000000000..0ec556d16
--- /dev/null
+++ b/ext/ply/test/yacc_rr.exp
@@ -0,0 +1,2 @@
+yacc: Generating SLR parsing table...
+yacc: 1 reduce/reduce conflict
diff --git a/ext/ply/test/yacc_rr.py b/ext/ply/test/yacc_rr.py
new file mode 100644
index 000000000..c061c2c17
--- /dev/null
+++ b/ext/ply/test/yacc_rr.py
@@ -0,0 +1,71 @@
+# -----------------------------------------------------------------------------
+# yacc_rr.py
+#
+# A grammar with a reduce/reduce conflict
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_assign_2(t):
+ 'statement : NAME EQUALS NUMBER'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_simple.exp b/ext/ply/test/yacc_simple.exp
new file mode 100644
index 000000000..de7964b6f
--- /dev/null
+++ b/ext/ply/test/yacc_simple.exp
@@ -0,0 +1 @@
+yacc: Generating SLR parsing table...
diff --git a/ext/ply/test/yacc_simple.py b/ext/ply/test/yacc_simple.py
new file mode 100644
index 000000000..7b4b40b17
--- /dev/null
+++ b/ext/ply/test/yacc_simple.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_simple.py
+#
+# A simple, properly specifier grammar
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_sr.exp b/ext/ply/test/yacc_sr.exp
new file mode 100644
index 000000000..7225ad94b
--- /dev/null
+++ b/ext/ply/test/yacc_sr.exp
@@ -0,0 +1,2 @@
+yacc: Generating SLR parsing table...
+yacc: 20 shift/reduce conflicts
diff --git a/ext/ply/test/yacc_sr.py b/ext/ply/test/yacc_sr.py
new file mode 100644
index 000000000..4341f6997
--- /dev/null
+++ b/ext/ply/test/yacc_sr.py
@@ -0,0 +1,62 @@
+# -----------------------------------------------------------------------------
+# yacc_sr.py
+#
+# A grammar with shift-reduce conflicts
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_term1.exp b/ext/ply/test/yacc_term1.exp
new file mode 100644
index 000000000..422d2bacd
--- /dev/null
+++ b/ext/ply/test/yacc_term1.exp
@@ -0,0 +1,2 @@
+./yacc_term1.py:22: Illegal rule name 'NUMBER'. Already defined as a token.
+yacc.YaccError: Unable to construct parser.
diff --git a/ext/ply/test/yacc_term1.py b/ext/ply/test/yacc_term1.py
new file mode 100644
index 000000000..97a2e7a60
--- /dev/null
+++ b/ext/ply/test/yacc_term1.py
@@ -0,0 +1,67 @@
+# -----------------------------------------------------------------------------
+# yacc_term1.py
+#
+# Terminal used on the left-hand-side
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'NUMBER : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_unused.exp b/ext/ply/test/yacc_unused.exp
new file mode 100644
index 000000000..390754de3
--- /dev/null
+++ b/ext/ply/test/yacc_unused.exp
@@ -0,0 +1,4 @@
+./yacc_unused.py:60: Symbol 'COMMA' used, but not defined as a token or a rule.
+yacc: Symbol 'COMMA' is unreachable.
+yacc: Symbol 'exprlist' is unreachable.
+yacc.YaccError: Unable to construct parser.
diff --git a/ext/ply/test/yacc_unused.py b/ext/ply/test/yacc_unused.py
new file mode 100644
index 000000000..4cbd63327
--- /dev/null
+++ b/ext/ply/test/yacc_unused.py
@@ -0,0 +1,76 @@
+# -----------------------------------------------------------------------------
+# yacc_unused.py
+#
+# A grammar with an unused rule
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+precedence = (
+ ('left','PLUS','MINUS'),
+ ('left','TIMES','DIVIDE'),
+ ('right','UMINUS'),
+ )
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_expr_list(t):
+ 'exprlist : exprlist COMMA expression'
+ pass
+
+def p_expr_list_2(t):
+ 'exprlist : expression'
+ pass
+
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+
diff --git a/ext/ply/test/yacc_uprec.exp b/ext/ply/test/yacc_uprec.exp
new file mode 100644
index 000000000..b1a71a250
--- /dev/null
+++ b/ext/ply/test/yacc_uprec.exp
@@ -0,0 +1,2 @@
+./yacc_uprec.py:35: Nothing known about the precedence of 'UMINUS'
+yacc.YaccError: Unable to construct parser.
diff --git a/ext/ply/test/yacc_uprec.py b/ext/ply/test/yacc_uprec.py
new file mode 100644
index 000000000..139ce6318
--- /dev/null
+++ b/ext/ply/test/yacc_uprec.py
@@ -0,0 +1,62 @@
+# -----------------------------------------------------------------------------
+# yacc_uprec.py
+#
+# A grammar with a bad %prec specifier
+# -----------------------------------------------------------------------------
+import sys
+sys.tracebacklimit = 0
+
+from calclex import tokens
+
+# Parsing rules
+
+# dictionary of names
+names = { }
+
+def p_statement_assign(t):
+ 'statement : NAME EQUALS expression'
+ names[t[1]] = t[3]
+
+def p_statement_expr(t):
+ 'statement : expression'
+ print t[1]
+
+def p_expression_binop(t):
+ '''expression : expression PLUS expression
+ | expression MINUS expression
+ | expression TIMES expression
+ | expression DIVIDE expression'''
+ if t[2] == '+' : t[0] = t[1] + t[3]
+ elif t[2] == '-': t[0] = t[1] - t[3]
+ elif t[2] == '*': t[0] = t[1] * t[3]
+ elif t[3] == '/': t[0] = t[1] / t[3]
+
+def p_expression_uminus(t):
+ 'expression : MINUS expression %prec UMINUS'
+ t[0] = -t[2]
+
+def p_expression_group(t):
+ 'expression : LPAREN expression RPAREN'
+ t[0] = t[2]
+
+def p_expression_number(t):
+ 'expression : NUMBER'
+ t[0] = t[1]
+
+def p_expression_name(t):
+ 'expression : NAME'
+ try:
+ t[0] = names[t[1]]
+ except LookupError:
+ print "Undefined name '%s'" % t[1]
+ t[0] = 0
+
+def p_error(t):
+ print "Syntax error at '%s'" % t.value
+
+import yacc
+yacc.yacc()
+
+
+
+