Here we are going to discuss about the lisp interpreter written in python by Peter Norvig. The complete code is given here.
Purpose of a language interpreter
A language interpreter has two main divisions termed as parsing and execution.
Parsing: A parser programme converts the input programme into an internal representation after analyzing the syntactic correctness of the programme. In most of the interpreters the internal representation will be a tree like structure which resembles with the nesting structures of the input programme. Consider the example given below, he output after the parser programme will be as followes.
>>> program = "(begin (define r 3) (* 3.141592653 (* r r)))"
>>> parse(program)
['begin', ['define', 'r', 3], ['*', 3.141592653, ['*', 'r', 'r']]]
Execution: The translated programme is processed according to the semantic rules of the language. Considering the same example for parsing programme, its output after evaluation step will be as follows.
>>> program = "(begin (define r 3) (* 3.141592653 (* r r)))"
>>> parse(program)
['begin', ['define', 'r', 3], ['*', 3.141592653, ['*', 'r', 'r']]]
>>> eval(parse(program))
28.274333
Now let us discuss the two topics in detail
Execution
The function eval() explains the methods to be executed for nine different conditions. These nine conditions covers all different types of expressions. Next we have to define the environment. class env is used for this purpose. Note that env is subclass of dict. So env will have all properties of dictionary and the additional functions such as find() is also included. find() is used to find the appropriate environment for a variable by lexical scoping method. Another function in the execution part is add_globals. This functions defines the global environment. Basic math functions such as '+', '*' etc are defined in the global environment.
Parsing
Parsing is traditionally separated into two parts: lexical analysis, in which the input character string is broken up into a sequence of tokens, and syntactic analysis, in which the tokens are assembled into an internal representation. Consider the example given below.
>>> program = "(set! x2 (* x x))"
>>> tokenize(program)
['(', 'set!', 'x2', '(', '*', 'x', 'x', ')', ')']
>>> parse(program)
['set!', 'x2', ['*', 'x', 'x']]
The tokenize() function splits the expression into a set of tokens and the parse() function rearranges the tokens into an internal representation. As the final steps of our code, the function atom() converts integers in string format to numbers and every other token is a symbol.
repl() function is used for making the interpreter user interactive.
Purpose of a language interpreter
A language interpreter has two main divisions termed as parsing and execution.
Parsing: A parser programme converts the input programme into an internal representation after analyzing the syntactic correctness of the programme. In most of the interpreters the internal representation will be a tree like structure which resembles with the nesting structures of the input programme. Consider the example given below, he output after the parser programme will be as followes.
>>> program = "(begin (define r 3) (* 3.141592653 (* r r)))"
>>> parse(program)
['begin', ['define', 'r', 3], ['*', 3.141592653, ['*', 'r', 'r']]]
Execution: The translated programme is processed according to the semantic rules of the language. Considering the same example for parsing programme, its output after evaluation step will be as follows.
>>> program = "(begin (define r 3) (* 3.141592653 (* r r)))"
>>> parse(program)
['begin', ['define', 'r', 3], ['*', 3.141592653, ['*', 'r', 'r']]]
>>> eval(parse(program))
28.274333
Now let us discuss the two topics in detail
Execution
The function eval() explains the methods to be executed for nine different conditions. These nine conditions covers all different types of expressions. Next we have to define the environment. class env is used for this purpose. Note that env is subclass of dict. So env will have all properties of dictionary and the additional functions such as find() is also included. find() is used to find the appropriate environment for a variable by lexical scoping method. Another function in the execution part is add_globals. This functions defines the global environment. Basic math functions such as '+', '*' etc are defined in the global environment.
Parsing
Parsing is traditionally separated into two parts: lexical analysis, in which the input character string is broken up into a sequence of tokens, and syntactic analysis, in which the tokens are assembled into an internal representation. Consider the example given below.
>>> program = "(set! x2 (* x x))"
>>> tokenize(program)
['(', 'set!', 'x2', '(', '*', 'x', 'x', ')', ')']
>>> parse(program)
['set!', 'x2', ['*', 'x', 'x']]
The tokenize() function splits the expression into a set of tokens and the parse() function rearranges the tokens into an internal representation. As the final steps of our code, the function atom() converts integers in string format to numbers and every other token is a symbol.
repl() function is used for making the interpreter user interactive.
Comments
Post a Comment