Adding gem5 source to svn.

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1819 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
friemel
2012-10-24 19:18:57 +00:00
parent f7ff71bd46
commit b41eec3f65
3222 changed files with 658579 additions and 1 deletions

View File

@ -0,0 +1,11 @@
This directory mostly contains tests for various types of error
conditions. To run:
$ python testlex.py .
$ python testyacc.py .
The tests can also be run using the Python unittest module.
$ python rununit.py
The script 'cleanup.sh' cleans up this directory to its original state.

View File

@ -0,0 +1,49 @@
# -----------------------------------------------------------------------------
# calclex.py
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
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 %s" % 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.lexer.skip(1)
# Build the lexer
lex.lex()

View File

@ -0,0 +1,4 @@
#!/bin/sh
rm -f *~ *.pyc *.pyo *.dif *.out

View File

@ -0,0 +1,54 @@
# -----------------------------------------------------------------------------
# lex_closure.py
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = (
'NAME','NUMBER',
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
'LPAREN','RPAREN',
)
def make_calc():
# 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 %s" % 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.lexer.skip(1)
# Build the lexer
return lex.lex()
make_calc()
lex.runmain(data="3+4")

View File

@ -0,0 +1,26 @@
# lex_doc1.py
#
# Missing documentation string
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
def t_NUMBER(t):
pass
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,29 @@
# lex_dup1.py
#
# Duplicated rule specifiers
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
t_NUMBER = r'\d+'
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,33 @@
# lex_dup2.py
#
# Duplicated rule specifiers
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as 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
lex.lex()

View File

@ -0,0 +1,31 @@
# lex_dup3.py
#
# Duplicated rule specifiers
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as 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
lex.lex()

View File

@ -0,0 +1,20 @@
# lex_empty.py
#
# No rules defined
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
lex.lex()

View File

@ -0,0 +1,24 @@
# lex_error1.py
#
# Missing t_error() rule
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
lex.lex()

View File

@ -0,0 +1,26 @@
# lex_error2.py
#
# t_error defined, but not function
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
t_error = "foo"
lex.lex()

View File

@ -0,0 +1,27 @@
# lex_error3.py
#
# t_error defined as function, but with wrong # args
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error():
pass
lex.lex()

View File

@ -0,0 +1,27 @@
# lex_error4.py
#
# t_error defined as function, but too many args
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t,s):
pass
lex.lex()

View File

@ -0,0 +1,47 @@
# -----------------------------------------------------------------------------
# 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
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
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.lexer.skip(1)
# Build the lexer
lex.lex()
lex.runmain(data="3Habc 10Habcdefghij 2Hxy")

View File

@ -0,0 +1,31 @@
# lex_ignore.py
#
# Improperly specific ignore declaration
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as 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
lex.lex()

View File

@ -0,0 +1,29 @@
# lex_ignore2.py
#
# ignore declaration as a raw string
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
t_ignore = r' \t'
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,25 @@
# lex_literal1.py
#
# Bad literal specification
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"NUMBER",
]
literals = ["+","-","**"]
def t_NUMBER(t):
r'\d+'
return t
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,25 @@
# lex_literal2.py
#
# Bad literal specification
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"NUMBER",
]
literals = 23
def t_NUMBER(t):
r'\d+'
return t
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,27 @@
# lex_many_tokens.py
#
# Test lex's ability to handle a large number of tokens (beyond the
# 100-group limit of the re module)
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = ["TOK%d" % i for i in range(1000)]
for tok in tokens:
if sys.version_info[0] < 3:
exec("t_%s = '%s:'" % (tok,tok))
else:
exec("t_%s = '%s:'" % (tok,tok), globals())
t_ignore = " \t"
def t_error(t):
pass
lex.lex(optimize=1,lextab="manytab")
lex.runmain(data="TOK34: TOK143: TOK269: TOK372: TOK452: TOK561: TOK999:")

View File

@ -0,0 +1,10 @@
# lex_module.py
#
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
import lex_module_import
lex.lex(module=lex_module_import)
lex.runmain(data="3+4")

View File

@ -0,0 +1,42 @@
# -----------------------------------------------------------------------------
# lex_module_import.py
#
# A lexer defined in a module, but built in lex_module.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 %s" % 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.lexer.skip(1)

View File

