Some small grammar changes for 2.7.

This commit is contained in:
Dave Halter
2017-07-13 08:44:25 +02:00
parent a647ee1f44
commit d1d019b3c0
2 changed files with 20 additions and 24 deletions

View File

@@ -329,8 +329,8 @@ class ParserGenerator(object):
msg = msg % args msg = msg % args
except: except:
msg = " ".join([msg] + list(map(str, args))) msg = " ".join([msg] + list(map(str, args)))
line = open(self.filename).readlines()[self.begin[0]] line = self._bnf_text.splitlines()[self.begin[0] - 1]
raise SyntaxError(msg, (self.filename, self.begin[0], raise SyntaxError(msg, ('<grammar>', self.begin[0],
self.begin[1], line)) self.begin[1], line))

View File

@@ -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 # Note: Changing the grammar specified in this file will most likely
# require corresponding changes in the parser module # require corresponding changes in the parser module
@@ -10,14 +10,13 @@
# NOTE WELL: You should also follow all the steps listed in PEP 306, # NOTE WELL: You should also follow all the steps listed in PEP 306,
# "How to Change Python's Grammar" # "How to Change Python's Grammar"
# Start symbols for the 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;
# 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. # eval_input is the input for the eval() and input() functions.
# NB: compound_stmt in single_input is followed by extra NEWLINE! # NB: compound_stmt in single_input is followed by extra NEWLINE!
file_input: (NEWLINE | stmt)* ENDMARKER
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
file_input: (NEWLINE | stmt)* ENDMARKER
eval_input: testlist NEWLINE* ENDMARKER eval_input: testlist NEWLINE* ENDMARKER
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
@@ -26,8 +25,8 @@ decorated: decorators (classdef | funcdef)
funcdef: 'def' NAME parameters ':' suite funcdef: 'def' NAME parameters ':' suite
parameters: '(' [varargslist] ')' parameters: '(' [varargslist] ')'
varargslist: ((fpdef ['=' test] ',')* varargslist: ((fpdef ['=' test] ',')*
('*' [NAME] (',' NAME ['=' test])* [',' '**' NAME] | '**' NAME) ('*' NAME [',' '**' NAME] | '**' NAME) |
| fpdef ['=' test] (',' fpdef ['=' test])* [',']) fpdef ['=' test] (',' fpdef ['=' test])* [','])
fpdef: NAME | '(' fplist ')' fpdef: NAME | '(' fplist ')'
fplist: fpdef (',' fpdef)* [','] fplist: fpdef (',' fpdef)* [',']
@@ -52,8 +51,7 @@ yield_stmt: yield_expr
raise_stmt: 'raise' [test [',' test [',' test]]] raise_stmt: 'raise' [test [',' test [',' test]]]
import_stmt: import_name | import_from import_stmt: import_name | import_from
import_name: 'import' dotted_as_names 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' ('*' | '(' import_as_names ')' | import_as_names))
import_as_name: NAME ['as' NAME] import_as_name: NAME ['as' NAME]
dotted_as_name: dotted_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] for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
try_stmt: ('try' ':' suite try_stmt: ('try' ':' suite
((except_clause ':' suite)+ ((except_clause ':' suite)+
['else' ':' suite] ['else' ':' suite]
['finally' ':' suite] | ['finally' ':' suite] |
'finally' ':' suite)) 'finally' ':' suite))
with_stmt: 'with' with_item (',' with_item)* ':' suite with_stmt: 'with' with_item (',' with_item)* ':' suite
with_item: test ['as' expr] with_item: test ['as' expr]
with_var: 'as' expr
# NB compile.c makes sure that the default except clause is last # 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 # 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. # classes and functions to be empty, which is beneficial for autocompletion.
suite: simple_stmt | NEWLINE INDENT stmt* DEDENT suite: simple_stmt | NEWLINE INDENT stmt* DEDENT
@@ -109,27 +106,26 @@ atom: ('(' [yield_expr|testlist_comp] ')' |
'[' [testlist_comp] ']' | '[' [testlist_comp] ']' |
'{' [dictorsetmaker] '}' | '{' [dictorsetmaker] '}' |
'`' testlist1 '`' | '`' testlist1 '`' |
NAME | NUMBER | STRING+ | '.' '.' '.') NAME | NUMBER | STRING+)
# Modification by David Halter, remove `testlist_gexp` and `listmaker`
testlist_comp: test ( comp_for | (',' test)* [','] ) testlist_comp: test ( comp_for | (',' test)* [','] )
lambdef: 'lambda' [varargslist] ':' test lambdef: 'lambda' [varargslist] ':' test
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
subscriptlist: subscript (',' subscript)* [','] subscriptlist: subscript (',' subscript)* [',']
subscript: test | [test] ':' [test] [sliceop] subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
sliceop: ':' [test] sliceop: ':' [test]
exprlist: expr (',' expr)* [','] exprlist: expr (',' expr)* [',']
testlist: test (',' test)* [','] 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)* [','])) | dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
(test (comp_for | (',' test)* [','])) ) (test (comp_for | (',' test)* [','])) )
classdef: 'class' NAME ['(' [testlist] ')'] ':' suite classdef: 'class' NAME ['(' [testlist] ')'] ':' suite
arglist: (argument ',')* (argument [','] arglist: (argument ',')* (argument [',']
|'*' test (',' argument)* [',' '**' test] |'*' test (',' argument)* [',' '**' test]
|'**' 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_iter: comp_for | comp_if
comp_for: 'for' exprlist 'in' testlist_safe [comp_iter] comp_for: 'for' exprlist 'in' testlist_safe [comp_iter]