diff --git a/parso/pgen2/pgen.py b/parso/pgen2/pgen.py index 75bd2ea..7310359 100644 --- a/parso/pgen2/pgen.py +++ b/parso/pgen2/pgen.py @@ -329,8 +329,8 @@ class ParserGenerator(object): msg = msg % args except: msg = " ".join([msg] + list(map(str, args))) - line = open(self.filename).readlines()[self.begin[0]] - raise SyntaxError(msg, (self.filename, self.begin[0], + line = self._bnf_text.splitlines()[self.begin[0] - 1] + raise SyntaxError(msg, ('', self.begin[0], self.begin[1], line)) diff --git a/parso/python/grammar27.txt b/parso/python/grammar27.txt index f82ef2a..0f7ed6f 100644 --- a/parso/python/grammar27.txt +++ b/parso/python/grammar27.txt @@ -1,4 +1,4 @@ -# Grammar for 2to3. This grammar supports Python 2.x and 3.x. +# Grammar for Python # Note: Changing the grammar specified in this file will most likely # require corresponding changes in the parser module @@ -10,14 +10,13 @@ # NOTE WELL: You should also follow all the steps listed in PEP 306, # "How to Change Python's Grammar" - # Start symbols for the grammar: -# file_input is a module or sequence of commands read from an input file; -# single_input is a single interactive statement; -# eval_input is the input for the eval() and input() functions. +# single_input is a single interactive statement; +# file_input is a module or sequence of commands read from an input file; +# eval_input is the input for the eval() and input() functions. # NB: compound_stmt in single_input is followed by extra NEWLINE! -file_input: (NEWLINE | stmt)* ENDMARKER single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE +file_input: (NEWLINE | stmt)* ENDMARKER eval_input: testlist NEWLINE* ENDMARKER decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE @@ -26,8 +25,8 @@ decorated: decorators (classdef | funcdef) funcdef: 'def' NAME parameters ':' suite parameters: '(' [varargslist] ')' varargslist: ((fpdef ['=' test] ',')* - ('*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME) - | fpdef ['=' test] (',' fpdef ['=' test])* [',']) + ('*' NAME [',' '**' NAME] | '**' NAME) | + fpdef ['=' test] (',' fpdef ['=' test])* [',']) fpdef: NAME | '(' fplist ')' fplist: fpdef (',' fpdef)* [','] @@ -52,8 +51,7 @@ yield_stmt: yield_expr raise_stmt: 'raise' [test [',' test [',' test]]] import_stmt: import_name | import_from import_name: 'import' dotted_as_names -# note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS -import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+) +import_from: ('from' ('.'* dotted_name | '.'+) 'import' ('*' | '(' import_as_names ')' | import_as_names)) import_as_name: NAME ['as' NAME] dotted_as_name: dotted_name ['as' NAME] @@ -70,14 +68,13 @@ while_stmt: 'while' test ':' suite ['else' ':' suite] for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] try_stmt: ('try' ':' suite ((except_clause ':' suite)+ - ['else' ':' suite] - ['finally' ':' suite] | - 'finally' ':' suite)) + ['else' ':' suite] + ['finally' ':' suite] | + 'finally' ':' suite)) with_stmt: 'with' with_item (',' with_item)* ':' suite with_item: test ['as' expr] -with_var: 'as' expr # NB compile.c makes sure that the default except clause is last -except_clause: 'except' [test [(',' | 'as') test]] +except_clause: 'except' [test [('as' | ',') test]] # Edit by David Halter: The stmt is now optional. This reflects how Jedi allows # classes and functions to be empty, which is beneficial for autocompletion. suite: simple_stmt | NEWLINE INDENT stmt* DEDENT @@ -109,27 +106,26 @@ atom: ('(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | '`' testlist1 '`' | - NAME | NUMBER | STRING+ | '.' '.' '.') -# Modification by David Halter, remove `testlist_gexp` and `listmaker` + NAME | NUMBER | STRING+) testlist_comp: test ( comp_for | (',' test)* [','] ) lambdef: 'lambda' [varargslist] ':' test trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] -subscript: test | [test] ':' [test] [sliceop] +subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop] sliceop: ':' [test] exprlist: expr (',' expr)* [','] testlist: test (',' test)* [','] -# Modification by David Halter, dictsetmaker -> dictorsetmaker (so that it's -# the same as in the 3.4 grammar). dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | - (test (comp_for | (',' test)* [','])) ) + (test (comp_for | (',' test)* [','])) ) classdef: 'class' NAME ['(' [testlist] ')'] ':' suite arglist: (argument ',')* (argument [','] |'*' test (',' argument)* [',' '**' test] |'**' test) -argument: test [comp_for] | test '=' test # Really [keyword '='] test +# The reason that keywords are test nodes instead of NAME is that using NAME +# results in an ambiguity. ast.c makes sure it's a NAME. +argument: test [comp_for] | test '=' test comp_iter: comp_for | comp_if comp_for: 'for' exprlist 'in' testlist_safe [comp_iter]