рдлреНрд▓реЗрдХреНрд╕ рдФрд░ рдмрд╛рдЗрд╕рди рдХреЗ рд╕рд╛рде рдкрд░рд╕рд┐рдо рдкрд╛рдпрдерди рдХреЛрдб

рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐


рдЕрдм рд▓рдЧрднрдЧ рджреЛ рд╕рд╛рд▓ рд╕реЗ рдореИрдВ OpenSource рдкреНрд░реЛрдЬреЗрдХреНрдЯ SourceAnalyzer рдореЗрдВ рднрд╛рдЧ рд▓реЗ рд░рд╣рд╛ рд╣реВрдВ , рдФрд░ рдЕрдм Python рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ Parser рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рдХреЙрд▓ рдЧреНрд░рд╛рдлрд╝ (рдХреЙрд▓ рдЧреНрд░рд╛рдлрд╝) рдФрд░ рдПрдХ рд╡рд░реНрдЧ рдкрд░ рдирд┐рд░реНрднрд░ рдЧреНрд░рд╛рдлрд╝ (рдХреНрд▓рд╛рд╕ рдЧреНрд░рд╛рдлрд╝ рдирд┐рд░реНрднрд░рддрд╛) рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, рдЧреНрд░рд╛рдл рдЕрдиреНрдп рдЙрдкрдХрд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдкрд╛рд░реНрд╕рд░ рдХреЛ рдХреЗрд╡рд▓ рдЗрди рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдкрд╛рд░реНрд╕рд░ рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛рдлреА рдордиреЛрд░рдВрдЬрдХ рдереА рдФрд░ рдореИрдВ рдЖрдкрдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдЕрдиреБрднрд╡ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рд╕рд╛рде рд╣реА рдЖрдкрдХреЛ рдХреБрдЫ рдРрд╕реЗ рдиреБрдХрд╕рд╛рдиреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдКрдВрдЧрд╛ рдЬреЛ рд╣рдореЗрдВ рд╡рд┐рдХрд╛рд╕ рдХреЗ рдЪрд░рдг рдореЗрдВ рдорд┐рд▓реЗ рдереЗред

рд╢рдмреНрджрд╛рд╡рд▓реА


рдпрджрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рдЪреБрдХреЗ рд╣реИрдВ рдФрд░ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЕрдЧрд▓реЗ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ, рдмрд╛рдХреА рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред

рдкрд╛рд░реНрд╕рд░ рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рджреЛ рдореБрдЦреНрдп рдШрдЯрдХреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

рдЖрдЗрдП рдереЛрдбрд╝рд╛ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВред рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ (рдпрд╛ рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░реАрдо) рд╣реЛрдиреЗ рджреЗрдВ:

3 + 4 * 15 


рдЗрдирдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдо рдмрдирд╛рдПрдБ:

 [1-9]* -> NUMBER + -> PLUS * -> MULT 


рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╢рд╛рдмреНрджрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдмрд╛рдж рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:
 NUMBER(3) PLUS(+) NUMBER(4) MULT(*) NUMBER(15) EQUAL(=) 


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХ рд╡реНрдпрд╛рдХрд░рдг рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдмрд╛рдж рдореЗрдВ, рдирд┐рдпрдореЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдЖрдк рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 exp: NUMBER | exp sign exp sign: PLUS | MULT * / \ + 15 / \ 3 4 


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, NUMBER, MULT, PLUS - рдкрд░рд┐рднрд╛рд╖рд╛, рдЯрд░реНрдорд┐рдирд▓реЛрдВ, рдпрд╛ рдЯреЛрдХрдиреЛрдВ рджреНрд╡рд╛рд░рд╛, рд╢рд╛рдмреНрджрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдЪрд░рдг рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред expr, sign рдЯрд░реНрдорд┐рдирд▓ рдирд╣реАрдВ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рдордЧреНрд░ рдЗрдХрд╛рдЗрдпрд╛рдБ рд╣реИрдВред

