рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рд╣рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рдЕрдкрдирд╛ рдХрдВрдкрд╛рдЗрд▓рд░ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдореИрдВ рдЦреБрдж рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рд╕рдВрдХрд▓рдХ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдЕрднрд┐рдЬрд╛рдд рд╡рд░реНрдЧ рдХреА рдирд┐рдпрддрд┐ рд╣реИ, рдФрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдирд╢реНрд╡рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЗрд╕ рд╡рд┐рдЬреНрдЮрд╛рди рдХреЛ рд╕рдордЭ рдирд╣реАрдВ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рдпрд╣ рд╕рд╛рдмрд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИред
рдПрдХ рдкреЛрд╕реНрдЯ рдореЗрдВ, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЖрдк рдЕрдкрдиреА рд╕реА-рд▓рд╛рдЗрдХ рднрд╛рд╖рд╛ рд╕рдВрдХрд▓рдХ рдХреЛ рдПрдХ рдШрдВрдЯреЗ рд╕реЗ рднреА рдХрдо рд╕рдордп рдореЗрдВ рдХреИрд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЛрдб рдХреА рд╕рд┐рд░реНрдл 300 рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд▓рд┐рдЦрдХрд░ред рдПрдХ рдмреЛрдирд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдЗрд╕рдореЗрдВ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХреЛрдб рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд╕реНрд░реЛрдд рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рд╕рдВрдХрд▓рдирдХрд░реНрддрд╛ рдкрд╛рдпрдерди рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рдПрдЧрд╛ред рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рднрд╛рд╖рд╛ рд╕реЗ рдкреНрдпрд╛рд░ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдХреЛрдб рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ рдЕрдирд╛рдбрд╝реА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЕрдЧрд░ рдХреБрдЫ рдЧрд▓рдд рд╣реИ - рдПрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдореЗрдВ рд▓рд┐рдЦреЗрдВред
рд╣рд╛рдВ, рдХрдВрдкрд╛рдЗрд▓рд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмреНрд▓рдВрдЯрд▓реА рд╣реИ рдЬреЛ рдЯрд╛рдЗрдиреА-рд╕реА рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред
рд╡реНрдпрд╛рдХрд░рдг
рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рддрдп рдХрд░реЗрдВ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣рдорд╛рд░реА рднрд╛рд╖рд╛ рдХреНрдпрд╛ рдХрд░ рдкрд╛рдПрдЧреАред
рд╡рд╣ рдмрд╣реБрдд рдХрдо рдХрд░ рдкрд╛рдПрдЧреА:
- рдХреЗрд╡рд▓ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдЗрдВрдЯ рд╣реИ
- рд╕рднреА рдЪрд░ рд╡реИрд╢реНрд╡рд┐рдХ рд╣реИрдВред рдХреБрд▓ рдореЗрдВ 26 рдЪрд░ рд╣реИрдВ (az)
- рдЧрдгрд┐рддреАрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдХреЗрд╡рд▓ "+" рдФрд░ "-" рд╕рдорд░реНрдерд┐рдд рд╣реИрдВ
- рдПрдХрдорд╛рддреНрд░ рддреБрд▓рдирд╛ рдСрдкрд░реЗрдЯрд░ "<" рд╣реИ
- рднрд╛рд╖рд╛ рдирд┐рд░реНрдорд╛рдгреЛрдВ рд╕реЗ - рд╕рд╢рд░реНрдд рдХрдерди рдпрджрд┐, рдпрджрд┐ / рдирд╣реАрдВ рддреЛ, рдЬрдмрдХрд┐, рдХрдм / рдХрд░рддреЗ рд╣реИрдВ
рд╡рд╣ рд╕рдм рд╣реИред рдХреЛрдИ рд╕рд░рдгрд┐рдпрд╛рдБ, рдХрд╛рд░реНрдп, рд╕рдВрд░рдЪрдирд╛рдПрдВред рдпрд╣рд╛рдБ рд╣рдорд╛рд░реА рднрд╛рд╖рд╛ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд╡реНрдпрд╛рдХрд░рдг рд╣реИ:
<program> ::= <statement> <statement> ::= "if" <paren-expr> <statement> | "if" <paren-expr> <statement> "else" <statement> | "while" <paren-expr> <statement> | "do" <statement> "while" <paren-expr> | "{" { <statement> } "}" | <expr> ";" | ";" <paren-expr> ::= "(" <expr> ")" <expr> ::= <test> | <id> "=" <expr> <test> ::= <sum> | <sum> "<" <sum> <sum> ::= <term> | <sum> "+" <term> | <sum> "-" <term> <term> ::= <id> | <int> | <paren-expr> <id> ::= "a" | "b" | ... | "z" <int> ::= <digit>, { <digit> } <digit> ::= "0" | "1" | ... | "9"
рдпрд╣
EBNF рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╡реНрдпрд╛рдХрд░рдг рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рд╣реИред рдпрд╣рд╛рдБ рдЗрд╕ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХрд╛ рдореЛрдЯреЗ рддреМрд░ рдкрд░ рдорддрд▓рдм рд╣реИред
рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рдПрдХрд▓ рдХрдерди рд╣реИред
рдСрдкрд░реЗрдЯрд░реНрд╕ рд╕рд╢рд░реНрдд рд╣реИрдВ (рдпрджрд┐..рдмреЗрд▓ ...), рдЪрдХреНрд░реАрдп (рдЬрдмрдХрд┐ ...), рдФрд░ рдмрд╕ рдСрдкрд░реЗрдЯрд░ (рдЬреИрд╕реЗ, "a = 2 + 3")ред
рд╕рд╢рд░реНрдд рдФрд░ рдЪрдХреНрд░реАрдп рдореЗрдВ рдПрдХ рд╕реНрдерд┐рддрд┐ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдФрд░ рдПрдХ рд╢рд░реАрд░ (рдПрдХ рдСрдкрд░реЗрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ) рд╣реЛрддрд╛ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рдСрдкрд░реЗрдЯрд░ рдЕрд░реНрдзрд╡рд┐рд░рд╛рдо рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВред рдЖрдк рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЛ рдмреНрд░реЗрд╕рд┐рдЬрд╝ рдореЗрдВ рд╕рдореВрд╣рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╣рдо рдПрдХ рдХрдВрдкрд╛рдЙрдВрдб рдСрдкрд░реЗрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рднрд╛рд╡ рдпрд╛ рддреЛ рдпреЛрдЧ рд╣реИрдВ рдпрд╛ рдХрд┐рд╕реА рдорд╛рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЪрд░ рдХрд╛ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯред
рдпрд╣рд╛рдБ, рдпреЛрдЧ рд╢рдмреНрджреЛрдВ рдХреЗ рдЬреЛрдбрд╝-рдШрдЯрд╛рд╡ рдХрд╛ рдПрдХ рдХреНрд░рдо рд╣реИред
рдПрдХ рд╢рдмреНрдж рдХреЛрд╖реНрдардХреЛрдВ рдореЗрдВ рдПрдХ рд╕рдВрдЦреНрдпрд╛, рдЪрд░ рдпрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реИред
рдЪрд░ z рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд░реНрдг рд╣реИрдВред рд╕рдВрдЦреНрдпрд╛рдПрдБ 0 рд╕реЗ 9 рддрдХ рдХреА рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╣реИрдВред
рдЗрди рд╕рднреА рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдХреЛ рд╕рдВрдХрд▓рдХ рдХреЛ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рд╕реНрд░реЛрдд рдХреЛрдб рдХрд╛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо "рдЕрдЧрд░" рд╢рдмреНрдж рд╕реЗ рдорд┐рд▓рддреЗ рд╣реИрдВ - рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдХреЛрд╖реНрдардХ рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпрд╛рдБ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИрдВ, рдЗрд╕рдХреЗ рдмрд╛рдж рдСрдкрд░реЗрдЯрд░ред
рд▓реЗрдХреНрд╕рд┐рдХрд▓ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ
рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ рдЯреЗрдХреНрд╕реНрдЯ рдлрд╝рд╛рдЗрд▓ (рд╕реНрд░реЛрдд) рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЯреЛрдХрди рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП
рдПрдХ рд╢рд╛рдмреНрджрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╛рдиреА рд▓рд╛рдЗрди "a = 3 + 42;" рд▓реЗрдХреНрд╕рд┐рдХрд▓ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЛ "рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛: рдПрдХ", "рдСрдкрд░реЗрдЯрд░ =", "рдирдВрдмрд░ 3", "рдСрдкрд░реЗрдЯрд░ +", "рд╕рдВрдЦреНрдпрд╛ 42", "рдЪрд░рд┐рддреНрд░" рдХреЗ рд░реВрдк рдореЗрдВ рдореМрдЬреВрдж рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХреНрд╕рд┐рдХрд▓ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЗрд╡рд▓ рдЕрдХреНрд╖рд░реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреНред рдЙрд╕рдХреЗ рд▓рд┐рдП, рд▓рд╛рдЗрди "рдЕрдм рдЕрдЧрд░ =" рднреА рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдФрд░ рдмрд┐рд▓реНрдХреБрд▓ рд╕рд╣реА рд╣реИред
рддреЛ, рд╣рдорд╛рд░реЗ рд╢рд╛рдмреНрджрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЯреЛрдХрди рдХреЛ рдкрд╣рдЪрд╛рдирдирд╛ рдЪрд╛рд╣рд┐рдП:
- рд╕рдВрдЦреНрдпрд╛
- рдЪрд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛
- рдХреАрд╡рд░реНрдб: рдпрджрд┐, рдФрд░, рдЬрдмрдХрд┐, рдХрд░рддреЗ рд╣реИрдВ
- рд╡рд░реНрдг +, -, <, =, {,}, (,),;
- рдлрд╛рдЗрд▓ рдХрд╛ рдЕрдВрдд
рдпрд╣рд╛рдБ рдЗрд╕рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:
class Lexer: NUM, ID, IF, ELSE, WHILE, DO, LBRA, RBRA, LPAR, RPAR, PLUS, MINUS, LESS, \ EQUAL, SEMICOLON, EOF = range(16)
рдЕрдЧрд▓реЗ_рдЯреЙрдХ () рд╡рд┐рдзрд┐ рдореЗрдВ, рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдЕрдЧрд▓реЗ рдЯреЛрдХрди рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдЯреЛрдХрди рдХрд╛ рдкреНрд░рдХрд╛рд░ рдорд╛рди рд╡рд┐рд╢реЗрд╖рддрд╛ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдорд╛рди (рдпрджрд┐ рдпрд╣ рдПрдХ рдЪрд░ рдпрд╛ рд╕рдВрдЦреНрдпрд╛ рд╣реИ) рдорд╛рди рд╡рд┐рд╢реЗрд╖рддрд╛ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рдХреА рдЕрдирджреЗрдЦреА рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╡рд░реНрддрдорд╛рди рдЪрд░рд┐рддреНрд░ рднрд╛рд╖рд╛ рдХрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЪрд░рд┐рддреНрд░ рд╣реИ, рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдВрдЦреНрдпрд╛ рдпрд╛ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдпрд╛рдиреА рдЕрдВрдХ 1 рд╕реЗ рдореБрд▓рд╛рдХрд╛рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рд╡рд░реНрдгреЛрдВ рдХреЛ рдШрдЯрд╛рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдпрд╣ рдПрдХ рдЧреИрд░-рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдЪрд░рд┐рддреНрд░ рдХрд╛ рд╕рд╛рдордирд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЙрд╕реА рддрд░рд╣ рд╕реЗ рдЬрд╛рдВрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЕрдХреНрд╖рд░ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрдЬрд╛рдп)ред
рдкрд╛рд░реНрд╕рд░
рдпрд╣ рд╢рд╛рдпрдж рд╣рдорд╛рд░реЗ рд╕рдВрдХрд▓рдХ рдХрд╛ рд╕рдмрд╕реЗ рдЬрдЯрд┐рд▓ рдШрдЯрдХ рд╣реИред рд▓реЗрдХреНрд╕рд┐рдХрд▓ рдПрдирд╛рд▓рд╛рдЗрдЬрд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдЯреЛрдХрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдЙрдирдХрд╛ рдХрд╛рд░реНрдп
рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡реГрдХреНрд╖ рдмрдирд╛рдирд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдкрджрд╛рдиреБрдХреНрд░рдо рдФрд░ рд╕рдВрдмрдВрдз рдХреЛрдб рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
"if (a < 0) a = 5;" IF +-LESS | +-VAR(a) | +-NUM(0) +-SET +-VAR(a) +-NUM(5)
рдкреЗрдбрд╝ рдЬреЛ рдкрд╛рд░реНрд╕рд░ рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЙрд╕рдореЗрдВ рдиреЛрдбреНрд╕ рд╣реЛрддреЗ рд╣реИрдВред рдПрдХ рдиреЛрдб рдореЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ (IF, LESS, SET, VAR ...), рдПрдХ рдорд╛рди (рдпрджрд┐ рдпрд╣ рдПрдХ рд╕рдВрдЦреНрдпрд╛ рдпрд╛ рдПрдХ рдЪрд░ рд╣реИ), рдФрд░ рдХрдИ рдмрд╛рд▓ рдСрдкрд░реЗрдВрдб рдиреЛрдбреНрд╕ (рдХреЛрдб рдореЗрдВ - op1, op2, op3) рд╣реИрдВред рдпрджрд┐ рдХреЗ рд▓рд┐рдП, рд╕реНрдерд┐рддрд┐ рдФрд░ рдлрд┐рд░ / рдЕрдиреНрдп рд╢рд╛рдЦрд╛рдПрдВ рдЙрдирдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рддреА рд╣реИрдВ, рддреЛ рд▓реВрдк рдХреЗ рд▓рд┐рдП, рд▓реВрдк рдХреА рд╕реНрдерд┐рддрд┐ рдФрд░ рд╢рд░реАрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрддреЗ рд╣реИрдВред
рдиреЛрдбреНрд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╡рд░реНрдЧ рдиреЛрдб рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдкрд╛рд░реНрд╕рд░ рд╡рд░реНрдЧ рдФрд░ рдиреЛрдб рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдХреЛрдб рд╣реИ:
class Node: def __init__(self, kind, value = None, op1 = None, op2 = None, op3 = None): self.kind = kind self.value = value self.op1 = op1 self.op2 = op2 self.op3 = op3 class Parser: VAR, CONST, ADD, SUB, LT, SET, IF1, IF2, WHILE, DO, EMPTY, SEQ, EXPR, PROG = range(14) def __init__(self, lexer): self.lexer = lexer def error(self, msg): print 'Parser error:', msg sys.exit(1) def term(self): if self.lexer.sym == Lexer.ID: n = Node(Parser.VAR, self.lexer.value) self.lexer.next_tok() return n elif self.lexer.sym == Lexer.NUM: n = Node(Parser.CONST, self.lexer.value) self.lexer.next_tok() return n else: return self.paren_expr() def summa(self): n = self.term() while self.lexer.sym == Lexer.PLUS or self.lexer.sym == Lexer.MINUS: if self.lexer.sym == Lexer.PLUS: kind = Parser.ADD else: kind = Parser.SUB self.lexer.next_tok() n = Node(kind, op1 = n, op2 = self.term()) return n def test(self): n = self.summa() if self.lexer.sym == Lexer.LESS: self.lexer.next_tok() n = Node(Parser.LT, op1 = n, op2 = self.summa()) return n def expr(self): if self.lexer.sym != Lexer.ID: return self.test() n = self.test() if n.kind == Parser.VAR and self.lexer.sym == Lexer.EQUAL: self.lexer.next_tok() n = Node(Parser.SET, op1 = n, op2 = self.expr()) return n def paren_expr(self): if self.lexer.sym != Lexer.LPAR: self.error('"(" expected') self.lexer.next_tok() n = self.expr() if self.lexer.sym != Lexer.RPAR: self.error('")" expected') self.lexer.next_tok() return n def statement(self): if self.lexer.sym == Lexer.IF: n = Node(Parser.IF1) self.lexer.next_tok() n.op1 = self.paren_expr() n.op2 = self.statement() if self.lexer.sym == Lexer.ELSE: n.kind = Parser.IF2 self.lexer.next_tok() n.op3 = self.statement() elif self.lexer.sym == Lexer.WHILE: n = Node(Parser.WHILE) self.lexer.next_tok() n.op1 = self.paren_expr() n.op2 = self.statement(); elif self.lexer.sym == Lexer.DO: n = Node(Parser.DO) self.lexer.next_tok() n.op1 = self.statement() if self.lexer.sym != Lexer.WHILE: self.error('"while" expected') self.lexer.next_tok() n.op2 = self.paren_expr() if self.lexer.sym != Lexer.SEMICOLON: self.error('";" expected') elif self.lexer.sym == Lexer.SEMICOLON: n = Node(Parser.EMPTY) self.lexer.next_tok() elif self.lexer.sym == Lexer.LBRA: n = Node(Parser.EMPTY) self.lexer.next_tok() while self.lexer.sym != Lexer.RBRA: n = Node(Parser.SEQ, op1 = n, op2 = self.statement()) self.lexer.next_tok() else: n = Node(Parser.EXPR, op1 = self.expr()) if self.lexer.sym != Lexer.SEMICOLON: self.error('";" expected') self.lexer.next_tok() return n def parse(self): self.lexer.next_tok() node = Node(Parser.PROG, op1 = self.statement()) if (self.lexer.sym != Lexer.EOF): self.error("Invalid statement syntax") return node
рдпрд╣ рдкрд╛рд░реНрд╕рд░ рдкрд╛рд░реНрд╕ () рдкрджреНрдзрддрд┐ рд╕реЗ рд╢реБрд░реВ рд╣реЛрдХрд░ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╡рд╣ "рдкреНрд░реЛрдЧреНрд░рд╛рдо" рдиреЛрдб рдмрдирд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдмрдЪреНрдЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛ рдореБрдЦреНрдп рдСрдкрд░реЗрдЯрд░ рдмрди рдЬрд╛рддрд╛ рд╣реИред
рдСрдкрд░реЗрдЯрд░ рдХрдерди () рд╡рд┐рдзрд┐ рдореЗрдВ рдЙрддреНрдкрдиреНрди рд╣реЛрддреЗ рд╣реИрдВред рдЗрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ, рдкрд╣рд▓реЗ рдЯреЛрдХрди рдХреА рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдпрджрд┐, рдЕрдЧрд░ / рдФрд░, рдЬрдмрдХрд┐, рдХрд░рддреЗ / рдХрд░рддреЗ рд╕рдордп, рдПрдХ рдпреМрдЧрд┐рдХ рдХрдерди (рдпрджрд┐ рдпрд╣ рдПрдХ рдШреБрдВрдШрд░рд╛рд▓реЗ рдмреНрд░реЗрд╕ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ), рдпрд╛ рдЕрд░реНрдзрд╡рд┐рд░рд╛рдо рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рд╡рд╛рд▓рд╛ рд╕рд┐рд░реНрдл рдПрдХ рдмрдпрд╛рди рдмрдирддрд╛ рд╣реИред
рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╕рдордп, рдПрдХреНрд╕рдкреНрд░реЗрд╢рди () рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдФрд░ paren_expr () - рдмреНрд░реИрдХреЗрдЯ рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЙрди рдЪреЗрдХ рд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдЙрди рд╢рдмреНрджреЛрдВ рд╕реЗ рдирд┐рд░реНрдорд┐рдд рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рд╢рдмреНрджреЛрдВ рд╕реЗ рдпреБрдХреНрдд рд╣реЛрддреЗ рд╣реИрдВред рдФрд░, рдмрджрд▓реЗ рдореЗрдВ, рдХреЛрд╖реНрдардХреЛрдВ рдореЗрдВ рд╕рдВрдЦреНрдпрд╛рдУрдВ, рдЪрд░ рдФрд░ рднрд╛рд╡реЛрдВ рд╕реЗ рдорд┐рд▓рдХрд░ рдмрдирддрд╛ рд╣реИред рдЙрд╕ рдШрд░ рдореЗрдВ рдЬрд┐рд╕реЗ рдЬреИрдХ рдиреЗ рдмрдирд╡рд╛рдпрд╛ рдерд╛ред
рдРрд╕реА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╡рд┐рдзрд┐рдпрд╛рдБ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рд╡реНрдпрд╛рдХрд░рдг рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВред
рдкрд╛рд░реНрд╕ () рд╡рд┐рдзрд┐ рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ, рд╣рдореЗрдВ рдХрдХреНрд╖рд╛ рдиреЛрдб рдХреА рдПрдХ рд╡рд╕реНрддреБ рдорд┐рд▓рддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдкреЗрдбрд╝ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕ рдкреЗрдбрд╝ рдХреЛ рдЕрдм рдорд╢реАрди рдХреЛрдб рдореЗрдВ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдорд╢реАрди рдХреЛрдб
рд╣рдо рдЕрдкрдиреЗ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдмрд╛рдпреЛрдЯреЗрдХ рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВрдЧреЗред рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХреЛ рд╕реНрдЯреИрдХ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИрдВред рдпрд╣рд╛рдБ рдЙрд╕рдХреЗ рд╕рдВрднрд╛рд╡рд┐рдд рдирд┐рд░реНрджреЗрд╢ рд╣реИрдВ:
FETCH x - x STORE x - x PUSH n - n POP - ADD - SUB - LT - (a < b). - 0 1 JZ a - 0 - a. JNZ a - 0 - a. JMP a - a HALT -
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдСрдкрд░реЗрдЯрд░ "рдП = 2; b = 5; "рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
PUSH 2 STORE 0 PUSH 5 STORE 1
рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХреЛрдб рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рдпрд╣ рд╕рднреА рд░рди рд╡рд┐рдзрд┐ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИ:
IFETCH, ISTORE, IPUSH, IPOP, IADD, ISUB, ILT, JZ, JNZ, JMP, HALT = range(11) class VirtualMachine: def run(self, program): var = [0 for i in xrange(26)] stack = [] pc = 0 while True: op = program[pc] if pc < len(program) - 1: arg = program[pc+1] if op == IFETCH: stack.append(var[arg]); pc += 2 elif op == ISTORE: var[arg] = stack.pop(); pc += 2 elif op == IPUSH: stack.append(arg); pc += 2 elif op == IPOP: stack.append(arg); stack.pop(); pc += 1 elif op == IADD: stack[-2] += stack[-1]; stack.pop(); pc += 1 elif op == ISUB: stack[-2] -= stack[-1]; stack.pop(); pc += 1 elif op == ILT: if stack[-2] < stack[-1]: stack[-2] = 1 else: stack[-2] = 0 stack.pop(); pc += 1 elif op == JZ: if stack.pop() == 0: pc = arg else: pc += 2 elif op == JNZ: if stack.pop() != 0: pc = arg else: pc += 2 elif op == JMP: pc = arg; elif op == HALT: break print 'Execution finished.' for i in xrange(26): if var[i] != 0: print '%c = %d' % (chr(i+ord('a')), var[i])
рдпрд╣ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрдХрд▓рдХ - рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИред
рд╕рдВрдХрд▓рдХ
рд╣рдорд╛рд░реА рд░рдЪрдирд╛ рдХрд╛ рддрд╛рдЬред рдпрд╣рд╛рдБ рдЗрд╕рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб рд╣реИ:
class Compiler: program = [] pc = 0 def gen(self, command): self.program.append(command) self.pc = self.pc + 1 def compile(self, node): if node.kind == Parser.VAR: self.gen(IFETCH) self.gen(node.value) elif node.kind == Parser.CONST: self.gen(IPUSH) self.gen(node.value) elif node.kind == Parser.ADD: self.compile(node.op1) self.compile(node.op2) self.gen(IADD) elif node.kind == Parser.SUB: self.compile(node.op1) self.compile(node.op2) self.gen(ISUB) elif node.kind == Parser.LT: self.compile(node.op1) self.compile(node.op2) self.gen(ILT) elif node.kind == Parser.SET: self.compile(node.op2) self.gen(ISTORE) self.gen(node.op1.value) elif node.kind == Parser.IF1: self.compile(node.op1) self.gen(JZ); addr = self.pc; self.gen(0); self.compile(node.op2) self.program[addr] = self.pc elif node.kind == Parser.IF2: self.compile(node.op1) self.gen(JZ); addr1 = self.pc; self.gen(0) self.compile(node.op2) self.gen(JMP); addr2 = self.pc; self.gen(0) self.program[addr1] = self.pc self.compile(node.op3) self.program[addr2] = self.pc elif node.kind == Parser.WHILE: addr1 = self.pc self.compile(node.op1) self.gen(JZ); addr2 = self.pc; self.gen(0) self.compile(node.op2) self.gen(JMP); self.gen(addr1); self.program[addr2] = self.pc elif node.kind == Parser.DO: addr = self.pc self.compile(node.op1) self.compile(node.op2) self.gen(JNZ); self.gen(addr); elif node.kind == Parser.SEQ: self.compile(node.op1) self.compile(node.op2) elif node.kind == Parser.EXPR: self.compile(node.op1); self.gen(IPOP) elif node.kind == Parser.PROG: self.compile(node.op1); self.gen(HALT) return self.program
рдЬреАрди () рд╡рд┐рдзрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо (рдмрд╛рдЗрдЯреНрд╕ рдХреА рд╕реВрдЪреА) рдореЗрдВ рдПрдХ рдирдпрд╛ рдмрд╛рдЗрдЯ (рдХрдорд╛рдВрдб рдпрд╛ рддрд░реНрдХ) рдЬреЛрдбрд╝рддрд╛ рд╣реИред
рд╕рдВрдХрд▓рди () рд╡рд┐рдзрд┐ рдкреВрд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреА рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рд╡рд┐рдзрд┐ рдиреЛрдбреНрд╕ рдХреЗ рдкреЗрдбрд╝ рдХреЛ рдкреБрди: рдЦреЛрдЬрддреА рд╣реИред рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдиреЛрдб рдХреЗ рд▓рд┐рдП рд╕рдВрдмрдВрдзрд┐рдд рдХреЛрдб рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред
рд╕рд╢рд░реНрдд рдмрдпрд╛рдиреЛрдВ рдФрд░ рдЫреЛрд░реЛрдВ рдореЗрдВ рдЪрд╛рд▓ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред JMP / JZ рдХреЗ рдмрд╛рдж, рд╣рдо рдкрд╣рд▓реЗ 0 рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдФрд░ рдЬрдм рд╢рд╛рдЦрд╛ рд╕реНрд╡рдпрдВ рд╕рдВрдХрд▓рд┐рдд рд╣реЛрддреА рд╣реИ рдФрд░ рдЬрд┐рд╕ рдкрддреЗ рдкрд░ рд╣рдореЗрдВ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЙрд╕реЗ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕ рд╢рд╛рдЦрд╛ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП - рдорд╛рди 0 рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрддреЗ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкрд░реАрдХреНрд╖рдг
рдпрд╣рд╛рдБ рдкреВрд░рд╛ рд╕рдВрдХрд▓рдХ рд╕реНрд░реЛрдд рдирд┐рд╣рд┐рдд рд╣реИред рдореИрдВрдиреЗ рдЪрд▓рд╛рдиреЗ рдФрд░ рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ (рдореЗрд░реЗ рдкрд╛рд╕ рд╕реНрдЯреИрдбрд░ рд╕реЗ рдкрдврд╝реЗ рдЧрдП рд▓реЗрдХреНрд╕рд░ рд╣реИрдВ):
echo " i = 3;" | ./cc.py echo " { a=3; b=5; }" | ./cc.py echo " { a = 1; b = 2; c = a + b; }" | ./cc.py echo " { a = 5; b = 2; c = a - b; }" | ./cc.py echo " { a = 5; b = 2; c = b < a; }" | ./cc.py echo " { a = 5; if (a < 10) a = 33; }" | ./cc.py echo " { a = 5; if (10 < a) a = 33; else { a = 1; b = 2; } }" | ./cc.py echo " { a = 10; do { a = a - 2;} while (3 < a); }" | ./cc.py echo " { a = 1; b = 5; while (a < b) { a = a + 3; }}" | ./cc.py
рдХрд╛рд░ рд╕рд╣реА рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдЧ рд░рд╣рд╛ рдерд╛ред
рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ?
рд╣рдорд╛рд░реЗ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдиреБрднрд╡ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред
рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рд╕рдВрдХрд▓рдХ рдХреЛ рдФрд░ рднреА рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдлрд┐рд░ рд╕рд░рд▓ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╡рд╛рд▓реА рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рдЙрджрд╛ред
рдЯрд╛рдЗрдиреАрдмреЗрд╕рд┐рдХ рдпрд╛
рдкреАрдПрд▓ / реж ред
рдпрджрд┐ рдЖрдк рдЕрдиреНрдп рд╕рдВрдХрд▓рдХ рдХреЗ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдЖрдкрдХреЛ рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдмреЗрд▓рд╛рд░реНрдб (
рдУрдЯреАрд╕реАрд╕реА ),
рдЯрд┐рдирд┐рдЪ ,
рдЯреАрд╕реАрд╕реА ,
рд╕реНрдореЙрд▓рдХ ,
рдПрд▓рд╕реАрд╕реА рдХреЗ рдХрд╛рдо рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред