diff -r fd4f6cd954a7 -r 729ce7f31462 src/arch/isa_parser.py --- a/src/arch/isa_parser.py Tue May 24 10:15:21 2011 -0700 +++ b/src/arch/isa_parser.py Tue May 24 10:15:32 2011 -0700 @@ -2046,7 +2046,7 @@ # Parse it. (isa_name, namespace, global_code, namespace_code) = \ - self.parse(isa_desc) + self.parse_string(isa_desc) # grab the last three path components of isa_desc_file to put in # the output diff -r fd4f6cd954a7 -r 729ce7f31462 src/mem/slicc/ast/AST.py --- a/src/mem/slicc/ast/AST.py Tue May 24 10:15:21 2011 -0700 +++ b/src/mem/slicc/ast/AST.py Tue May 24 10:15:32 2011 -0700 @@ -30,7 +30,7 @@ class AST(PairContainer): def __init__(self, slicc, pairs=None): self.slicc = slicc - self.location = Location(slicc.current_file, slicc.lexer.lineno) + self.location = Location(slicc.current_source, slicc.current_line) self.pairs = {} if pairs: self.pairs.update(getattr(pairs, "pairs", pairs)) diff -r fd4f6cd954a7 -r 729ce7f31462 src/mem/slicc/parser.py --- a/src/mem/slicc/parser.py Tue May 24 10:15:21 2011 -0700 +++ b/src/mem/slicc/parser.py Tue May 24 10:15:32 2011 -0700 @@ -31,7 +31,7 @@ import sys from m5.util import code_formatter -from m5.util.grammar import Grammar, TokenError, ParseError +from m5.util.grammar import Grammar, ParseError import slicc.ast as ast import slicc.util as util @@ -52,9 +52,7 @@ class SLICC(Grammar): def __init__(self, protocol, **kwargs): - super(SLICC, self).__init__(**kwargs) self.decl_list_vec = [] - self.current_file = None self.protocol = protocol self.symtab = SymbolTable(self) @@ -64,15 +62,11 @@ return code def parse(self, filename): - self.current_file = filename - f = file(filename, 'r') - text = f.read() try: - decl_list = super(SLICC, self).parse(text) - except (TokenError, ParseError), e: - sys.exit("%s: %s:%d" % (e, filename, e.token.lineno)) + decl_list = self.parse_file(filename) + except ParseError, e: + sys.exit(str(e)) self.decl_list_vec.append(decl_list) - self.current_file = None def _load(self, *filenames): filenames = list(filenames) @@ -238,7 +232,7 @@ try: t.value = float(t.value) except ValueError: - raise TokenError("Illegal float", t) + raise ParseError("Illegal float", t) return t def t_NUMBER(self, t): @@ -246,7 +240,7 @@ try: t.value = int(t.value) except ValueError: - raise TokenError("Illegal number", t) + raise ParseError("Illegal number", t) return t def t_STRING1(self, t): diff -r fd4f6cd954a7 -r 729ce7f31462 src/python/m5/util/grammar.py --- a/src/python/m5/util/grammar.py Tue May 24 10:15:21 2011 -0700 +++ b/src/python/m5/util/grammar.py Tue May 24 10:15:32 2011 -0700 @@ -1,4 +1,4 @@ -# Copyright (c) 2006-2009 Nathan Binkert +# Copyright (c) 2006-2011 Nathan Binkert # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -24,100 +24,116 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from ply import lex, yacc +import os -class TokenError(lex.LexError): - def __init__(self, msg, t): - super(TokenError, self).__init__(msg) - self.token = t +import ply.lex +import ply.yacc -class ParseError(yacc.YaccError): +class ParseError(Exception): def __init__(self, message, token=None): - super(ParseError, self).__init__(message) + Exception.__init__(self, message) self.token = token -class Tokenizer(object): - def __init__(self, lexer, data): - if isinstance(data, basestring): - indata = [ data ] - elif isinstance(data, file): - indata = data.xreadlines() - else: - indata = data +class Grammar(object): + def setupLexerFactory(self, **kwargs): + if 'module' in kwargs: + raise AttributeError, "module is an illegal attribute" + self.lex_kwargs = kwargs - def _input(): - for i,line in enumerate(indata): - lexer.lineno = i + 1 - lexer.input(line) - while True: - tok = lexer.token() - if not tok: - break - yield tok - self.input = _input() - self.lexer = lexer + def setupParserFactory(self, **kwargs): + if 'module' in kwargs: + raise AttributeError, "module is an illegal attribute" - def next(self): - return self.input.next() + if 'output' in kwargs: + dir,tab = os.path.split(output) + if not tab.endswith('.py'): + raise AttributeError, \ + 'The output file must end with .py' + kwargs['outputdir'] = dir + kwargs['tabmodule'] = tab[:-3] - def __iter__(self): - return self - - def token(self): - try: - return self.next() - except StopIteration: - return None + self.yacc_kwargs = kwargs def __getattr__(self, attr): - return getattr(self.lexer, attr) + if attr == 'lexers': + self.lexers = [] + return self.lexers -class Grammar(object): - def __init__(self, output=None, debug=False): - self.yacc_args = {} - self.yacc_args['debug'] = debug + if attr == 'lex_kwargs': + self.setupLexerFactory() + return self.lex_kwargs - if output: - import os + if attr == 'yacc_kwargs': + self.setupParserFactory() + return self.yacc_kwargs - dir,tab = os.path.split(output) - if not tab.endswith('.py'): - raise AttributeError, 'The output file must end with .py' - self.yacc_args['outputdir'] = dir - self.yacc_args['tabmodule'] = tab[:-3] + if attr == 'lex': + self.lex = ply.lex.lex(module=self, **self.lex_kwargs) + return self.lex - def t_error(self, t): - raise lex.LexError("Illegal character %s @ %d:%d" % \ - (`t.value[0]`, t.lineno, t.lexpos), `t.value[0]`) + if attr == 'yacc': + self.yacc = ply.yacc.yacc(module=self, **self.yacc_kwargs) + return self.yacc + + if attr == 'current_lexer': + if not self.lexers: + return None + return self.lexers[-1][0] + + if attr == 'current_source': + if not self.lexers: + return '' + return self.lexers[-1][1] + + if attr == 'current_line': + if not self.lexers: + return -1 + return self.current_lexer.lineno + + raise AttributeError, \ + "'%s' object has no attribute '%s'" % (type(self), attr) + + def parse_string(self, data, source='', debug=None, tracking=0): + if not isinstance(data, basestring): + raise AttributeError, \ + "argument must be a string, was '%s'" % type(f) + + import new + lexer = self.lex.clone() + lexer.input(data) + self.lexers.append((lexer, source)) + dict = { + 'productions' : self.yacc.productions, + 'action' : self.yacc.action, + 'goto' : self.yacc.goto, + 'errorfunc' : self.yacc.errorfunc, + } + parser = new.instance(ply.yacc.LRParser, dict) + result = parser.parse(lexer=lexer, debug=debug, tracking=tracking) + self.lexers.pop() + return result + + def parse_file(self, f, **kwargs): + if isinstance(f, basestring): + source = f + f = file(f, 'r') + elif isinstance(f, file): + source = f.name + else: + raise AttributeError, \ + "argument must be either a string or file, was '%s'" % type(f) + + return self.parse_string(f.read(), source, **kwargs) def p_error(self, t): if t: - msg = "Syntax error at %d:%d\n>>%s<<" % \ - (t.lineno, t.lexpos + 1, t.value) + msg = "Syntax error at %s:%d:%d\n>>%s<<" % \ + (self.current_source, t.lineno, t.lexpos + 1, t.value) else: - msg = "Syntax error at end of input" + msg = "Syntax error at end of %s" % (self.current_source, ) raise ParseError(msg, t) - def __getattr__(self, attr): - if attr == 'parser': - import ply.yacc - parser = ply.yacc.yacc(module=self, **self.yacc_args) - self.parser = parser - return parser - - if attr == 'lexer': - import ply.lex - lexer = ply.lex.lex(module=self) - self.lexer = lexer - return lexer - - raise AttributeError, "'%s' object has no attribute '%s'" % \ - (self.__class__.__name__, attr) - - def parse(self, stmt, **kwargs): - self.lexer.lineno = 1 - result = self.parser.parse(lexer=Tokenizer(self.lexer, stmt), **kwargs) - self.parser.restart() - - return result - + def t_error(self, t): + msg = "Illegal character %s @ %d:%d" % \ + (`t.value[0]`, t.lineno, t.lexpos) + raise ParseError(msg, t)