Class: ToyLang::Parser
- Inherits:
-
Object
- Object
- ToyLang::Parser
- Defined in:
- lib/toy_lang/parser.rb
Overview
This it the class that parses the toy language grammatical rules are lower cased (e.g. statement) tokens are upper case (e.g. COMMA) optional rules are surrounded by parentheses
The toy language grammar is as follows
program =>
statement*
statement =>
function_definition |
conditional_expression |
function_call |
return_statement
function_definition =>
function_header OPEN_BLOCK expression* CLOSE_BLOCK
function_header =>
DEF IDENTIFIER OPEN_PARENTHESES argument_list CLOSE_PARENTHESES
argument_list =>
(IDENTIFIER ( COMMA IDENTIFIER)*)
conditional_expression =>
IF condition OPEN_BLOCK expression* CLOSE_BLOCK
expression =>
additive_expression
additive_expression =>
substraction_expression PLUS substraction_expression
substraction_expression =>
primary_expresion MINUS primary_expresion
primary_expresion =>
NUMBER
function_call =>
IDENTIFIER OPEN_PARENTHESES parameter_list CLOSE_PARENTHESES
parameter_list =>
(expression ( COMMA expression)*)
return_statement =>
RETURN expression
An example program would be def fibbo(number) {
if number == 0 { return 0 }
if number == 1 { return 1 }
return fibbo(number-1) + fibbo(number-2)
} fibbo(5)
This program should output 8
Instance Method Summary collapse
-
#conditional_expression ⇒ Object
conditional_expression => IF condition OPEN_BLOCK expression* CLOSE_BLOCK.
-
#expression ⇒ Object
expression => .…
-
#function_call ⇒ Object
function_call => IDENTIFIER OPEN_PARENTHESES parameter_list CLOSE_PARENTHESES.
-
#function_definition ⇒ Object
function_definition => function_header OPEN_BLOCK expression* CLOSE_BLOCK.
-
#parameter_list ⇒ Object
parameter_list => (expression ( COMMA expression)*).
- #program=(program) ⇒ Object
-
#return_statement ⇒ Object
return_statement => RETURN expression.
-
#statement ⇒ Object
statement => function_definition | conditional_expression | function_call | return_statement.
Instance Method Details
#conditional_expression ⇒ Object
conditional_expression =>
IF condition OPEN_BLOCK expression* CLOSE_BLOCK
83 84 85 |
# File 'lib/toy_lang/parser.rb', line 83 def conditional_expression return nil end |
#expression ⇒ Object
expression =>
....
!!! INCOMPLETE IMPLEMENTATION !!! To get going, expression can only be a number TODO: Do it for real
142 143 144 145 146 147 148 149 |
# File 'lib/toy_lang/parser.rb', line 142 def expression if token_is_not? :number nil end token = @scanner.get_next_token return { number: token.content } end |
#function_call ⇒ Object
function_call =>
IDENTIFIER OPEN_PARENTHESES parameter_list CLOSE_PARENTHESES
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/toy_lang/parser.rb', line 89 def function_call unless tokens_are?(:id, :open_parentheses) return nil end method_name = @scanner.get_next_token.content @scanner.get_next_token # open parentheses params = parameter_list() # Verify close parentheses if token_is_not? :close_parentheses throw :parser_exception end @scanner.get_next_token # close parentheses return { function_call: method_name, params: params } end |
#function_definition ⇒ Object
function_definition =>
function_header OPEN_BLOCK expression* CLOSE_BLOCK
77 78 79 |
# File 'lib/toy_lang/parser.rb', line 77 def function_definition return nil end |
#parameter_list ⇒ Object
parameter_list =>
(expression ( COMMA expression)*)
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/toy_lang/parser.rb', line 110 def parameter_list expression_list = [] expr = expression() return [] if expr == nil expression_list << expr while (token_is? :comma) @scanner.get_next_token # the comma expr = expression() expression_list << expr if expr != nil end expression_list end |
#program=(program) ⇒ Object
51 52 53 54 |
# File 'lib/toy_lang/parser.rb', line 51 def program=(program) @scanner = Scanner.new @scanner.set_program(program) end |
#return_statement ⇒ Object
return_statement =>
RETURN expression
128 129 130 131 132 133 134 135 |
# File 'lib/toy_lang/parser.rb', line 128 def return_statement unless token_is? :return return nil end @scanner.get_next_token return {return: expression()} end |
#statement ⇒ Object
statement =>
function_definition |
conditional_expression |
function_call |
return_statement
61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/toy_lang/parser.rb', line 61 def statement # ast => Abstract Syntax Tree if ((ast = function_definition) != nil) return ast elsif ((ast = conditional_expression) != nil) return ast elsif ((ast = function_call) != nil) return ast elsif ((ast = return_statement) != nil) return ast end throw :parser_exception end |