@ -0,0 +1,55 @@
# -----------------------------------------------------------------------------
# lex_object.py
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
class CalcLexer:
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(self,t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print("Integer value too large %s" % t.value)
t.value = 0
return t
t_ignore = " \t"
def t_newline(self,t):
r'\n+'
t.lineno += t.value.count("\n")
def t_error(self,t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
calc = CalcLexer()
# Build the lexer
lex.lex(object=calc)
lex.runmain(data="3+4")

View File

@ -0,0 +1,54 @@
# -----------------------------------------------------------------------------
# lex_opt_alias.py
#
# Tests ability to match up functions with states, aliases, and
# lexing tables.
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
tokens = (
'NAME','NUMBER',
)
states = (('instdef','inclusive'),('spam','exclusive'))
literals = ['=','+','-','*','/', '(',')']
# Tokens
def t_instdef_spam_BITS(t):
r'[01-]+'
return t
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
def NUMBER(t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print("Integer value too large %s" % t.value)
t.value = 0
return t
t_ANY_NUMBER = NUMBER
t_ignore = " \t"
t_spam_ignore = t_ignore
def t_newline(t):
r'\n+'
t.lexer.lineno += t.value.count("\n")
def t_error(t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
t_spam_error = t_error
# Build the lexer
import ply.lex as lex
lex.lex(optimize=1,lextab="aliastab")
lex.runmain(data="3+4")

View File

@ -0,0 +1,50 @@
# -----------------------------------------------------------------------------
# lex_optimize.py
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
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 %s" % 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.lexer.skip(1)
# Build the lexer
lex.lex(optimize=1)
lex.runmain(data="3+4")

View File

@ -0,0 +1,50 @@
# -----------------------------------------------------------------------------
# lex_optimize2.py
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
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 %s" % 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.lexer.skip(1)
# Build the lexer
lex.lex(optimize=1,lextab="opt2tab")
lex.runmain(data="3+4")

View File

@ -0,0 +1,52 @@
# -----------------------------------------------------------------------------
# lex_optimize3.py
#
# Writes table in a subdirectory structure.
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
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 %s" % 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.lexer.skip(1)
# Build the lexer
lex.lex(optimize=1,lextab="lexdir.sub.calctab",outputdir="lexdir/sub")
lex.runmain(data="3+4")

View File

@ -0,0 +1,27 @@
# lex_re1.py
#
# Bad regular expression in a string
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'(\d+'
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,27 @@
# lex_re2.py
#
# Regular expression rule matches empty string
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+?'
t_MINUS = r'-'
t_NUMBER = r'(\d+)'
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,29 @@
# lex_re3.py
#
# Regular expression rule matches empty string
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
"POUND",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'(\d+)'
t_POUND = r'#'
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,27 @@
# lex_rule1.py
#
# Rule function with incorrect number of arguments
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = 1
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,29 @@
# lex_rule2.py
#
# Rule function with incorrect number of arguments
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
def t_NUMBER():
r'\d+'
return t
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,27 @@
# lex_rule3.py
#
# Rule function with incorrect number of arguments
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
def t_NUMBER(t,s):
r'\d+'
return t
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,40 @@
# lex_state1.py
#
# Bad state declaration
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
states = 'comment'
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
# Comments
def t_comment(t):
r'/\*'
t.lexer.begin('comment')
print("Entering comment state")
def t_comment_body_part(t):
r'(.|\n)*\*/'
print("comment body %s" % t)
t.lexer.begin('INITIAL')
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,40 @@
# lex_state2.py
#
# Bad state declaration
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
states = ('comment','example')
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
# Comments
def t_comment(t):
r'/\*'
t.lexer.begin('comment')
print("Entering comment state")
def t_comment_body_part(t):
r'(.|\n)*\*/'
print("comment body %s" % t)
t.lexer.begin('INITIAL')
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,42 @@
# lex_state3.py
#
# Bad state declaration
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
comment = 1
states = ((comment, 'inclusive'),
('example', 'exclusive'))
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
# Comments
def t_comment(t):
r'/\*'
t.lexer.begin('comment')
print("Entering comment state")
def t_comment_body_part(t):
r'(.|\n)*\*/'
print("comment body %s" % t)
t.lexer.begin('INITIAL')
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,41 @@
# lex_state4.py
#
# Bad state declaration
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
states = (('comment', 'exclsive'),)
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
# Comments
def t_comment(t):
r'/\*'
t.lexer.begin('comment')
print("Entering comment state")
def t_comment_body_part(t):
r'(.|\n)*\*/'
print("comment body %s" % t)
t.lexer.begin('INITIAL')
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,40 @@
# lex_state5.py
#
# Bad state declaration
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
states = (('comment', 'exclusive'),
('comment', 'exclusive'))
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
# Comments
def t_comment(t):
r'/\*'
t.lexer.begin('comment')
print("Entering comment state")
def t_comment_body_part(t):
r'(.|\n)*\*/'
print("comment body %s" % t)
t.lexer.begin('INITIAL')
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,39 @@
# lex_state_noerror.py
#
# Declaration of a state for which no rules are defined
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
states = (('comment', 'exclusive'),)
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
# Comments
def t_comment(t):
r'/\*'
t.lexer.begin('comment')
print("Entering comment state")
def t_comment_body_part(t):
r'(.|\n)*\*/'
print("comment body %s" % t)
t.lexer.begin('INITIAL')
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,40 @@
# lex_state_norule.py
#
# Declaration of a state for which no rules are defined
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
states = (('comment', 'exclusive'),
('example', 'exclusive'))
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
# Comments
def t_comment(t):
r'/\*'
t.lexer.begin('comment')
print("Entering comment state")
def t_comment_body_part(t):
r'(.|\n)*\*/'
print("comment body %s" % t)
t.lexer.begin('INITIAL')
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,45 @@
# lex_state_try.py
#
# Declaration of a state for which no rules are defined
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
states = (('comment', 'exclusive'),)
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
t_ignore = " \t"
# Comments
def t_comment(t):
r'/\*'
t.lexer.begin('comment')
print("Entering comment state")
def t_comment_body_part(t):
r'(.|\n)*\*/'
print("comment body %s" % t)
t.lexer.begin('INITIAL')
def t_error(t):
pass
t_comment_error = t_error
t_comment_ignore = t_ignore
lex.lex()
data = "3 + 4 /* This is a comment */ + 10"
lex.runmain(data=data)

View File

@ -0,0 +1,19 @@
# lex_token1.py
#
# Tests for absence of tokens variable
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,22 @@
# lex_token2.py
#
# Tests for tokens of wrong type
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = "PLUS MINUS NUMBER"
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,24 @@
# lex_token3.py
#
# tokens is right type, but is missing a token for one rule
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,26 @@
# lex_token4.py
#
# Bad token name
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"-",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,31 @@
# lex_token5.py
#
# Return a bad token name
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as 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
lex.lex()
lex.input("1234")
t = lex.token()

View File

@ -0,0 +1,29 @@
# lex_token_dup.py
#
# Duplicate token name in tokens
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.lex as lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
"MINUS"
]
t_PLUS = r'\+'
t_MINUS = r'-'
def t_NUMBER(t):
r'\d+'
return t
def t_error(t):
pass
lex.lex()

View File

@ -0,0 +1,581 @@
# testlex.py
import unittest
try:
import StringIO
except ImportError:
import io as StringIO
import sys
sys.path.insert(0,"..")
sys.tracebacklimit = 0
import ply.lex
def check_expected(result,expected):
if sys.version_info[0] >= 3:
if isinstance(result,str):
result = result.encode('ascii')
if isinstance(expected,str):
expected = expected.encode('ascii')
resultlines = result.splitlines()
expectedlines = expected.splitlines()
if len(resultlines) != len(expectedlines):
return False
for rline,eline in zip(resultlines,expectedlines):
if not rline.endswith(eline):
return False
return True
def run_import(module):
code = "import "+module
exec(code)
del sys.modules[module]
# Tests related to errors and warnings when building lexers
class LexErrorWarningTests(unittest.TestCase):
def setUp(self):
sys.stderr = StringIO.StringIO()
sys.stdout = StringIO.StringIO()
def tearDown(self):
sys.stderr = sys.__stderr__
sys.stdout = sys.__stdout__
def test_lex_doc1(self):
self.assertRaises(SyntaxError,run_import,"lex_doc1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"lex_doc1.py:18: No regular expression defined for rule 't_NUMBER'\n"))
def test_lex_dup1(self):
self.assertRaises(SyntaxError,run_import,"lex_dup1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"lex_dup1.py:20: Rule t_NUMBER redefined. Previously defined on line 18\n" ))
def test_lex_dup2(self):
self.assertRaises(SyntaxError,run_import,"lex_dup2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"lex_dup2.py:22: Rule t_NUMBER redefined. Previously defined on line 18\n" ))
def test_lex_dup3(self):
self.assertRaises(SyntaxError,run_import,"lex_dup3")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"lex_dup3.py:20: Rule t_NUMBER redefined. Previously defined on line 18\n" ))
def test_lex_empty(self):
self.assertRaises(SyntaxError,run_import,"lex_empty")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"No rules of the form t_rulename are defined\n"
"No rules defined for state 'INITIAL'\n"))
def test_lex_error1(self):
run_import("lex_error1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"No t_error rule is defined\n"))
def test_lex_error2(self):
self.assertRaises(SyntaxError,run_import,"lex_error2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Rule 't_error' must be defined as a function\n")
)
def test_lex_error3(self):
self.assertRaises(SyntaxError,run_import,"lex_error3")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"lex_error3.py:20: Rule 't_error' requires an argument\n"))
def test_lex_error4(self):
self.assertRaises(SyntaxError,run_import,"lex_error4")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"lex_error4.py:20: Rule 't_error' has too many arguments\n"))
def test_lex_ignore(self):
self.assertRaises(SyntaxError,run_import,"lex_ignore")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"lex_ignore.py:20: Rule 't_ignore' must be defined as a string\n"))
def test_lex_ignore2(self):
run_import("lex_ignore2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"t_ignore contains a literal backslash '\\'\n"))
def test_lex_re1(self):
self.assertRaises(SyntaxError,run_import,"lex_re1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Invalid regular expression for rule 't_NUMBER'. unbalanced parenthesis\n"))
def test_lex_re2(self):
self.assertRaises(SyntaxError,run_import,"lex_re2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Regular expression for rule 't_PLUS' matches empty string\n"))
def test_lex_re3(self):
self.assertRaises(SyntaxError,run_import,"lex_re3")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Invalid regular expression for rule 't_POUND'. unbalanced parenthesis\n"
"Make sure '#' in rule 't_POUND' is escaped with '\\#'\n"))
def test_lex_rule1(self):
self.assertRaises(SyntaxError,run_import,"lex_rule1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"t_NUMBER not defined as a function or string\n"))
def test_lex_rule2(self):
self.assertRaises(SyntaxError,run_import,"lex_rule2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"lex_rule2.py:18: Rule 't_NUMBER' requires an argument\n"))
def test_lex_rule3(self):
self.assertRaises(SyntaxError,run_import,"lex_rule3")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"lex_rule3.py:18: Rule 't_NUMBER' has too many arguments\n"))
def test_lex_state1(self):
self.assertRaises(SyntaxError,run_import,"lex_state1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"states must be defined as a tuple or list\n"))
def test_lex_state2(self):
self.assertRaises(SyntaxError,run_import,"lex_state2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Invalid state specifier 'comment'. Must be a tuple (statename,'exclusive|inclusive')\n"
"Invalid state specifier 'example'. Must be a tuple (statename,'exclusive|inclusive')\n"))
def test_lex_state3(self):
self.assertRaises(SyntaxError,run_import,"lex_state3")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"State name 1 must be a string\n"
"No rules defined for state 'example'\n"))
def test_lex_state4(self):
self.assertRaises(SyntaxError,run_import,"lex_state4")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"State type for state comment must be 'inclusive' or 'exclusive'\n"))
def test_lex_state5(self):
self.assertRaises(SyntaxError,run_import,"lex_state5")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"State 'comment' already defined\n"))
def test_lex_state_noerror(self):
run_import("lex_state_noerror")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"No error rule is defined for exclusive state 'comment'\n"))
def test_lex_state_norule(self):
self.assertRaises(SyntaxError,run_import,"lex_state_norule")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"No rules defined for state 'example'\n"))
def test_lex_token1(self):
self.assertRaises(SyntaxError,run_import,"lex_token1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"No token list is defined\n"
"Rule 't_NUMBER' defined for an unspecified token NUMBER\n"
"Rule 't_PLUS' defined for an unspecified token PLUS\n"
"Rule 't_MINUS' defined for an unspecified token MINUS\n"
))
def test_lex_token2(self):
self.assertRaises(SyntaxError,run_import,"lex_token2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"tokens must be a list or tuple\n"
"Rule 't_NUMBER' defined for an unspecified token NUMBER\n"
"Rule 't_PLUS' defined for an unspecified token PLUS\n"
"Rule 't_MINUS' defined for an unspecified token MINUS\n"
))
def test_lex_token3(self):
self.assertRaises(SyntaxError,run_import,"lex_token3")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Rule 't_MINUS' defined for an unspecified token MINUS\n"))
def test_lex_token4(self):
self.assertRaises(SyntaxError,run_import,"lex_token4")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Bad token name '-'\n"))
def test_lex_token5(self):
try:
run_import("lex_token5")
except ply.lex.LexError:
e = sys.exc_info()[1]
self.assert_(check_expected(str(e),"lex_token5.py:19: Rule 't_NUMBER' returned an unknown token type 'NUM'"))
def test_lex_token_dup(self):
run_import("lex_token_dup")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Token 'MINUS' multiply defined\n"))
def test_lex_literal1(self):
self.assertRaises(SyntaxError,run_import,"lex_literal1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Invalid literal '**'. Must be a single character\n"))
def test_lex_literal2(self):
self.assertRaises(SyntaxError,run_import,"lex_literal2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Invalid literals specification. literals must be a sequence of characters\n"))
import os
import subprocess
import shutil
# Tests related to various build options associated with lexers
class LexBuildOptionTests(unittest.TestCase):
def setUp(self):
sys.stderr = StringIO.StringIO()
sys.stdout = StringIO.StringIO()
def tearDown(self):
sys.stderr = sys.__stderr__
sys.stdout = sys.__stdout__
try:
shutil.rmtree("lexdir")
except OSError:
pass
def test_lex_module(self):
run_import("lex_module")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
def test_lex_object(self):
run_import("lex_object")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
def test_lex_closure(self):
run_import("lex_closure")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
def test_lex_optimize(self):
try:
os.remove("lextab.py")
except OSError:
pass
try:
os.remove("lextab.pyc")
except OSError:
pass
try:
os.remove("lextab.pyo")
except OSError:
pass
run_import("lex_optimize")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("lextab.py"))
p = subprocess.Popen([sys.executable,'-O','lex_optimize.py'],
stdout=subprocess.PIPE)
result = p.stdout.read()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("lextab.pyo"))
os.remove("lextab.pyo")
p = subprocess.Popen([sys.executable,'-OO','lex_optimize.py'],
stdout=subprocess.PIPE)
result = p.stdout.read()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("lextab.pyo"))
try:
os.remove("lextab.py")
except OSError:
pass
try:
os.remove("lextab.pyc")
except OSError:
pass
try:
os.remove("lextab.pyo")
except OSError:
pass
def test_lex_optimize2(self):
try:
os.remove("opt2tab.py")
except OSError:
pass
try:
os.remove("opt2tab.pyc")
except OSError:
pass
try:
os.remove("opt2tab.pyo")
except OSError:
pass
run_import("lex_optimize2")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("opt2tab.py"))
p = subprocess.Popen([sys.executable,'-O','lex_optimize2.py'],
stdout=subprocess.PIPE)
result = p.stdout.read()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("opt2tab.pyo"))
os.remove("opt2tab.pyo")
p = subprocess.Popen([sys.executable,'-OO','lex_optimize2.py'],
stdout=subprocess.PIPE)
result = p.stdout.read()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("opt2tab.pyo"))
try:
os.remove("opt2tab.py")
except OSError:
pass
try:
os.remove("opt2tab.pyc")
except OSError:
pass
try:
os.remove("opt2tab.pyo")
except OSError:
pass
def test_lex_optimize3(self):
try:
shutil.rmtree("lexdir")
except OSError:
pass
os.mkdir("lexdir")
os.mkdir("lexdir/sub")
open("lexdir/__init__.py","w").write("")
open("lexdir/sub/__init__.py","w").write("")
run_import("lex_optimize3")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("lexdir/sub/calctab.py"))
p = subprocess.Popen([sys.executable,'-O','lex_optimize3.py'],
stdout=subprocess.PIPE)
result = p.stdout.read()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("lexdir/sub/calctab.pyo"))
os.remove("lexdir/sub/calctab.pyo")
p = subprocess.Popen([sys.executable,'-OO','lex_optimize3.py'],
stdout=subprocess.PIPE)
result = p.stdout.read()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(PLUS,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("lexdir/sub/calctab.pyo"))
try:
shutil.rmtree("lexdir")
except OSError:
pass
def test_lex_opt_alias(self):
try:
os.remove("aliastab.py")
except OSError:
pass
try:
os.remove("aliastab.pyc")
except OSError:
pass
try:
os.remove("aliastab.pyo")
except OSError:
pass
run_import("lex_opt_alias")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(+,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("aliastab.py"))
p = subprocess.Popen([sys.executable,'-O','lex_opt_alias.py'],
stdout=subprocess.PIPE)
result = p.stdout.read()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(+,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("aliastab.pyo"))
os.remove("aliastab.pyo")
p = subprocess.Popen([sys.executable,'-OO','lex_opt_alias.py'],
stdout=subprocess.PIPE)
result = p.stdout.read()
self.assert_(check_expected(result,
"(NUMBER,3,1,0)\n"
"(+,'+',1,1)\n"
"(NUMBER,4,1,2)\n"))
self.assert_(os.path.exists("aliastab.pyo"))
try:
os.remove("aliastab.py")
except OSError:
pass
try:
os.remove("aliastab.pyc")
except OSError:
pass
try:
os.remove("aliastab.pyo")
except OSError:
pass
def test_lex_many_tokens(self):
try:
os.remove("manytab.py")
except OSError:
pass
try:
os.remove("manytab.pyc")
except OSError:
pass
try:
os.remove("manytab.pyo")
except OSError:
pass
run_import("lex_many_tokens")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(TOK34,'TOK34:',1,0)\n"
"(TOK143,'TOK143:',1,7)\n"
"(TOK269,'TOK269:',1,15)\n"
"(TOK372,'TOK372:',1,23)\n"
"(TOK452,'TOK452:',1,31)\n"
"(TOK561,'TOK561:',1,39)\n"
"(TOK999,'TOK999:',1,47)\n"
))
self.assert_(os.path.exists("manytab.py"))
p = subprocess.Popen([sys.executable,'-O','lex_many_tokens.py'],
stdout=subprocess.PIPE)
result = p.stdout.read()
self.assert_(check_expected(result,
"(TOK34,'TOK34:',1,0)\n"
"(TOK143,'TOK143:',1,7)\n"
"(TOK269,'TOK269:',1,15)\n"
"(TOK372,'TOK372:',1,23)\n"
"(TOK452,'TOK452:',1,31)\n"
"(TOK561,'TOK561:',1,39)\n"
"(TOK999,'TOK999:',1,47)\n"
))
self.assert_(os.path.exists("manytab.pyo"))
os.remove("manytab.pyo")
try:
os.remove("manytab.py")
except OSError:
pass
try:
os.remove("manytab.pyc")
except OSError:
pass
try:
os.remove("manytab.pyo")
except OSError:
pass
# Tests related to run-time behavior of lexers
class LexRunTests(unittest.TestCase):
def setUp(self):
sys.stderr = StringIO.StringIO()
sys.stdout = StringIO.StringIO()
def tearDown(self):
sys.stderr = sys.__stderr__
sys.stdout = sys.__stdout__
def test_lex_hedit(self):
run_import("lex_hedit")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(H_EDIT_DESCRIPTOR,'abc',1,0)\n"
"(H_EDIT_DESCRIPTOR,'abcdefghij',1,6)\n"
"(H_EDIT_DESCRIPTOR,'xy',1,20)\n"))
def test_lex_state_try(self):
run_import("lex_state_try")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"(NUMBER,'3',1,0)\n"
"(PLUS,'+',1,2)\n"
"(NUMBER,'4',1,4)\n"
"Entering comment state\n"
"comment body LexToken(body_part,'This is a comment */',1,9)\n"
"(PLUS,'+',1,30)\n"
"(NUMBER,'10',1,32)\n"
))
unittest.main()

View File

@ -0,0 +1,324 @@
# testyacc.py
import unittest
try:
import StringIO
except ImportError:
import io as StringIO
import sys
import os
sys.path.insert(0,"..")
sys.tracebacklimit = 0
import ply.yacc
def check_expected(result,expected):
resultlines = []
for line in result.splitlines():
if line.startswith("WARNING: "):
line = line[9:]
elif line.startswith("ERROR: "):
line = line[7:]
resultlines.append(line)
expectedlines = expected.splitlines()
if len(resultlines) != len(expectedlines):
return False
for rline,eline in zip(resultlines,expectedlines):
if not rline.endswith(eline):
return False
return True
def run_import(module):
code = "import "+module
exec(code)
del sys.modules[module]
# Tests related to errors and warnings when building parsers
class YaccErrorWarningTests(unittest.TestCase):
def setUp(self):
sys.stderr = StringIO.StringIO()
sys.stdout = StringIO.StringIO()
try:
os.remove("parsetab.py")
os.remove("parsetab.pyc")
except OSError:
pass
def tearDown(self):
sys.stderr = sys.__stderr__
sys.stdout = sys.__stdout__
def test_yacc_badargs(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_badargs")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_badargs.py:23: Rule 'p_statement_assign' has too many arguments\n"
"yacc_badargs.py:27: Rule 'p_statement_expr' requires an argument\n"
))
def test_yacc_badid(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_badid")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_badid.py:32: Illegal name 'bad&rule' in rule 'statement'\n"
"yacc_badid.py:36: Illegal rule name 'bad&rule'\n"
))
def test_yacc_badprec(self):
try:
run_import("yacc_badprec")
except ply.yacc.YaccError:
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"precedence must be a list or tuple\n"
))
def test_yacc_badprec2(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_badprec2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Bad precedence table\n"
))
def test_yacc_badprec3(self):
run_import("yacc_badprec3")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Precedence already specified for terminal 'MINUS'\n"
"Generating LALR tables\n"
))
def test_yacc_badrule(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_badrule")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_badrule.py:24: Syntax error. Expected ':'\n"
"yacc_badrule.py:28: Syntax error in rule 'statement'\n"
"yacc_badrule.py:33: Syntax error. Expected ':'\n"
"yacc_badrule.py:42: Syntax error. Expected ':'\n"
))
def test_yacc_badtok(self):
try:
run_import("yacc_badtok")
except ply.yacc.YaccError:
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"tokens must be a list or tuple\n"))
def test_yacc_dup(self):
run_import("yacc_dup")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_dup.py:27: Function p_statement redefined. Previously defined on line 23\n"
"Token 'EQUALS' defined, but not used\n"
"There is 1 unused token\n"
"Generating LALR tables\n"
))
def test_yacc_error1(self):
try:
run_import("yacc_error1")
except ply.yacc.YaccError:
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_error1.py:61: p_error() requires 1 argument\n"))
def test_yacc_error2(self):
try:
run_import("yacc_error2")
except ply.yacc.YaccError:
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_error2.py:61: p_error() requires 1 argument\n"))
def test_yacc_error3(self):
try:
run_import("yacc_error3")
except ply.yacc.YaccError:
e = sys.exc_info()[1]
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"'p_error' defined, but is not a function or method\n"))
def test_yacc_error4(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_error4")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_error4.py:62: Illegal rule name 'error'. Already defined as a token\n"
))
def test_yacc_inf(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_inf")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Token 'NUMBER' defined, but not used\n"
"There is 1 unused token\n"
"Infinite recursion detected for symbol 'statement'\n"
"Infinite recursion detected for symbol 'expression'\n"
))
def test_yacc_literal(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_literal")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_literal.py:36: Literal token '**' in rule 'expression' may only be a single character\n"
))
def test_yacc_misplaced(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_misplaced")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_misplaced.py:32: Misplaced '|'\n"
))
def test_yacc_missing1(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_missing1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_missing1.py:24: Symbol 'location' used, but not defined as a token or a rule\n"
))
def test_yacc_nested(self):
run_import("yacc_nested")
result = sys.stdout.getvalue()
self.assert_(check_expected(result,
"A\n"
"A\n"
"A\n",
))
def test_yacc_nodoc(self):
run_import("yacc_nodoc")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_nodoc.py:27: No documentation string specified in function 'p_statement_expr' (ignored)\n"
"Generating LALR tables\n"
))
def test_yacc_noerror(self):
run_import("yacc_noerror")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"no p_error() function is defined\n"
"Generating LALR tables\n"
))
def test_yacc_nop(self):
run_import("yacc_nop")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_nop.py:27: Possible grammar rule 'statement_expr' defined without p_ prefix\n"
"Generating LALR tables\n"
))
def test_yacc_notfunc(self):
run_import("yacc_notfunc")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"'p_statement_assign' not defined as a function\n"
"Token 'EQUALS' defined, but not used\n"
"There is 1 unused token\n"
"Generating LALR tables\n"
))
def test_yacc_notok(self):
try:
run_import("yacc_notok")
except ply.yacc.YaccError:
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"No token list is defined\n"))
def test_yacc_rr(self):
run_import("yacc_rr")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Generating LALR tables\n"
"1 reduce/reduce conflict\n"
"reduce/reduce conflict in state 15 resolved using rule (statement -> NAME EQUALS NUMBER)\n"
"rejected rule (expression -> NUMBER) in state 15\n"
))
def test_yacc_rr_unused(self):
run_import("yacc_rr_unused")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"no p_error() function is defined\n"
"Generating LALR tables\n"
"3 reduce/reduce conflicts\n"
"reduce/reduce conflict in state 1 resolved using rule (rule3 -> A)\n"
"rejected rule (rule4 -> A) in state 1\n"
"reduce/reduce conflict in state 1 resolved using rule (rule3 -> A)\n"
"rejected rule (rule5 -> A) in state 1\n"
"reduce/reduce conflict in state 1 resolved using rule (rule4 -> A)\n"
"rejected rule (rule5 -> A) in state 1\n"
"Rule (rule5 -> A) is never reduced\n"
))
def test_yacc_simple(self):
run_import("yacc_simple")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Generating LALR tables\n"
))
def test_yacc_sr(self):
run_import("yacc_sr")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Generating LALR tables\n"
"20 shift/reduce conflicts\n"
))
def test_yacc_term1(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_term1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_term1.py:24: Illegal rule name 'NUMBER'. Already defined as a token\n"
))
def test_yacc_unused(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_unused")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_unused.py:62: Symbol 'COMMA' used, but not defined as a token or a rule\n"
"Symbol 'COMMA' is unreachable\n"
"Symbol 'exprlist' is unreachable\n"
))
def test_yacc_unused_rule(self):
run_import("yacc_unused_rule")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_unused_rule.py:62: Rule 'integer' defined, but not used\n"
"There is 1 unused rule\n"
"Symbol 'integer' is unreachable\n"
"Generating LALR tables\n"
))
def test_yacc_uprec(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_uprec")
result = sys.stderr.getvalue()
print repr(result)
self.assert_(check_expected(result,
"yacc_uprec.py:37: Nothing known about the precedence of 'UMINUS'\n"
))
def test_yacc_uprec2(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_uprec2")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"yacc_uprec2.py:37: Syntax error. Nothing follows %prec\n"
))
def test_yacc_prec1(self):
self.assertRaises(ply.yacc.YaccError,run_import,"yacc_prec1")
result = sys.stderr.getvalue()
self.assert_(check_expected(result,
"Precedence rule 'left' defined for unknown symbol '+'\n"
"Precedence rule 'left' defined for unknown symbol '*'\n"
"Precedence rule 'left' defined for unknown symbol '-'\n"
"Precedence rule 'left' defined for unknown symbol '/'\n"
))
unittest.main()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_badargs.py
#
# Rules with wrong # args
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,77 @@
# -----------------------------------------------------------------------------
# yacc_badid.py
#
# Attempt to define a rule with a bad-identifier name
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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_statement_expr2(t):
'statement : bad&rule'
pass
def p_badrule(t):
'bad&rule : expression'
pass
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[2] == '/': 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):
pass
yacc.yacc()