рдпрд╣ рдкрд░рд┐рдЪрдп рдердХрд╛рдК рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рд▓рд┐рдП рдкреБрд╕реНрддрдХ рдлреНрд▓реЗрдХреНрд╕ рдПрдВрдб рдмрд╛рдЗрд╕рди рдУ'рд░реЗрд▓реА рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╡реНрдпрд╛рдХрд░рдг


рдЕрдЬрдЧрд░ рдХреЗ рд▓рд┐рдП рдкреВрд░реНрдг рд╡реНрдпрд╛рдХрд░рдг (рд╕рдВрд╕реНрдХрд░рдг 2.5.2) рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
http://docs.python.org/release/2.5.2/ref/grammar.txt

рдореЗрд░рд╛ рдХрд╛рдо рдХреЗрд╡рд▓ рдХрдХреНрд╖рд╛рдУрдВ, рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдирд╛ рдерд╛ред

рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреИрдХрд╕-рдиреМрд░ рдлреЙрд░реНрдо (рдЖрд░рдмреАрдПрдирдПрдл) ( рд╡рд┐рдХреА ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рдЖрд╡рд╢реНрдпрдХ рд╣рд┐рд╕реНрд╕реЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВрдЧреЗред

 class_def = CLASS classname [inheritance] COLON suite classname = ID inheritance = LBRACE class_args_list RBRACE class_args_list = [class_arg] class_arg = dotted_name {COMMA dotted_name} dotted_name = ID {DOT ID} 

рдпрд╣рд╛рдВ [X] рдХреА 0 рдпрд╛ 1 рдШрдЯрдирд╛ рд╣реИ, {Y} 0 рд╣реИ рдпрд╛ {Y} рдЕрдзрд┐рдХ рдШрдЯрдирд╛рдПрдВ рд╣реИрдВ Y

рд╡рд░реНрдЧ рдХрд╛ рдирд╛рдо рдФрд░ рдЙрд╕рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдЕрдм рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд▓рд┐рдПред

 func_def = DEF funcname LBRACE [func_args_list] RBRACE COLON suite funcname = ID func_args_list = [func_arg] func_arg = (dotted_name | star_arg) {OTHER | COMMA | dotted_name | star_arg | MESSAGE} star_arg = [STAR] STAR ID 

рд╡реИрд╕реЗ, рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛрдб рд╕рд╣реА рд╣реЛрдЧрд╛ (рджреБрднрд╛рд╖рд┐рдпрд╛ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ), рдЕрдиреНрдпрдерд╛ рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рдирд┐рдпрдореЛрдВ рдХреЛ рдЕрдзрд┐рдХ рд╕рдЦреНрддреА рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЦреИрд░, рдЕрдм рдХреЗ рд▓рд┐рдП, рдЪрд▓реЛ рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рдХрд░реЗрдВ рдФрд░ рд▓реЗрдХреНрд╕рд░ (рд▓реЗрдХреНрд╕рд┐рдХрд▓ рдПрдирд╛рд▓рд╛рдЗрдЬрд╝рд░) рдкрд░ рдЬрд╛рдПрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реНрдпрд╛рдХрд░рдг рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореВрд▓ рдкрд╛рдпрдерди рдХреЛрдб рдХреЛ рдЯреЛрдХрди рдореЗрдВ рддреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд▓реЗрдХреНрд╕рд┐рдХрд▓ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ


рд▓реЗрдХреНрд╕рд░ рдлреНрд▓реЗрдХреНрд╕ рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг:
 %{ #include <stdio.h> %} %% start printf("START\n"); stop printf("STOP\n"); . ; /*    */ %% 

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдХреИрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ:

 % flex lexer.l && gcc lex.yy.c -o lexer -lfl 


рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╛рдХрд░рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╕реАрдЦреЗрдВ:
http://rus-linux.net/lib.php?name=/MyLDP/algol/lex-yacc-howto.html

рдареАрдХ рд╣реИ, рдЕрдм рдЯреЛрдХрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдлреИрд╕рд▓рд╛ рдХрд░рддреЗ рд╣реИрдВред рд╡реНрдпрд╛рдХрд░рдг рдореЗрдВ, рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ:
CLASS, COLON, COMMA, DEF, DOT, ID, LBRACE, MESSAGE, RBRACE, OTHER, STAR
рд╣рдореЗрдВ рднреА DEFINED - рдЖрд░рдХреНрд╖рд┐рдд рдкрд╛рдпрдерди рд╢рдмреНрджреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╣рдо рдПрдХ рд▓реЗрдХреНрд╕рд░ рдмрдирд╛рддреЗ рд╣реИрдВред
рдХреЛрдб: https://gist.github.com/2158334

рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдкрд╛рд░реНрд╕рд┐рдВрдЧ: рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ, рд░рд┐рдХреНрдд рд▓рд╛рдЗрдиреЛрдВ рдФрд░ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рдХреА рдЕрдирджреЗрдЦреА рдХреА рдЬрд╛рддреА рд╣реИред рдмрд╛рдХреА рд╕рдм рдХреБрдЫ (рддрдерд╛рдХрдерд┐рдд рдЯреЛрдХрди рд╕реНрдЯреНрд░реАрдо) рдмрд╛рдЗрд╕рди рдЗрдирдкреБрдЯ рдХреЛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рд╡рд░реНрдг рд╕реЗрдЯ рдЬреЛ рдкреИрдЯрд░реНрди рдкрд╛рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреИрдЯрд░реНрди [ \t]+ ) рдХреЛ yytext рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, yytext рдПрдХ yytext рдкреЙрдЗрдВрдЯрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рд╕рдВрдХрд▓рди рдореЗрдВ -l рд╕реНрд╡рд┐рдЪ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ yytext рдХреЛ рдЪрд╛рд░ рд╕рд░рдгреА рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рдПрдЧрд╛ред рдмрд╛рдЗрд╕рди рдХреЛ рдЯреЛрдХрди рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЯреЗрдореНрдкрд▓реЗрдЯ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдореВрд▓реНрдп рдХреЛ yylval рдореЗрдВ yylval (рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП, рдиреАрдЪреЗ рджреЗрдЦреЗрдВ)ред

рдпрд╣ рдмрд╛рдЗрд╕рди рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╛рдХрд░рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред

рдмрд┐рдЬреЛрди


рдмрд╛рдпрд╕рди рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╛рдХрд░рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╕реАрдЦреЗрдВ: http://rus-linux.net/lib.php?name=/MyLDP/algol/lex-yacc-howto.html

рдореИрдВ рдЖрдкрдХреЛ рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдмрддрд╛ рд░рд╣рд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЬреЛ рд▓реЛрдЧ рдмрд╛рдЗрд╕рди рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╛рдХрд░рдг рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд╡реЗ рдЗрд╕ рд▓рд┐рдВрдХ рдкрд░ рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕реАрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдЦреИрд░, рдХреМрди рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ - рдорд╣рд╛рди, рдЪрд▓реЛ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред

рдЗрд╕рд▓рд┐рдП, рд╡реНрдпрд╛рдХрд░рдг рд▓реЗрдЦ рдХреЗ рдЕрдиреБрдЪреНрдЫреЗрдж рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рдо рдмрд╛рдЗрд╕рди рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реНрдпрд╛рдХрд░рдг рд░рдЪрдирд╛ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗ:

рдХреЛрдб: https://gist.github.com/2158315

рдмрд╛рдЗрд╕рди рдирд┐рдпрдо рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдЯреЛрдХрди рдХрд╛ рдПрдХ рдЕрд░реНрде рд╣реИред рд╡рд░реНрддрдорд╛рди рдирд┐рдпрдо рджреНрд╡рд╛рд░рд╛ рдПрдХрддреНрд░рд┐рдд рд╕рдореВрд╣ рдХрд╛ рдореВрд▓реНрдп $ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╢реЗрд╖ рдЯреЛрдХрди рдХрд╛ рдореВрд▓реНрдп $1, $2, тАж
 test_rule: token1, token2, token3; $$ $1 $2 $3 

$n рдореЗрдВ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдореВрд▓реНрдп рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм yylval рдЯреЛрдХрди рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рддреЛ yylval рдХрд╛ рдореВрд▓реНрдпред

.tab.h -d рд╕рд╛рде рд░рдирд┐рдВрдЧ рдмрд╛рдЗрд╕рди рдлрд╝рд╛рдЗрд▓ .tab.h рдЬреЗрдирд░реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдореЗрдВ .tab.h рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЯреЛрдХрди рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреА рдореИрдХреНрд░реЛ рдкрд░рд┐рднрд╛рд╖рд╛рдПрдБ рд╣реЛрддреА рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдЯреЛрдХрди рд╕рдВрдЦреНрдпрд╛ > 257 рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ #include "pyparser.tab.h" рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рд╣рдордиреЗ рдХрд┐рдпрд╛ рдерд╛: #include "pyparser.tab.h" ред

рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ? yyparse рдлрд╝рдВрдХреНрд╢рди рдХреЛ main рд╕реЗ yyparse рд╣реИ, рдЬреЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ - рдЯреЛрдХрди рдкрдврд╝рддрд╛ рд╣реИ, рдХреБрдЫ рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддрд╛ рд╣реИ рдЕрдЧрд░ рдпрд╣ рдЗрдирдкреБрдЯ рдкрд╛рда ( return 0 ) рдпрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рддреНрд░реБрдЯрд┐ ( return 1 ) рдХреЗ рдЕрдВрдд рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рддрд╛ рд╣реИред

рдмрд╛рдЗрд╕рди рдХреЗ рдХрд╛рдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА: http://www.linux.org.ru/books/GNU/bison/bison_7.html

рд╣рдо рдпрд╣ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдФрд░ рдкрд░рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреНрдпрд╛ рд╣реИ:
 % bison -d pyparser.y --verbose && flex lexer.l && g++ -c lex.yy.c pyparser.tab.c && g++ -o parser lex.yy.o pyparser.tab.o -ll -ly 

рдкрд░реАрдХреНрд╖рдг рдЙрджрд╛рд╣рд░рдг:
 class Foo: pass class Test(Foo): class Test2: def __init__(self): pass def foo(): pass 

рдкрд░рд┐рдгрд╛рдо:
  >> CLASS: Foo() >> CLASS: Test(Foo) >> CLASS: Test2() >> FUNC: __init__(self) >> FUNC: foo() 

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдпрд╣ рд╕рдЪ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХрд╛рдлреА рдирд╣реАрдВ рд╣реИред рдореИрдВ рдлрд╝рдВрдХреНрд╢рди рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдореЗрдВ "рдкреВрд░рд╛ рдирд╛рдо" рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЬреЛ рд╣реИ:
 >> CLASS: Foo() >> CLASS: Test(Foo) >> CLASS: Test2() >> FUNC: Test.Test2.__init__(self) >> FUNC: Test.Test2.foo() 

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВ: рд╣рдо рдПрдХ рд╕реНрдЯреИрдХ рдмрдирд╛рдПрдВрдЧреЗ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╡рд░реНрддрдорд╛рди рд╡рд░реНрдЧ рдХрд╛ рдирд╛рдо рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗред рдЬреИрд╕реЗ рд╣реА рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд╛ рдорд┐рд▓рддреА рд╣реИ, рд╣рдо рдзреАрд░реЗ-рдзреАрд░реЗ рд╕реНрдЯреИрдХ рд╕реЗ рдХреНрд▓рд╛рд╕ рдХреЗ рдирд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдлрд╝рдВрдХреНрд╢рди рдирд╛рдо рдХреЗ рд╕рд╛рде рдХрдВрдХреНрд░реАрдЯрд┐рдВрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдПрдХ рдирдпрд╛ рд╡рд░реНрдЧ рд╕реНрддрд░ рдореЗрдВ рдЧрд╣рд░рд╛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рд╕реНрдЯреИрдХ рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЕрдиреНрдпрдерд╛ рд╣рдо рд╕реНрдЯреИрдХ рд╕реЗ рддрддреНрд╡реЛрдВ рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рд╣рдо рдиреЗрд╕реНрдЯрд┐рдВрдЧ (рдФрд░ рдПрдХ рдХрдо рдХрдо) рдХреЗ рд╡рд░реНрддрдорд╛рди рд╕реНрддрд░ рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪ рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рд╕реНрдЯреИрдХ рдореЗрдВ рдПрдХ рдирдпрд╛ рд╡рд░реНрдЧ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред

рд╡рд┐рдЪрд╛рд░ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЖрдЧреЗ рд╣реИред

рдкрд╛рдпрдерди рд╕реБрд╡рд┐рдзрд╛рдПрдБ


рд╕реНрдкрд╖реНрдЯ рд╕рдорд╕реНрдпрд╛ рдиреЗрд╕реНрдЯрд┐рдВрдЧ рдХреЗ рд╕реНрддрд░ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрд╛рдпрдерди рдЯреИрдм (рдпрд╛ рд╕реНрдкреЗрд╕) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЬреЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдФрд░ рд▓реЗрдХреНрд╕рд░ рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реБрд▓рдн рд╣реИред рдмрд╛рдЗрд╕рди рдореИрдиреБрдЕрд▓ рдХрд╛ рдХрд╣рдирд╛ рд╣реИ рдХрд┐ yylloc рдХреЛ yylloc рдЧреНрд▓реЛрдмрд▓ рд╡реИрд░рд┐рдПрдмрд▓ рдореЗрдВ рдкрд╛рда рдореЗрдВ рдмрд╕ рдкрд╛рд░реНрд╕ рдХрд┐рдП рдЧрдП рдЯреЛрдХрди рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдЙрдореНрдореАрдж рд╣реИред

yylloc рдЪрд╛рд░ рддрддреНрд╡реЛрдВ рдХреА рдПрдХ рд╕рдВрд░рдЪрдирд╛ рд╣реИ: first_line, first_column, last_line last_column ред first_line рд╣рдо рд╡рд░реНрддрдорд╛рди рд▓рд╛рдЗрди рдХреА рд╕рдВрдЦреНрдпрд╛ (рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИ, рдФрд░ рдпрд╣ рдореЗрд░реЗ рдХрд╛рдо рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ) рдХреЛ last_column рдХрд░реЗрдЧрд╛, last_column рд╣рдо рдЗрдВрдбреЗрдВрдЯ рд░рдЦреЗрдВрдЧреЗред

рд╣рдо рдХреЛрдб рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрд╕рд░ рдореЗрдВ, yylloc рдЪрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рд▓рд╛рдЗрди рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ:
 extern YYLTYPE yylloc; #define YY_USER_INIT yylloc.first_line=1; // =0 

рдЬрдм рд╣рдо рдПрдХ рдирдИ рдкрдВрдХреНрддрд┐ рдХреЛ рдкреВрд░рд╛ рдХрд░рддреЗ рд╣реИрдВ:
 yylloc.first_line++; yylloc.last_column = 0; isNewLine = true; 

рдпрджрд┐ рдХреЛрдИ рд░реЗрдЦрд╛ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ:
 if (isNewLine == true && 0 == yyleng % SPACES_PER_INDENT) yylloc.last_column = yyleng / SPACES_PER_INDENT; isNewLine = false; 

yyleng - рдЯреЗрдореНрдкрд▓реЗрдЯ рджреНрд╡рд╛рд░рд╛ рдкрд╛рдпрд╛ рдЧрдпрд╛ рдЯреЛрдХрди рдХреА рд▓рдВрдмрд╛рдИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, SPACES_PER_INDENT рдХреЛ 4 (рдорд╛рдирдХ рджреНрд╡рд╛рд░рд╛) рд╕реЗрдЯ рдХрд░реЗрдВред

рдпрджрд┐ рдкрдВрдХреНрддрд┐ рдЯреИрдм рд╡рд░реНрдг рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ:
 if (isNewLine == true) yylloc.last_column = yyleng; isNewLine = false; 

рдЕрдм рд╣рдо рд▓рд╛рдЗрди рдХрд╛рдЙрдВрдЯ рдХреЛ рд╕рд╣реА рдХрд░реЗрдВрдЧреЗред рдЕрдЬрдЧрд░ рдореЗрдВ рдЯреНрд░рд┐рдкрд▓ рдЙрджреНрдзрд░рдг рд╣реИрдВ, рдЖрдорддреМрд░ рдкрд░ рдкреНрд░рд▓реЗрдЦрди рдкрд░ рд▓рдВрдмреА рдЯрд┐рдкреНрдкрдгреА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрдкреЗрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрддреЗ рд╣реИрдВ:
 static string skipMessage(string _ch){ string ch; string str = _ch; _ch = _ch[0]; bool skip = false; int count = 1; for(;;ch = yyinput()) { str += ch; if (ch == _ch){ if (count == 3) return str; else count++; } else count = 1; if ("\n" == ch || "\r" == ch) yylloc.first_line++; } } 

рдпрд╣рд╛рдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд╕рд╛рде рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рд▓рд╛рдЗрди рд╕рдВрдЦреНрдпрд╛ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрдЧрд╛ - рд╣рдо regexp рджреНрд╡рд╛рд░рд╛ рдЦрд╛рдП рдЧрдП рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ (рдпрд╛ рд╣рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдпрджрд┐ рд╣рд╛рдВ, рддреЛ рд╡рд┐рдзрд┐ рд▓рд┐рдЦреЗрдВ)ред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЯрд┐рдкреНрдкрдгреА рд▓рд╛рдЗрди рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рди рднреВрд▓реЗрдВ:
 static void skipComments(){ for(char ch = yyinput();;ch = yyinput()) { if ('\0' == ch || '\n' == ch || '\r' == ch) { yylloc.first_line++; break; } } } 


рд╣рдо рд╕реНрдЯреИрдХ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред

рдиреЗрд╕реНрдЯрд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░реЗрдВ


рд╣рдо рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реИрдВред

рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
 typedef pair <string, int> meta_data; // <_, > typedef stack <meta_data> meta_stack; static meta_stack class_st; 

рд╣рдордиреЗ рд╕реНрдЯреИрдХ рдкрд░ <__, > рдХреА рдПрдХ рдЬреЛрдбрд╝реА рд▓рдЧрд╛рдИ
 class_def: CLASS classname inheritance COLON suite { int indent = @1.last_column; //    meta_data new_class($2, indent); clean_stack( class_st, indent ); class_st.push( new_class ); } ; 

рд╡рд░реНрддрдорд╛рди рдЗрдВрдбреЗрдВрдЯ рд╕реЗ рдкрд╣рд▓реЗ рд╕реНрдЯреИрдХ рдХреЛ рдЦрд╛рд▓реА рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп:
 static void clean_stack( meta_stack& stack, int indent ) { while(!stack.empty()) { if( indent > stack.top().second ) break; stack.pop(); } } 

рдЦреИрд░, рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреВрд░рд╛ рдирд╛рдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
 func_def: DEF funcname LBRACE func_args_list RBRACE COLON suite { string fnc_name = $2; int indent = @1.last_column; clean_stack( class_st, indent ); meta_stack tmp_class_st(class_st); while (!tmp_class_st.empty()) { fnc_name = tmp_class_st.top().first + "." + fnc_name; tmp_class_st.pop(); } } 


рдирд┐рд╖реНрдХрд░реНрд╖


рдореИрдВрдиреЗ рд▓реЗрдЦ рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рдгрд╛ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд╕рдорд╛рди рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕рдХреА рдЕрдкрдиреА рдХрдард┐рдирд╛рдЗрдпрд╛рдВ рд╣реИрдВред рдЕрдЧрд░ рд░реБрдЪрд┐ рд╣реИ - рдпрд╣рд╛рдБ github рдкрд░ рдореЗрд░реА рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╣реИ: https://github.com/sagod/pyparser ред рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ, рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ рдФрд░ рдкреВрд▓ рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред

рд╕рд╛рд╣рд┐рддреНрдп


Source: https://habr.com/ru/post/In141756/


All Articles