Initial commit with python grammar and parser files.
This commit is contained in:
parent
b8dab2a2c4
commit
aaadba738c
3 changed files with 826 additions and 0 deletions
677
Python.grako
Normal file
677
Python.grako
Normal file
|
|
@ -0,0 +1,677 @@
|
||||||
|
@@comments :: /\#[^\n]*/
|
||||||
|
@@eol_comments :: /\#[^\n]*/
|
||||||
|
|
||||||
|
@@whitespace :: /[\t \f]+/
|
||||||
|
|
||||||
|
|
||||||
|
start
|
||||||
|
=
|
||||||
|
{newline|@:stmt}+
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
single_input
|
||||||
|
=
|
||||||
|
newline | @:simple_stmt | @:compound_stmt {dedent} newline
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
file_input
|
||||||
|
=
|
||||||
|
{NEWLINE | stmt}* $
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
eval_input
|
||||||
|
=
|
||||||
|
testlist {NEWLINE}* $
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
decorator
|
||||||
|
=
|
||||||
|
'@' name:dotted_name args:{'(' {arglist} ')'} newline
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
decorators
|
||||||
|
=
|
||||||
|
decorators:{decorator}+
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
decorated
|
||||||
|
=
|
||||||
|
decorators (classdef | funcdef)
|
||||||
|
;
|
||||||
|
|
||||||
|
funcdef
|
||||||
|
=
|
||||||
|
type:'def' name:name params:parameters ':' body:suite
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
parameters
|
||||||
|
=
|
||||||
|
'(' @:({varargslist}) ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
varargslist= ({@:fpdef {'=' @:test} ','}*
|
||||||
|
('*' @:name {',' '**' @:name} | '**' @:name) |
|
||||||
|
@:fpdef {'=' @:test} {',' @:fpdef {'=' @:test}}* {','});
|
||||||
|
|
||||||
|
fpdef = name | '(' fplist ')';
|
||||||
|
fplist= fpdef {',' fpdef}* {','};
|
||||||
|
|
||||||
|
stmt
|
||||||
|
=
|
||||||
|
$ ~ | @:(compound_stmt | simple_stmt)
|
||||||
|
;
|
||||||
|
|
||||||
|
newline=
|
||||||
|
NEWLINE
|
||||||
|
;
|
||||||
|
|
||||||
|
eof = EOF ~;
|
||||||
|
|
||||||
|
simple_stmt
|
||||||
|
=
|
||||||
|
statement:small_stmt {';' statement:small_stmt}* {';'} newline {dedent} {eof}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
small_stmt
|
||||||
|
=
|
||||||
|
(print_stmt
|
||||||
|
| expr_stmt
|
||||||
|
| del_stmt
|
||||||
|
| pass_stmt
|
||||||
|
| flow_stmt
|
||||||
|
| import_stmt
|
||||||
|
| global_stmt
|
||||||
|
| exec_stmt
|
||||||
|
| assert_stmt)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
expr_stmt
|
||||||
|
=
|
||||||
|
@:testlist ~
|
||||||
|
(
|
||||||
|
@:augassign @:(yield_expr | testlist) ~
|
||||||
|
| {@:'=' @:(yield_expr | testlist)}* ~
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
augassign
|
||||||
|
=
|
||||||
|
(
|
||||||
|
'+='
|
||||||
|
| '-='
|
||||||
|
| '*='
|
||||||
|
| '/='
|
||||||
|
| '%='
|
||||||
|
| '&='
|
||||||
|
| '|='
|
||||||
|
| '^='
|
||||||
|
| '<<='
|
||||||
|
| '>>='
|
||||||
|
| '**='
|
||||||
|
| '//='
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
del_stmt
|
||||||
|
=
|
||||||
|
'del' exprlist
|
||||||
|
;
|
||||||
|
|
||||||
|
print_stmt
|
||||||
|
=
|
||||||
|
@:'print' ( { @+:test {',' @+:test}* {','} } |
|
||||||
|
@:'>>' @+:test { {',' @+:test}+ {','}} )
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
pass_stmt
|
||||||
|
=
|
||||||
|
'pass'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
flow_stmt
|
||||||
|
=
|
||||||
|
break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
break_stmt
|
||||||
|
=
|
||||||
|
'break'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
continue_stmt
|
||||||
|
=
|
||||||
|
'continue'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
return_stmt
|
||||||
|
=
|
||||||
|
'return' {testlist}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
yield_stmt
|
||||||
|
=
|
||||||
|
yield_expr
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
raise_stmt
|
||||||
|
=
|
||||||
|
'raise' {test {'from' test}}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
import_stmt
|
||||||
|
=
|
||||||
|
import_name | import_from
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
import_name
|
||||||
|
=
|
||||||
|
'import' dotted_as_names
|
||||||
|
;
|
||||||
|
|
||||||
|
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}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
import_as_names
|
||||||
|
=
|
||||||
|
import_as_name {',' import_as_name}* {','}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
dotted_as_names
|
||||||
|
=
|
||||||
|
dotted_as_name {',' dotted_as_name}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
dotted_name
|
||||||
|
=
|
||||||
|
@:(NAME {'.' NAME}*)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
global_stmt
|
||||||
|
=
|
||||||
|
'global' name {',' name}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
exec_stmt
|
||||||
|
=
|
||||||
|
'exec' expr {'in' test {',' test}}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
assert_stmt
|
||||||
|
=
|
||||||
|
'assert' test {',' test}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
compound_stmt
|
||||||
|
=
|
||||||
|
statement:(if_stmt
|
||||||
|
| while_stmt
|
||||||
|
| for_stmt
|
||||||
|
| try_stmt
|
||||||
|
| with_stmt
|
||||||
|
| funcdef
|
||||||
|
| classdef
|
||||||
|
| decorated)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
if_stmt
|
||||||
|
=
|
||||||
|
'if' test ':' suite {'elif' test ':' suite}* {'else' ':' suite}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
with_stmt
|
||||||
|
=
|
||||||
|
'with' items:(with_item {',' with_item}*) ':' body:suite
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
with_item
|
||||||
|
=
|
||||||
|
test {'as' expr}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
except_clause
|
||||||
|
=
|
||||||
|
'except' {test {('as' | ',') test}}
|
||||||
|
;
|
||||||
|
|
||||||
|
suite
|
||||||
|
=
|
||||||
|
{newline} indent @:{stmt}+ {dedent} {eof} | @:simple_stmt
|
||||||
|
;
|
||||||
|
|
||||||
|
testlist_safe= old_test {{',' old_test}+ {','}};
|
||||||
|
old_test= or_test | old_lambdef;
|
||||||
|
old_lambdef= 'lambda' {varargslist} ':' old_test;
|
||||||
|
|
||||||
|
test
|
||||||
|
=
|
||||||
|
@:or_test {'if' @:or_test 'else' @:test} | @:lambdef
|
||||||
|
;
|
||||||
|
|
||||||
|
lambdef
|
||||||
|
=
|
||||||
|
'lambda' {varargslist} ':' test
|
||||||
|
;
|
||||||
|
|
||||||
|
or_test
|
||||||
|
=
|
||||||
|
@:and_test {'or' @:and_test}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
and_test
|
||||||
|
=
|
||||||
|
(@:not_test {'and' @:not_test}*)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
not_test
|
||||||
|
=
|
||||||
|
'not' @:not_test | @:comparison
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
comparison
|
||||||
|
=
|
||||||
|
@:expr {comp_op @:expr}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
comp_op
|
||||||
|
=
|
||||||
|
'<'
|
||||||
|
| '>'
|
||||||
|
| '=='
|
||||||
|
| '>='
|
||||||
|
| '<='
|
||||||
|
| '<>'
|
||||||
|
| '!='
|
||||||
|
| 'in'
|
||||||
|
| 'not' 'in'
|
||||||
|
| 'is'
|
||||||
|
| 'is' 'not'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
expr
|
||||||
|
=
|
||||||
|
@:xor_expr {'|' @:xor_expr}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
xor_expr
|
||||||
|
=
|
||||||
|
@:and_expr {'^' @:and_expr}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
and_expr
|
||||||
|
=
|
||||||
|
@:shift_expr {'&' @:shift_expr}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
shift_expr
|
||||||
|
=
|
||||||
|
@:arith_expr {('<<' | '>>') @:arith_expr}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
arith_expr
|
||||||
|
=
|
||||||
|
@:term {('+' | '-') @:term}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
term
|
||||||
|
=
|
||||||
|
@:factor {('*' | '/' | '%' | '//') @:factor}*
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
factor
|
||||||
|
=
|
||||||
|
('+' | '-' | '~') @:factor | @:power
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
power
|
||||||
|
=
|
||||||
|
@:atom {@:trailer} {'**' @:factor}
|
||||||
|
;
|
||||||
|
|
||||||
|
atom= ('(' @:{yield_expr|testlist_comp} ')' |
|
||||||
|
'[' @:{listmaker} ']' |
|
||||||
|
'{' @:{dictorsetmaker} '}' |
|
||||||
|
'`' @:testlist1 '`' |
|
||||||
|
@:name | @:NUMBER | @:{string}+);
|
||||||
|
|
||||||
|
listmaker= test ( list_for | {',' test}* {','} );
|
||||||
|
|
||||||
|
testlist_comp
|
||||||
|
=
|
||||||
|
test ( comp_for | {',' test}* {','} )
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
trailer
|
||||||
|
=
|
||||||
|
'(' {@:arglist} ')' | '[' @:subscriptlist ']' | '.' @:NAME
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
subscriptlist
|
||||||
|
=
|
||||||
|
subscript {',' subscript}* {','}
|
||||||
|
;
|
||||||
|
|
||||||
|
subscript= '.' '.' '.' | test | {test} ':' {test} {sliceop};
|
||||||
|
|
||||||
|
|
||||||
|
sliceop
|
||||||
|
=
|
||||||
|
':' {test}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
exprlist
|
||||||
|
=
|
||||||
|
@:expr {',' @:expr}* {','}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
testlist
|
||||||
|
=
|
||||||
|
@:test {',' @:test}* {','}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
dictorsetmaker
|
||||||
|
=
|
||||||
|
(
|
||||||
|
(test ':' test (comp_for | {',' test ':' test}* {','}))
|
||||||
|
| (test (comp_for | {',' test}* {','}))
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
classdef
|
||||||
|
=
|
||||||
|
type:'class' name:name {'(' base_classes:{arglist} ')'} ':' body:suite
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
arglist
|
||||||
|
=
|
||||||
|
{@+:argument ','}* (@+:argument {','} | '*' @+:test {',' @+:argument}* {',' '**' @+:test} | '**' @+:test)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
argument
|
||||||
|
=
|
||||||
|
@:test {@:comp_for} | @:test '=' @:test
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
list_iter= list_for | list_if;
|
||||||
|
list_for= 'for' exprlist 'in' testlist_safe {list_iter};
|
||||||
|
list_if= 'if' old_test {list_iter};
|
||||||
|
|
||||||
|
comp_iter
|
||||||
|
=
|
||||||
|
comp_for | comp_if
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
comp_for
|
||||||
|
=
|
||||||
|
'for' exprlist 'in' or_test {comp_iter}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
comp_if
|
||||||
|
=
|
||||||
|
'if' old_test {comp_iter}
|
||||||
|
;
|
||||||
|
|
||||||
|
testlist1= test {',' test}*;
|
||||||
|
|
||||||
|
encoding_decl
|
||||||
|
=
|
||||||
|
name
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
yield_expr
|
||||||
|
=
|
||||||
|
'yield' {testlist1}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
NEWLINE
|
||||||
|
=
|
||||||
|
/(\r?\n[\t ]*)+/
|
||||||
|
;
|
||||||
|
|
||||||
|
NUMBER
|
||||||
|
=
|
||||||
|
number:(FLOAT_NUMBER |
|
||||||
|
DEC_NUMBER |
|
||||||
|
HEX_NUMBER |
|
||||||
|
OCT_NUMBER |
|
||||||
|
BIN_NUMBER |
|
||||||
|
IMAG_NUMBER)
|
||||||
|
;
|
||||||
|
|
||||||
|
term_symbol = STAR|SLASH|PERCENT|DOUBLESLASH ;
|
||||||
|
shift_symbol = LEFTSHIFT|RIGHTSHIFT;
|
||||||
|
add_symbol = PLUS|MINUS;
|
||||||
|
name = NAME;
|
||||||
|
string = STRING | LONG_STRING;
|
||||||
|
|
||||||
|
I = /(?i)/; # Case insensitive
|
||||||
|
S = /(?s)/; # Dot matches newline
|
||||||
|
J = /([jJ])/;
|
||||||
|
|
||||||
|
LONG_POSTFIX = /[lL]?/;
|
||||||
|
EXP_POSTFIX = /[eE][-+]?\d+/;
|
||||||
|
DEC_NUMBER = value:/[1-9]\d*(?![.0])/ postfix:LONG_POSTFIX;
|
||||||
|
HEX_NUMBER = value:/0[xX][\da-fA-F]*/ postfix:LONG_POSTFIX;
|
||||||
|
OCT_NUMBER = value:/0[oO]?(?![bBxX])[0-7]*/ postfix:LONG_POSTFIX;
|
||||||
|
FLOAT_NUMBER = value:/(\d+\.\d*|\.\d+)([eE][-+]?\d+)?|\d+[eE][-+]?\d+/;
|
||||||
|
IMAG_NUMBER = value:(/\d+/ | FLOAT_NUMBER) postfix:J;
|
||||||
|
BIN_NUMBER = value:/0[bB][01]+/ postfix:LONG_POSTFIX;
|
||||||
|
STRING_PREFIX = /(u|b|)r?/;
|
||||||
|
STRING_INTERNAL = /.\*?(?<!\\)(\\\\)*?/ ;
|
||||||
|
QUOTE = "'";
|
||||||
|
DBLQUOTE = '"';
|
||||||
|
QUOTE3 = "'''";
|
||||||
|
DBLQUOTE3 = '"""';
|
||||||
|
|
||||||
|
STRING = STRING_PREFIX @:(/"(?!"").*?(?<!\\)(\\\\)*?"/ | /'(?!'').*?(?<!\\)(\\\\)*?'/);
|
||||||
|
|
||||||
|
LONG_STRING = S STRING_PREFIX @:(/""".*?(?<!\\)(\\\\)*?(\n)*?"""/ | /'''.*?(?<!\\)(\\\\)*?(\n)*?'''/);
|
||||||
|
|
||||||
|
LEFTSHIFTEQUAL = '<<=';
|
||||||
|
RIGHTSHIFTEQUAL = '>>=';
|
||||||
|
DOUBLESTAREQUAL = '**=';
|
||||||
|
DOUBLESLASHEQUAL = '//=';
|
||||||
|
|
||||||
|
EQEQUAL = '==';
|
||||||
|
NOTEQUAL = '!=|<>';
|
||||||
|
LESSEQUAL = '<=';
|
||||||
|
LEFTSHIFT = '<<';
|
||||||
|
GREATEREQUAL = '>=';
|
||||||
|
RIGHTSHIFT = '>>';
|
||||||
|
PLUSEQUAL = '+=';
|
||||||
|
MINEQUAL = '-=';
|
||||||
|
DOUBLESTAR = '**';
|
||||||
|
STAREQUAL = '*=';
|
||||||
|
DOUBLESLASH = '//';
|
||||||
|
SLASHEQUAL = '/=';
|
||||||
|
VBAREQUAL = '|=';
|
||||||
|
PERCENTEQUAL = '%=';
|
||||||
|
AMPEREQUAL = '&=';
|
||||||
|
CIRCUMFLEXEQUAL = '^=';
|
||||||
|
|
||||||
|
COLON = ':';
|
||||||
|
COMMA = ',';
|
||||||
|
SEMI = ';';
|
||||||
|
PLUS = '+';
|
||||||
|
MINUS = '-';
|
||||||
|
STAR = '*';
|
||||||
|
SLASH = '/';
|
||||||
|
VBAR = '|';
|
||||||
|
AMPER = '&';
|
||||||
|
|
||||||
|
LESS = '<';
|
||||||
|
GREATER = '>';
|
||||||
|
EQUAL = '=';
|
||||||
|
DOT = '.';
|
||||||
|
PERCENT = '%';
|
||||||
|
BACKQUOTE = '`';
|
||||||
|
CIRCUMFLEX = '^';
|
||||||
|
TILDE = '~';
|
||||||
|
AT = '@';
|
||||||
|
|
||||||
|
LPAR = '(';
|
||||||
|
RPAR = ')';
|
||||||
|
LBRACE = '{';
|
||||||
|
RBRACE = '}';
|
||||||
|
LSQB = '[';
|
||||||
|
RSQB = ']';
|
||||||
|
|
||||||
|
PRINT = 'print';
|
||||||
|
IMPORT = 'import';
|
||||||
|
FROM = 'from';
|
||||||
|
GLOBAL = 'global';
|
||||||
|
EXEC = 'exec';
|
||||||
|
ASSERT = 'assert';
|
||||||
|
DEL = 'del';
|
||||||
|
AS = 'as';
|
||||||
|
LAMBDA = 'lambda';
|
||||||
|
|
||||||
|
# Definitions
|
||||||
|
DEF = 'def';
|
||||||
|
CLASS = 'class';
|
||||||
|
|
||||||
|
# Flow Blocks
|
||||||
|
TRY = 'try';
|
||||||
|
EXCEPT = 'except';
|
||||||
|
FINALLY = 'finally';
|
||||||
|
IF = 'if';
|
||||||
|
ELIF = 'elif';
|
||||||
|
ELSE = 'else';
|
||||||
|
FOR = 'for';
|
||||||
|
WHILE = 'while';
|
||||||
|
WITH = 'with';
|
||||||
|
|
||||||
|
# Flow
|
||||||
|
BREAK = 'break';
|
||||||
|
CONTINUE = 'continue';
|
||||||
|
RETURN = 'return';
|
||||||
|
YIELD = 'yield';
|
||||||
|
RAISE = 'raise';
|
||||||
|
PASS = 'pass';
|
||||||
|
|
||||||
|
# Operators
|
||||||
|
AND = 'and';
|
||||||
|
OR = 'or';
|
||||||
|
NOT = 'not';
|
||||||
|
IS = 'is';
|
||||||
|
IN = 'in';
|
||||||
|
|
||||||
|
NAME
|
||||||
|
=
|
||||||
|
/[a-zA-Z_]\w*/
|
||||||
|
;
|
||||||
|
|
||||||
|
EOF
|
||||||
|
=
|
||||||
|
'<EOF>' $ ~
|
||||||
|
;
|
||||||
|
|
||||||
|
indent =
|
||||||
|
INDENT
|
||||||
|
;
|
||||||
|
dedent =
|
||||||
|
DEDENT
|
||||||
|
;
|
||||||
|
|
||||||
|
INDENT
|
||||||
|
=
|
||||||
|
'<INDENT>'
|
||||||
|
;
|
||||||
|
|
||||||
|
DEDENT
|
||||||
|
=
|
||||||
|
'<DEDENT>'
|
||||||
|
;
|
||||||
136
python_parser.py
Normal file
136
python_parser.py
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
from __future__ import print_function, division, absolute_import, unicode_literals
|
||||||
|
from grako.parsing import graken, Parser
|
||||||
|
from grako.buffering import Buffer, PosLine, LineInfo
|
||||||
|
from grako.util import re, RE_FLAGS
|
||||||
|
|
||||||
|
|
||||||
|
__version__ = (2015, 5, 20, 15, 52, 20, 2)
|
||||||
|
|
||||||
|
from parser_class import PythonParser
|
||||||
|
|
||||||
|
class MyBuffer(Buffer):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
text,
|
||||||
|
filename=None,
|
||||||
|
comments_re=None,
|
||||||
|
eol_comments_re=None,
|
||||||
|
whitespace=None,
|
||||||
|
**kwargs):
|
||||||
|
self.last_line = 0
|
||||||
|
self.indent_stack = []
|
||||||
|
super(MyBuffer, self).__init__(
|
||||||
|
text,
|
||||||
|
filename=filename,
|
||||||
|
memoize_lookaheads=False,
|
||||||
|
comment_recovery=True,
|
||||||
|
comments_re=comments_re,
|
||||||
|
whitespace=whitespace or '\t \f',
|
||||||
|
eol_comments_re=eol_comments_re,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def _dedent_from_stack(self, new_lines):
|
||||||
|
while self.indent_stack:
|
||||||
|
self.indent_stack.pop()
|
||||||
|
new_lines[-1] +='<DEDENT>'
|
||||||
|
return new_lines
|
||||||
|
|
||||||
|
def process_leading_spaces(self, line, leading_spaces):
|
||||||
|
if self.indent_stack:
|
||||||
|
if len(leading_spaces) > len(self.indent_stack[-1]):
|
||||||
|
line = '<INDENT>'+line
|
||||||
|
self.indent_stack.append(leading_spaces)
|
||||||
|
elif len(leading_spaces) < len(self.indent_stack[-1]):
|
||||||
|
line = line+'<DEDENT>'
|
||||||
|
self.indent_stack.pop()
|
||||||
|
else:
|
||||||
|
line = '<INDENT>'+line
|
||||||
|
self.indent_stack.append(leading_spaces)
|
||||||
|
return line
|
||||||
|
|
||||||
|
def dedent_and_end(self, new_lines):
|
||||||
|
new_lines = self._dedent_from_stack(new_lines)
|
||||||
|
new_lines[-1] += '<EOF>'
|
||||||
|
|
||||||
|
def indent_and_dedent_lines(self, lines):
|
||||||
|
new_lines = []
|
||||||
|
for line in lines:
|
||||||
|
leading_spaces = re.search(u'^['+self.whitespace+']+', line)
|
||||||
|
if leading_spaces is not None:
|
||||||
|
leading_spaces = leading_spaces.group().strip('\n')
|
||||||
|
if leading_spaces:
|
||||||
|
line = self.process_leading_spaces(line, leading_spaces)
|
||||||
|
else:
|
||||||
|
new_lines = self._dedent_from_stack(new_lines)
|
||||||
|
else:
|
||||||
|
new_lines = self._dedent_from_stack(new_lines)
|
||||||
|
|
||||||
|
new_lines.append(line)
|
||||||
|
return new_lines
|
||||||
|
|
||||||
|
def process_lines(self, lines):
|
||||||
|
new_lines = self.indent_and_dedent_lines(lines)
|
||||||
|
self.dedent_and_end(new_lines)
|
||||||
|
return new_lines
|
||||||
|
|
||||||
|
def process_block(self, name, lines, index, **kwargs):
|
||||||
|
new_lines = self.process_lines(lines)
|
||||||
|
return new_lines, index
|
||||||
|
|
||||||
|
|
||||||
|
def main(filename, startrule, trace=False, whitespace=None, nameguard=None):
|
||||||
|
import json
|
||||||
|
with open(filename) as f:
|
||||||
|
text = f.read()
|
||||||
|
parser = PythonParser(parseinfo=False)
|
||||||
|
buf = MyBuffer(text, whitespace=whitespace,nameguard=nameguard,trace=trace,filename=filename)
|
||||||
|
ast = parser.parse(
|
||||||
|
buf,
|
||||||
|
startrule,
|
||||||
|
filename=filename,
|
||||||
|
trace=trace,
|
||||||
|
whitespace=whitespace,
|
||||||
|
nameguard=nameguard)
|
||||||
|
print('AST:')
|
||||||
|
print(ast)
|
||||||
|
print()
|
||||||
|
print('JSON:')
|
||||||
|
print(json.dumps(ast, indent=2))
|
||||||
|
print()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class ListRules(argparse.Action):
|
||||||
|
def __call__(self, parser, namespace, values, option_string):
|
||||||
|
print('Rules:')
|
||||||
|
for r in pythonParser.rule_list():
|
||||||
|
print(r)
|
||||||
|
print()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Simple parser for python.")
|
||||||
|
parser.add_argument('-l', '--list', action=ListRules, nargs=0,
|
||||||
|
help="list all rules and exit")
|
||||||
|
parser.add_argument('-n', '--no-nameguard', action='store_true',
|
||||||
|
dest='no_nameguard',
|
||||||
|
help="disable the 'nameguard' feature")
|
||||||
|
parser.add_argument('-t', '--trace', action='store_true',
|
||||||
|
help="output trace information")
|
||||||
|
parser.add_argument('-w', '--whitespace', type=str, default=None,
|
||||||
|
help="whitespace specification")
|
||||||
|
parser.add_argument('file', metavar="FILE", help="the input file to parse")
|
||||||
|
parser.add_argument('startrule', metavar="STARTRULE",
|
||||||
|
help="the start rule for parsing")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
main(
|
||||||
|
args.file,
|
||||||
|
args.startrule,
|
||||||
|
trace=args.trace,
|
||||||
|
whitespace=args.whitespace,
|
||||||
|
nameguard=not args.no_nameguard
|
||||||
|
)
|
||||||
13
test/test.py
Normal file
13
test/test.py
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
a = 8
|
||||||
|
stuff = x
|
||||||
|
|
||||||
|
class Test(object):
|
||||||
|
def stuff(self):
|
||||||
|
print 'stuff'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
x = 8
|
||||||
|
c = u
|
||||||
Loading…
Add table
Add a link
Reference in a new issue