рд╕реНрд╡рд┐рдлреНрдЯ рдХрдВрдкрд╛рдЗрд▓рд░ рдбрд┐рд╡рд╛рдЗрд╕ред рднрд╛рдЧ реи


рдореЗрд░реА рд╕реНрд╡рд┐рдлреНрдЯ рд╕рдВрдХрд▓рдХ рдХрд╣рд╛рдиреА рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧред рд╣рдо рдлреНрд░рдВрдЯ-рдПрдВрдб, рдмрд▓реНрдХрд┐ рдЗрд╕рдХреЗ рдЙрди рд╣рд┐рд╕реНрд╕реЛрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВред


рд▓реЗрдЦ рдХрд╛ рдкрд╣рд▓рд╛ рднрд╛рдЧ рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред


рджреГрд╢реНрдпрдкрдЯрд▓





рдлреНрд░рдВрдЯреЗрдВрдб рдХрд╛ рдХрд╛рд░реНрдп рд╕реНрд░реЛрдд рдХреЛрдб рд╕реЗ рдПрдХ рдордзреНрдпрд╡рд░реНрддреА рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдФрд░ рдЗрд╕реЗ рдПрд▓рдПрд▓рд╡реАрдПрдо рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ 8 рдЪрд░рдгреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд▓рдЧрднрдЧ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╕рдВрдХрд▓рдХ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд░рд┐рдд рдХрд░рдХреЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдиреАрдЪреЗ рдореИрдВ рдПрдХ рдЖрджрд┐рдо "рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛" рдХреЗ рд▓рд┐рдП рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ рдЬрд┐рд╕рдореЗрдВ рдХреЗрд╡рд▓ "рдЧреБрдВрдЬрд╛рдЗрд╢" рдФрд░ рдПрдХ рд╕рдВрдЦреНрдпрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рдЗрд╕рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдХрд╛рд░реНрдп рдХрдВрд╕реЛрд▓ рдореЗрдВ рд╕рдВрдЦреНрдпрд╛ (рдпрджрд┐ рдХреЛрдИ рд╣реЛ) рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рдирд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ "рдХреЛрдб" рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╕рдВрдЦреНрдпрд╛ 678 рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдЧреА:


{{{678}}} 

рдЗрд╕ рд╕рдВрдХрд▓рдХ рдХреЛ рдХреЗрд╡рд▓ рдЖрдкрдХреЗ рд▓рд┐рдП рдпрд╣ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рдЪрд░рдгреЛрдВ рдореЗрдВ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред рдХреИрд▓реЗрдбреЛрд╕реНрдХреЛрдк рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ, рд▓реЗрдХрд┐рди рд╕рд░рд▓ рднрд╛рд╖рд╛ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдХреЛрдк рдореЗрдВ рдПрдХ рдУрдкрдирд┐рдВрдЧ рдмреНрд░реИрдХреЗрдЯ, рдХрдВрдЯреЗрдВрдЯ рдФрд░ рдПрдХ рдХреНрд▓реЛрдЬрд┐рдВрдЧ рдмреНрд░реИрдХреЗрдЯ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


 scope ::= open_brace x close_brace open_brace ::= "{" close_brace ::= "}" 

рд╕рд╛рдордЧреНрд░реА рд╕рдорд╛рди рдХреНрд╖реЗрддреНрд░, рд╕рдВрдЦреНрдпрд╛, рдпрд╛ рдпрд╣рд╛рдБ рдЗрдВрдЧрд┐рдд рдХреА рдЧрдИ рдХреБрдЫ рднреА рд╣реЛ рд╕рдХрддреА рд╣реИ :

 scope ::= open_brace x close_brace x ::= scope | number | <empty> open_brace ::= "{" close_brace ::= "}" 

рдкреНрд░рддреАрдХ | рдХрд╛ рдЕрд░реНрде рд╣реИ "рдпрд╛ред" рдПрдХ рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдПрдХ рдпрд╛ рдЕрдзрд┐рдХ рдЕрдВрдХ рд╣реЛрддреЗ рд╣реИрдВ:


 scope ::= open_brace x close_brace x ::= scope | number | <empty> open_brace ::= "{" close_brace ::= "}" number ::= digit | number digit digit :: = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 

рдЗрд╕ рддрд░рд╣ рдХреЗ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдмреИрдХрд╕-рдиреМрд░ (рдмреАрдПрдирдПрдл) рдлреЙрд░реНрдо рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╕рднреА рдирд┐рдпрдореЛрдВ рдХреА рд╕рдордЧреНрд░рддрд╛ рдХреЛ рднрд╛рд╖рд╛ рдпрд╛ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХрд╛ рд╡реНрдпрд╛рдХрд░рдг рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред


