# $Id: kfbparser.py 49507964ae64 2010-03-27 mtnyogi $
# coding=utf-8
#
# Copyright 2008 Bruce Frederiksen
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
""" See http://www.dabeaz.com/ply/ply.html for syntax of grammer definitions.
"""
from __future__ import with_statement
import os, os.path
from pyke.krb_compiler.ply import yacc
from pyke.krb_compiler import scanner
from pyke import fact_base
tokens = scanner.kfb_tokens
def p_file(p):
''' file : nl_opt facts_opt
facts_opt :
facts_opt : facts nl_opt
facts : fact
facts : facts NL_TOK fact
'''
pass
def p_fact0(p):
''' fact : IDENTIFIER_TOK LP_TOK RP_TOK '''
Fact_base.add_universal_fact(p[1], ())
def p_fact1(p):
''' fact : IDENTIFIER_TOK LP_TOK data_list RP_TOK '''
Fact_base.add_universal_fact(p[1], tuple(p[3]))
def p_none(p):
''' data : NONE_TOK
comma_opt :
comma_opt : ','
nl_opt :
nl_opt : NL_TOK
'''
p[0] = None
def p_number(p):
''' data : NUMBER_TOK
'''
p[0] = p[1]
def p_string(p):
''' data : STRING_TOK
'''
p[0] = eval(p[1])
def p_quoted_last(p):
''' data : IDENTIFIER_TOK
'''
p[0] = p[1]
def p_false(p):
''' data : FALSE_TOK
'''
p[0] = False
def p_true(p):
''' data : TRUE_TOK
'''
p[0] = True
def p_empty_tuple(p):
''' data : LP_TOK RP_TOK
'''
p[0] = ()
def p_start_list(p):
''' data_list : data
'''
p[0] = [p[1]]
def p_append_list(p):
''' data_list : data_list ',' data
'''
p[1].append(p[len(p)-1])
p[0] = p[1]
def p_tuple(p):
''' data : LP_TOK data_list comma_opt RP_TOK '''
p[0] = tuple(p[2])
def p_error(t):
if t is None:
raise SyntaxError("invalid syntax", scanner.syntaxerror_params())
else:
raise SyntaxError("invalid syntax",
scanner.syntaxerror_params(t.lexpos, t.lineno))
parser = None
def init(this_module, check_tables = False, debug = 0):
global parser
if parser is None:
outputdir = os.path.dirname(this_module.__file__)
if debug:
parser = yacc.yacc(module=this_module, write_tables=0,
debug=debug, debugfile='kfbparser.yacc.out',
outputdir=outputdir)
else:
if check_tables:
kfbparser_mtime = os.path.getmtime(this_module.__file__)
tables_name = os.path.join(outputdir, 'kfbparser_tables.py')
try:
ok = os.path.getmtime(tables_name) >= kfbparser_mtime
except OSError:
ok = False
if not ok:
#print "regenerating kfbparser_tables"
try: os.remove(tables_name)
except OSError: pass
try: os.remove(tables_name + 'c')
except OSError: pass
try: os.remove(tables_name + 'o')
except OSError: pass
parser = yacc.yacc(module=this_module, debug=0,
optimize=1, write_tables=1,
tabmodule='pyke.krb_compiler.kfbparser_tables',
outputdir=outputdir)
# Use the first line for normal use, the second for testing changes in the
# grammer (the first line does not report grammer errors!).
def parse(this_module, filename, check_tables = False, debug = 0):
#def parse(this_module, filename, check_tables = False, debug = 1):
'''
>>> from pyke.krb_compiler import kfbparser
>>> kfbparser.parse(kfbparser,
... os.path.join(os.path.dirname(__file__),
... 'TEST/kfbparse_test.kfb'),
... True)
<fact_base kfbparse_test>
'''
global Fact_base
init(this_module, check_tables, debug)
name = os.path.basename(filename)[:-4]
Fact_base = fact_base.fact_base(None, name, False)
with open(filename) as f:
scanner.init(scanner, debug, check_tables, True)
scanner.lexer.lineno = 1
scanner.lexer.filename = filename
#parser.restart()
parser.parse(f.read(), lexer=scanner.lexer, tracking=True, debug=debug)
ans = Fact_base
Fact_base = None
return ans
|