View File

@ -0,0 +1,64 @@
# -----------------------------------------------------------------------------
# yacc_badprec.py
#
# Bad precedence specifier
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_badprec2.py
#
# Bad precedence
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_badprec3.py
#
# Bad precedence
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
from calclex import tokens
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE','MINUS'),
('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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_badrule.py
#
# Syntax problems in the rule strings
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_badtok.py
#
# A grammar, but tokens is a bad datatype
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_dup.py
#
# Duplicated rule name
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_error1.py
#
# Bad p_error() function
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_error2.py
#
# Bad p_error() function
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_error3.py
#
# Bad p_error() function
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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"
yacc.yacc()

View File

@ -0,0 +1,72 @@
# -----------------------------------------------------------------------------
# yacc_error4.py
#
# Attempt to define a rule named 'error'
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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_handler(t):
'error : NAME'
pass
def p_error(t):
pass
yacc.yacc()

View File

@ -0,0 +1,56 @@
# -----------------------------------------------------------------------------
# yacc_inf.py
#
# Infinite recursion
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,69 @@
# -----------------------------------------------------------------------------
# yacc_literal.py
#
# Grammar with bad literal characters
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
from calclex import tokens
# Parsing rules
precedence = (
('left','+','-'),
('left','*','/'),
('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 '+' expression
| expression '-' expression
| expression '*' expression
| expression '/' expression
| expression '**' 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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_misplaced.py
#
# A misplaced | in grammar rules
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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 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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_missing1.py
#
# Grammar with a missing rule
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,33 @@
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
from ply import lex, yacc
t_A = 'A'
t_B = 'B'
t_C = 'C'
tokens = ('A', 'B', 'C')
the_lexer = lex.lex()
def t_error(t):
pass
def p_error(p):
pass
def p_start(t):
'''start : A nest C'''
pass
def p_nest(t):
'''nest : B'''
print(t[-1])
the_parser = yacc.yacc(debug = False, write_tables = False)
the_parser.parse('ABC', the_lexer)
the_parser.parse('ABC', the_lexer, tracking=True)
the_parser.parse('ABC', the_lexer, tracking=True, debug=1)

View File

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_nodoc.py
#
# Rule with a missing doc-string
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,66 @@
# -----------------------------------------------------------------------------
# yacc_noerror.py
#
# No p_error() rule defined.
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_nop.py
#
# Possible grammar rule defined without p_ prefix
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,66 @@
# -----------------------------------------------------------------------------
# yacc_notfunc.py
#
# p_rule not defined as a function
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_notok.py
#
# A grammar, but we forgot to import the tokens list
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
# 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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_prec1.py
#
# Tests case where precedence specifier doesn't match up to terminals
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
from calclex import tokens
# Parsing rules
precedence = (
('left','+','-'),
('left','*','/'),
('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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,72 @@
# -----------------------------------------------------------------------------
# yacc_rr.py
#
# A grammar with a reduce/reduce conflict
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,30 @@
# -----------------------------------------------------------------------------
# yacc_rr_unused.py
#
# A grammar with reduce/reduce conflicts and a rule that never
# gets reduced.
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
tokens = ('A', 'B', 'C')
def p_grammar(p):
'''
rule1 : rule2 B
| rule2 C
rule2 : rule3 B
| rule4
| rule5
rule3 : A
rule4 : A
rule5 : A
'''
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_simple.py
#
# A simple, properly specifier grammar
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,63 @@
# -----------------------------------------------------------------------------
# yacc_sr.py
#
# A grammar with shift-reduce conflicts
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_term1.py
#
# Terminal used on the left-hand-side
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,77 @@
# -----------------------------------------------------------------------------
# yacc_unused.py
#
# A grammar with an unused rule
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,72 @@
# -----------------------------------------------------------------------------
# yacc_unused_rule.py
#
# Grammar with an unused rule
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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_integer(t):
'integer : NUMBER'
t[0] = t[1]
def p_error(t):
print("Syntax error at '%s'" % t.value)
yacc.yacc()

View File

@ -0,0 +1,63 @@
# -----------------------------------------------------------------------------
# yacc_uprec.py
#
# A grammar with a bad %prec specifier
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': 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)
yacc.yacc()

View File

@ -0,0 +1,63 @@
# -----------------------------------------------------------------------------
# yacc_uprec2.py
#
# A grammar with a bad %prec specifier
# -----------------------------------------------------------------------------
import sys
if ".." not in sys.path: sys.path.insert(0,"..")
import ply.yacc as yacc
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[2] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec'
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)
yacc.yacc()