рдПрдХ рдмрдврд╝рд╛ рд╣реБрдЖ BPF (RBNF) рднреА рд╣реИред рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдг рдЗрд╕рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЧрдП рдереЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рдореВрд╣рди рдХреЗ рд▓рд┐рдП рдХреЛрд╖реНрдардХред


рдШреБрдВрдШрд░рд╛рд▓реЗ рдмреНрд░реЗрд╕рд┐рдЬрд╝ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВред рдЗрд╕ рддрд░рд╣ рдХреЗ рд░рд┐рдХреЙрд░реНрдб рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ A, B рдХреА рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░ рдпрд╛ рдмрд░рд╛рдмрд░ рд╣реИ:


 A ::= { B } 

рд╕реНрдХреНрд╡рд╛рдпрд░ рдмреНрд░реИрдХреЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд╢рд░реНрдд рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреЗ рд░рд┐рдХреЙрд░реНрдб рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ A рдпрд╛ рддреЛ рдЦрд╛рд▓реА рд╣реИ рдпрд╛ B рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ:


 A ::= [B] 

RBNF рдХреЛ рд▓рдШреБрдХреЛрдгреАрдп рд╕рдВрдХрд▓рдХ рдХреЗ рд╡реНрдпрд╛рдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдЗрд╕реЗ рдЗрд╕ рд░реВрдк рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 scope ::= open_brace [scope | number] close_brace open_brace ::= "{" close_brace ::= "}" number ::= digit {digit} digit :: = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 

рдХреЛрд╖реНрдардХ рд╕рдВрдХрд▓рдХ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдПрдХ рд╕рд░рд▓ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдХреЗ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд┐рдлреНрдЯ рд╕рдВрдХрд▓рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ:


 let x = 16 

рдХреЛрдб рдХреЛ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрддрдирд╛ рд╕рд░рд▓ рд╣реИред рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХрд╛ рд╡реНрдпрд╛рдХрд░рдг рдЙрдкрд░реЛрдХреНрдд рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдЖрдк рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рд╕реНрд╡рд┐рдлреНрдЯ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред


lexer


рд╕рдВрдХрд▓рдХ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рд╕реНрд░реЛрдд рдХреЛрдб рдлрд╝рд╛рдЗрд▓ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╡рд░реНрдгреЛрдВ рдХреА рдПрдХ рдзрд╛рд░рд╛ рд╣реИ, рдФрд░ рд╢рд╛рдпрдж рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХрдЪрд░рд╛ред рдЗрд╕рд▓рд┐рдП, рдкрд╣рд▓рд╛ рдЪрд░рдг рдЗрди рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╡рд░реНрдгреЛрдВ рдХреЛ рд╢рдмреНрджреЛрдВ рдореЗрдВ рдмрджрд▓рдирд╛ рд╣реИ рдЬреЛ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рдпрд╣ рд▓реЗрдХреНрд╕рд┐рдХрд▓ рдПрдирд╛рд▓рд╛рдЗрдЬрд╝рд░ (lexer / tokenizer) рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд╣ рдЬреЛ рд╢рдмреНрдж рдЪрд╛рд╣рддрд╛ рд╣реИ, рдЙрд╕реЗ рдЯреЛрдХрди рдпрд╛ рдЯреЛрдХрди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ (рд╣рдо рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╡рд┐рд╡рд░рдгреЛрдВ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдПрдВрдЧреЗ рдФрд░ рдЗрди рд╢рдмреНрджреЛрдВ рдХреЛ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдВрдЧреЗ)ред рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЯреЛрдХрди рднреА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред


рд▓реЗрдХреНрд╕рд░ рднрд╛рд╖рд╛ рдХреЗ рд╡рд╛рдХреНрдп-рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддрд╛ рд╣реИред рдкреНрд░рддреАрдХ рджреНрд╡рд╛рд░рд╛ рд╕реНрдХреИрди рдХрд░рдирд╛, рдпрд╣ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдкрддреНрд░рд╛рдЪрд╛рд░ рдФрд░ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рджрд╛рдИрдВ рдУрд░ рдкрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдмрд╛рдИрдВ рдУрд░ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЯреЛрдХрди рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред


рд▓реЗрдХреНрд╕рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЙрджрд╛рд╣рд░рдг


рд╡реНрдпрд╛рдХрд░рдг рддреАрди рдЯреЛрдХрди рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ: рдПрдХ рдЙрджреНрдШрд╛рдЯрди рдмреНрд░реИрдХреЗрдЯ, рдПрдХ рд╕рдорд╛рдкрди рдмреНрд░реИрдХреЗрдЯ рдФрд░ рдПрдХ рд╕рдВрдЦреНрдпрд╛ред рдЙрдиреНрд╣реЗрдВ рдПрдХ рдкреНрд░рддрд┐рдЬреНрдЮрд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рд╛рде рд╣реА рд╕рдВрднрд╛рд╡рд┐рдд рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА:


 enum Token: CustomStringConvertible { case openBraceToken case closeBraceToken case number(Int) var description: String { switch self { case .openBraceToken: return "openBraceToken" case .closeBraceToken: return "closeBraceToken" case .number(let value): return "\(value)" } } } enum LexerError: Error { case unexpectedCharacted case invalidNumber } 

рд▓реЗрдХреНрд╕рд░ рдореЗрдВ рд╣реА, рд╡рд░реНрддрдорд╛рди рд╡рд░реНрдг рдХреЗ рдЗрдирдкреБрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдФрд░ рдЗрдВрдбреЗрдХреНрд╕ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:


 class Lexer { private let string: String private var index: String.Index private var currentCharacter: Character? { return index != string.endIndex ? string[index] : nil } init(string: String) { self.string = string index = string.startIndex } 

рд╡рд┐рд╢реНрд▓реЗрд╖рдг startAnalyze () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдореЗрдВ, рдЕрдЧрд▓реЗ рдЯреЛрдХрди рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдХреЛ рд▓реВрдк рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╕рд░рдгреА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдВрдд рдореЗрдВ - рдорд╛рдиреНрдпрддрд╛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдЕрд╡рд░реЛрдзрди:


 func startAnalyzing() -> [Token] { var result: [Token] = [] do { while let token = try getNextToken() { result.append(token) } } catch LexerError.unexpectedCharacted { print("Unexpected character at index \(index.encodedOffset)") result = [] } catch LexerError.invalidNumber { print("Invalid number at index \(index.encodedOffset)") result = [] } catch { print("Unexpected error") result = [] } return result } 

рдЯреЛрдХрди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╡рд░реНрддрдорд╛рди рд╡рд░реНрдг рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рдФрд░ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЛ рдПрдХ рдпрд╛ рдЕрдзрд┐рдХ рд╡рд░реНрдгреЛрдВ рдХреЛ рдЖрдЧреЗ рдмрдврд╝рд╛рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ:


 private func getNextToken() throws -> Token? { guard let character = currentCharacter else { return nil } switch character { case "{": return getOpenBrace() case "}": return getCloseBrace() default: break } if let scalar = character.unicodeScalars.first, CharacterSet.decimalDigits.contains(scalar) { return try getNumber() } throw LexerError.unexpectedCharacted } private func getOpenBrace() -> Token { moveIndex() return Token.openBraceToken } private func getCloseBrace() -> Token { moveIndex() return Token.closeBraceToken } 

рдпрджрд┐ рдХреЛрдИ рдЕрдВрдХ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЧреЗрдЯрдирдВрдмрд░ () рд╡рд┐рдзрд┐ рдХреЛ рдЗрд╕реЗ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдмрд╕ рд╕рднреА рдЕрдВрдХреЛрдВ рдХреЛ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдПрдХрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ Int рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ:


 private func getNumber() throws -> Token { var numberString = "" while let character = currentCharacter, let scalar = character.unicodeScalars.first, CharacterSet.decimalDigits.contains(scalar) { numberString.append(character) moveIndex() } guard let number = Int(numberString) else { throw LexerError.invalidNumber } return Token.number(number) } 

рд▓реЗрд╕рд░ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЗрд╕реЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рд▓рд╛рдЗрди рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдирд▓реАрдЬрд╝ () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ:


 let lexer = Lexer(string: "{{5678}}") let tokens = lexer.startAnalyzing() 

рдкрд░рд┐рдгрд╛рдо рдЕрдкреЗрдХреНрд╖рд╛рдУрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ:


 [openBraceToken, openBraceToken, 5678, closeBraceToken, closeBraceToken] 

рд╕реНрд╡рд┐рдлреНрдЯ рдореЗрдВ, рд▓реЗрд╕рд░ рдкрд╛рд░реНрд╕рд░ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдЕрдиреБрд░реВрдк рдЯреЛрдХрди рдХреА рд╕реВрдЪреА рдирд╣реАрдВ рдорд┐рд▓ рд╕рдХрддреА рд╣реИред


рд╕реНрд░реЛрдд рдХреЛрдб:



рдкрд╛рд░реНрд╕рд░


рдкрд╛рд░реНрд╕рд░ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХрд░рддрд╛ рд╣реИред рдЯреЛрдХрди рдХрд╛ рдПрдХ рдЕрдиреБрдХреНрд░рдо рдЗрдирдкреБрдЯ рдХреЛ рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдХрд╛рд░реНрдп рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдПрд╕рдЯреА рд╣реИред


рдПрдПрд╕рдЯреА рдПрдХ рдЧреНрд░рд╛рдл рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХреЛрдиреЗ рдСрдкрд░реЗрдЯрд░ рд╣реИрдВ рдФрд░ рдкрддреНрддрд┐рдпрд╛рдВ рдЙрдирдХреЗ рдСрдкрд░реЗрдВрдб рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ 1 + (2 * 3) рдореЗрдВ рджреЛ рдСрдкрд░реЗрдЯрд░ рд╣реЛрддреЗ рд╣реИрдВ: рдЬреЛрдбрд╝ рдФрд░ рдЧреБрдгрд╛ред рдЬреЛрдбрд╝ рдХрд╛ рдкрд╣рд▓рд╛ рдСрдкрд░реЗрдВрдб 1 рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рдЙрддреНрдкрд╛рджреЛрдВ 2 рдФрд░ 3 рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред рдЧреНрд░реБрдкрд┐рдВрдЧ рдмреНрд░реИрдХреЗрдЯ рдПрдПрд╕рдЯреА рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИрдВред рдЧреНрд░рд╛рдлрд╝ рд╕реНрд╡рдпрдВ рдСрдкрд░реЗрд╢рдиреЛрдВ рдХреЗ рдШреЛрдВрд╕рд▓реЗ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рддрд╛ рд╣реИ:





рдкреНрд░рддреНрдпреЗрдХ рдиреЛрдб рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдпрд╛ рдмрд╛рд▓ рддрддреНрд╡реЛрдВ рд╕реЗ рдпреБрдХреНрдд рдПрдХ рдЧрдгрдирд╛ рджреНрд╡рд╛рд░рд╛ред


рдкреЗрдбрд╝ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рджреМрд░рд╛рди, рдкрд╛рд░реНрд╕рд░ рднрд╛рд╖рд╛ рдХреЗ рд╡реНрдпрд╛рдХрд░рдг рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ: рдХреНрдпрд╛ рд╕рд╣реА рдЕрдиреБрдХреНрд░рдо "рд╢рдмреНрджреЛрдВ" рд╕реЗ рдмрдирд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрдЯреНрд░рд┐рдВрдЧ "{{}" рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд▓реЗрдХреНрд╕рд░ рджреНрд╡рд╛рд░рд╛ рдкрд╛рд░реНрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдЧрд▓рдд рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рджреВрд╕рд░рд╛ рд╕рдорд╛рдкрди рдмреНрд░реИрдХреЗрдЯ рдЧрд╛рдпрдм рд╣реИред


рд╕реНрд╡рд┐рдлреНрдЯ рдкрд╛рд░реНрд╕рд░ рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдЕрд╡рд░реЛрд╣реА рдкрд╛рд░реНрд╕рд░ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рд╡рд╣ рдкрд╣рд▓реЗ рдПрдХ рдмрд╛рд╣рд░реА рдЗрдХрд╛рдИ рдкрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЕрдкрдиреА рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддрд╛ рд╣реИред рдЖрд░реЛрд╣реА рдкрд╛рд░реНрд╕рд░ рдкрд╣рд▓реЗ рд╕рдмрд╕реЗ рдиреЗрд╕реНрдЯреЗрдб рдЗрдХрд╛рдИ рдкрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдКрдкрд░ рдЙрдарддрд╛ рд╣реИред


рдкрд╛рд░реНрд╕рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЙрджрд╛рд╣рд░рдг


рдкрд╛рд░реНрд╕рд░реНрд╕ рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдПрдХ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рд╣реИред рдиреАрдЪреЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрдВрддрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд╡рд░реЛрд╣реА рдФрд░ рдЖрд░реЛрд╣реА рдкрд╛рд░реНрд╕рд░ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред


рджреЛрдиреЛрдВ рдкрд╛рд░реНрд╕рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдо рдПрдХ рдЧрдгрдирд╛ рд╣реЛрдЧреА рдЬреЛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдФрд░ рдПрдПрд╕рдЯреА рдиреЛрдб рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреА рд╣реИ:


 indirect enum ASTNode: CustomStringConvertible { case brace(childNode: ASTNode?) case number(value: Int) var description: String { switch self { case let .brace(childNode?): return "brace(\(childNode.description))" case .brace(nil): return "brace(nil)" case let .number(value): return "\(value)" } } } enum ParserError: Error { case expectedOpenBrace case expectedCloseBrace case expectedNumber case expectedEndOfArray } 

рдЕрд╡рд░реЛрд╣реА рдкрд░рд╕рд░


рдПрдХ рдиреАрдЪреЗ рд╡рд╛рд▓рд╛ рдкрд╛рд░реНрд╕рд░ рдЯреЛрдХрди рдХреА рдПрдХ рд╕рд░рдгреА рдФрд░ рд╡рд░реНрддрдорд╛рди рдЯреЛрдХрди рдХрд╛ рдПрдХ рд╕реВрдЪрдХрд╛рдВрдХ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ:


 class TopDownParser { private let tokens: [Token] private var index: Int private var currentToken: Token? { return index != tokens.endIndex ? tokens[index] : nil } init(tokens: [Token]) { self.tokens = tokens index = tokens.startIndex } 

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


 func startParsing() -> ASTNode? { var rootNode: ASTNode? do { rootNode = try parseBraces() guard currentToken == nil else { rootNode = nil throw ParserError.expectedEndOfArray } } catch ParserError.expectedCloseBrace { print("Expected close brace at index \(index)") } catch ParserError.expectedOpenBrace { print("Expected open brace at index \(index)") } catch ParserError.expectedEndOfArray { print("Expected end of tokens array at index \(index)") } catch { print("Unexpected error") } return rootNode } 

рдЬрдм рдХреЛрд╖реНрдардХ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЦреЛрд▓рдиреЗ рд╡рд╛рд▓реЗ рдмреНрд░реИрдХреЗрдЯ рдХреЛ рдкрд╣рд▓реЗ рд╕реНрдХреИрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рдЬреЛрдбрд╝реА (рдпрджрд┐ рдХреЛрдИ рд╣реИ) рдХреЗ рднреАрддрд░ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╕рд╛рдордЧреНрд░реА, рдФрд░ рдЕрдВрдд рдореЗрдВ рд╕рдорд╛рдкрди рдмреНрд░реИрдХреЗрдЯред


рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ: рдЬреИрд╕реЗ рд╣реА рдкрд╛рд░реНрд╕рд░ рдЙрджреНрдШрд╛рдЯрди рдмреНрд░реИрдХреЗрдЯ рдХреЛ рджреЗрдЦрддрд╛ рд╣реИ, рдпрд╣ рдорд╛рдирддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдЕрдЧрд▓реА рдЬреЛрдбрд╝реА рдХреЛ рдорд┐рд▓рд╛ рд╣реИ рдФрд░ рдЖрдк рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдпрд╣ рдмрд╛рд╣рд░реА рд╕рдВрд╕реНрдерд╛рдУрдВ рд╕реЗ рдЖрдВрддрд░рд┐рдХ рддрдХ рдЬрд╛рддрд╛ рд╣реИред


 private func parseBraces() throws -> ASTNode? { try consumeOpenBrace() print("Pair found") let node: ASTNode? if let currentToken = self.currentToken, case .openBraceToken = currentToken { node = .brace(childNode: try parseBraces()) } else if let currentToken = self.currentToken, case let .number(value) = currentToken { node = .brace(childNode: .number(value: value)) try consumeNumber() } else { node = .brace(childNode: nil) } try consumeCloseBrace() return node } 

рд╕реНрдХреИрдирд┐рдВрдЧ рдореЗрдВ рдЯреЛрдХрди рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕реВрдЪрдХрд╛рдВрдХ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ:


 private func consumeOpenBrace() throws { if let currentToken = self.currentToken, case .openBraceToken = currentToken { print("Open brace found") moveIndex() } else { throw ParserError.expectedOpenBrace } } 

рдЖрд░реЛрд╣реА рдкрд╛рд░реНрд╕рд░


рдПрдХ рдЕрдкрд╕реНрдЯреНрд░реАрдо рдкрд╛рд░реНрд╕рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдЙрд╕реЗ рдЕрдкрдирд╛ рд░рд╛рдЬреНрдп, рдЯреЛрдХрди рдХрд╛ рдПрдХ рдвреЗрд░ рдФрд░ рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рдмреАрдЪ рдПрдХ рд░реВрдкрд╛рдВрддрд░рдг рддрд╛рд▓рд┐рдХрд╛ рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


рд╕реНрдерд┐рддрд┐ рдХреЛ рдПрдХ рдкреНрд░рддрд┐рдЬреНрдЮрд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкрд┐рдЫрд▓реЗ рдЯреЛрдХрди рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдФрд░ рдПрдХ рдирдП рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХрд╛ рд╕рд╣реА рдЬрд╡рд╛рдм рджреЗрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЪреВрдВрдХрд┐ рдпрд╣ рдЙрджрд╛рд╣рд░рдг рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд░рд╛рдЬреНрдп рдореЗрдВ, рдкрд╛рд░реНрд╕рд░ рдЙрджреНрдШрд╛рдЯрди рдХреЛрд╖реНрдардХ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░реЗ рдореЗрдВ - рд╕рдорд╛рдкрди рдХреЛрд╖реНрдардХ:


 class BottomUpParser { private enum State { case state1 case state2 } 

рдкрд╛рд░реНрд╕рд░ рдХреЛ рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ рд╣реА рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рдЕрд▓рдЧ рдЗрдХрд╛рдИ рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрдИ рд╕рдВрдХреНрд░рдордг рддрд╛рд▓рд┐рдХрд╛ рдирд╣реАрдВ рд╣реИред рд╕рд░рд▓реАрдХрд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрд╡рд┐рдЪ рдЕрдкрдиреА рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рдПрдЧрд╛:


 private let tokens: [Token] private var index: Int private var state: State = .state1 private var stack: [Token] = [] private var rootNode: ASTNode? private var currentToken: Token? { return index != tokens.endIndex ? tokens[index] : nil } init(tokens: [Token]) { self.tokens = tokens index = tokens.startIndex } 

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


 func startParsing() -> ASTNode? { do { guard !tokens.isEmpty else { throw ParserError.expectedOpenBrace } while index != tokens.endIndex { try parseNextToken() moveIndex() } guard stack.isEmpty else { rootNode = nil throw ParserError.expectedCloseBrace } } catch ParserError.expectedCloseBrace { rootNode = nil print("Expected close brace at index \(index)") } catch ParserError.expectedOpenBrace { rootNode = nil print("Expected open brace at index \(index)") } catch ParserError.expectedEndOfArray { rootNode = nil print("Expected end of tokens array at index \(index)") } catch { rootNode = nil print("Unexpected error") } return rootNode } 

рд╕реНрд╡рд┐рдЪ рдореЗрдВ рдЕрдЧрд▓реЗ рдЯреЛрдХрди рдХреЛ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдПрдХ рдЙрджреНрдШрд╛рдЯрди рдмреНрд░реИрдХреЗрдЯ рдЖрддрд╛ рд╣реИ рдФрд░ рд░рд╛рдЬреНрдп 1 рд╣реИ, рддреЛ рдЗрд╕реЗ рд╕реНрдЯреИрдХ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкрд╛рд░реНрд╕рд░ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реНрдЯреИрдХ рдкрд░ рдПрдХ рдЙрджреНрдШрд╛рдЯрди рдмреНрд░реИрдХреЗрдЯ рд╣реИ, рддреЛ рдЗрд╕реЗ рд╕реНрдЯреИрдХ рд╕реЗ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИ рдФрд░ 2 рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рддрд╛ рд╣реИред рдПрдХ рдирдВрдмрд░ рдорд┐рд▓рдиреЗ рдкрд░ рджреВрд╕рд░реЗ рд░рд╛рдЬреНрдп рдореЗрдВ рд╕рдВрдХреНрд░рдордг рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


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


рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ: рдКрдкрд░ рд╡рд╛рд▓реЗ рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЛ рдиреАрдЪреЗ рдЧрд┐рд░рд╛рдиреЗ рдХреЗ рдмрд╛рдж рд╣реА рдЬреЛрдбрд╝реЗ рдХреЛ рдорд┐рд▓рд╛, рдпрд╣ рдПрдХ рд╕рдорд╛рдкрди рдХреЛрд╖реНрдардХ рджреЗрдЦрддрд╛ рд╣реИ, рдмрд╢рд░реНрддреЗ рдХрд┐ рдЙрджреНрдШрд╛рдЯрди рдПрдХ рд╕реНрдЯреИрдХ рдкрд░ рд╣реЛред рдЗрд╕рдХреЗ рдмрд╛рдж рд╣реА рд╡рд╣ рдореВрд▓ рддрддреНрд╡ рдХреЛ рдЦреЛрдЬреЗрдЧрд╛, рдФрд░ рдЗрд╕реА рддрд░рд╣ рд╡рд╣ рдЬрдбрд╝ рддрдХ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдЖрд░реЛрд╣реА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред


 private func parseNextToken() throws { guard let currentToken = currentToken else { return } switch (state, currentToken) { case (.state1, .openBraceToken): print("Open brace found") stack.append(.openBraceToken) case (.state1, .number(let value)): if stack.isEmpty { throw ParserError.expectedOpenBrace } else { consumeNumber(value: value) state = .state2 } case (.state1, .closeBraceToken): if stack.isEmpty { throw ParserError.expectedOpenBrace } else { consumeCloseBrace() state = .state2 } case (.state2, .closeBraceToken): if stack.isEmpty { throw ParserError.expectedEndOfArray } else { consumeCloseBrace() } case (.state2, .number), (.state2, .openBraceToken): if stack.isEmpty { throw ParserError.expectedEndOfArray } else { throw ParserError.expectedCloseBrace } } } private func consumeCloseBrace() { print("Close brace found") _ = stack.popLast() print("Pair found") if rootNode == nil { rootNode = .brace(childNode: nil) } else { rootNode = .brace(childNode: rootNode) } } private func consumeNumber(value: Int) { rootNode = .number(value: value) } 

рджреЛрдиреЛрдВ рдкрд╛рд░реНрд╕рд░ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд▓реЗрдХреНрд╕рд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдЯреЛрдХрди рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рд╕реНрдЯрд╛рд░реНрдЯрдкрд░реНрд╕рд┐рдВрдЧ () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ :


 let parserTD = TopDownParser(tokens: tokens) let ast1 = parserTD.startParsing() let parserBU = BottomUpParser(tokens: tokens) let ast2 = parserBU.startParsing() 

рджреЛрдиреЛрдВ рдкрд╛рд░реНрд╕рд░реНрд╕ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдгрд╛рдо рд╕рд╣реА рдерд╛:


 brace(brace(5678)) 

рд╕реНрд╡рд┐рдлреНрдЯ рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рд╕реНрд╡рд┐рдлреНрдЯ рдкрд╛рд░реНрд╕рд░ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ -dump-parse рдлреНрд▓реИрдЧ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:


 swiftc -dump-parse main.swift 

рдПрдХ рдЕрд╕рд▓реА рдПрдПрд╕рдЯреА рдореЗрдВ рдПрдХ рдХреЛрд╖реНрдардХ рдкрд╛рд░реНрд╕рд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╕рдВрд░рдЪрдирд╛ рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рдпрд╣ рдЫреЛрдЯрд╛ рд╣реИ, рдЖрдк рдЗрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкреВрд░реНрдгрд╛рдВрдХ 16 рдФрд░ рд╕реНрдерд┐рд░ x рдЬреНрдЮрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 (source_file (top_level_code_decl (brace_stmt (pattern_binding_decl (pattern_named 'x') (integer_literal_expr type='<null>' value=16)) )) (var_decl "x" type='<null type>' let storage_kind=stored)) 

рдПрдПрд╕рдЯреА рдХрд╛ рдпрд╣ рд░реВрдк рдПрдХ рдЕрдкреНрд░рд╛рдкреНрдд рд╡реГрдХреНрд╖ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╕реНрдерд┐рд░ x рдореЗрдВ рдкреНрд░рдХрд╛рд░ = '' рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ - рдЪрд▓реЛ x: рдЗрдВрдЯ = 16 рдкреЗрдбрд╝ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдкреНрд░рдХрд╛рд░ рд╡реИрд╕реЗ рднреА рдкрдВрдЬреАрдХреГрдд рдирд╣реАрдВ рд╣реЛрдЧрд╛:

 (source_file (top_level_code_decl (brace_stmt (pattern_binding_decl (pattern_typed (pattern_named 'x') (type_ident (component id='Int' bind=none))) (integer_literal_expr type='<null>' value=16)) )) (var_decl "x" type='<null type>' let storage_kind=stored)) 

рд╕реНрд░реЛрдд рдХреЛрдб:



рд╕реЗрдорд╛


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


рд╕реНрд╡рд┐рдлреНрдЯ рд╕рд┐рдореЗрдВрдЯрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рд╕рд┐рдореЗрдВрдЯрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, -dump-ast рдзреНрд╡рдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:


 swiftc -dump-ast main.swift 

рдЖрджреЗрд╢ рдХрд╛ рдкрд░рд┐рдгрд╛рдо:


 (source_file (top_level_code_decl (brace_stmt (pattern_binding_decl (pattern_named type='Int' 'x') (call_expr implicit type='Int' location=main.swift:1:9 range=[main.swift:1:9 - line:1:9] nothrow arg_labels=_builtinIntegerLiteral: (constructor_ref_call_expr implicit type='(_MaxBuiltinIntegerType) -> Int' location=main.swift:1:9 range=[main.swift:1:9 - line:1:9] nothrow (declref_expr implicit type='(Int.Type) -> (_MaxBuiltinIntegerType) -> Int' location=main.swift:1:9 range=[main.swift:1:9 - line:1:9] decl=Swift.(file).Int.init(_builtinIntegerLiteral:) function_ref=single) (type_expr implicit type='Int.Type' location=main.swift:1:9 range=[main.swift:1:9 - line:1:9] typerepr='Int')) (tuple_expr implicit type='(_builtinIntegerLiteral: Int2048)' location=main.swift:1:9 range=[main.swift:1:9 - line:1:9] names=_builtinIntegerLiteral (integer_literal_expr type='Int2048' location=main.swift:1:9 range=[main.swift:1:9 - line:1:9] value=16)))) )) (var_decl "x" type='Int' interface type='Int' access=internal let storage_kind=stored)) 

рд╕реНрдерд┐рд░рд╛рдВрдХ рдореЗрдВ рдЯрд╛рдЗрдк рдкреНрд░рдХрд╛рд░ = 'Int' рд╣реИ , рд╕рд╛рде рд╣реА рдкрд╣реБрдВрдЪ рд╕реНрддрд░ рднреА рд╣реИред рд╕реНрдерд┐рд░рд╛рдВрдХ рдХрд╛ рдкреНрд░рд╛рд░рдВрдн рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЙрд▓ _builtinIntegerLiteral ред рдпрджрд┐ рдЖрдк рдПрдХ рд╕реНрд╡рд┐рдлреНрдЯ рдХреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рдкреЗрдбрд╝ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдорд┐рд▓рддрд╛ рд╣реИ:


 internal let x: Int = Int(_builtinIntegerLiteral: 16) 

рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реИ:


 let x: Bool = 16 

рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдкрд╛рд░реНрд╕рд░ рдХреЗ рдкрд╛рд╕ рднреЗрдЬрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдХрд┐рд╕реА рднреА рд╡рд┐рдЪрд▓рди рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛рдПрдЧрд╛:


 (source_file (top_level_code_decl (brace_stmt (pattern_binding_decl (pattern_typed (pattern_named 'x') (type_ident (component id='Bool' bind=none))) (integer_literal_expr type='<null>' value=16)) )) (var_decl "x" type='<null type>' let storage_kind=stored)) 

рд▓реЗрдХрд┐рди рд╕рд┐рдореЗрдВрдЯрд┐рдХ рдПрдирд╛рд▓рд╛рдЗрдЬрд╝рд░ рдпрд╣ рд╕рдВрдХреЗрдд рджреЗрдЧрд╛ рдХрд┐ рдЗрд╕рдореЗрдВ рджрд┐рдП рдЧрдП рдХреЛрдб рдореЗрдВ рдХреНрдпрд╛ рдЧрд▓рдд рд╣реИ:


 error: cannot convert value of type 'Int' to specified type 'Bool' let x: Bool = 16 

рдЬрд╛рд╣рд┐рд░ рд╣реИ, рддреНрд░реБрдЯрд┐ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмреВрд▓ рдХреЗ рдПрдХ рдирд┐рд░рдВрддрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реА рдереАред рд╕реНрд╡рд┐рдлреНрдЯ рдЗрд╕рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рд╕рд┐рдореЗрдВрдЯрд┐рдХ рдПрдирд╛рд▓рд╛рдЗрдЬрд░ рдХреА рдмрджреМрд▓рддред


рд╕реНрд░реЛрдд рдХреЛрдб:



рджрдмрдВрдЧ рдЖрдпрд╛рддрдХ


рдЗрд╕ рд╕реНрддрд░ рдкрд░, рд╣рдо рдХреНрд▓реИрдВрдЧ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕реНрд╡рд┐рдлреНрдЯ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХреЙрд▓ рдореЗрдВ рд╕реА рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдПрдкреАрдЖрдИ рдХреЛ рдореИрдк рдХрд░рддреЗ рд╣реИрдВред


рд╕реНрд░реЛрдд рдХреЛрдб:



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


рд╕реНрд░реЛрдд рдХреЛрдб рдХрд╛ рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

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


All Articles