diff --git a/lib/parser/basic_types.rb b/lib/parser/basic_types.rb index 6136d08c..167e835a 100644 --- a/lib/parser/basic_types.rb +++ b/lib/parser/basic_types.rb @@ -6,7 +6,6 @@ module Parser include Parslet rule(:space) { match('\s').repeat(1) } rule(:space?) { space.maybe } - rule(:name) { match('[a-z]').repeat(1).as(:name) >> space? } rule(:double_quote){ str('"') } rule(:minus) { str('-') } rule(:plus) { str('+') } @@ -16,17 +15,22 @@ module Parser rule(:exponent) { (str('e')| str('E')) } rule(:escaped_character) { str('\\') >> (match('["\\\\/bfnrt]') | (str('u') >> hexdigit.repeat(4,4))) } - rule(:true) { str('true').as(:true) } - rule(:false) { str('false').as(:false) } - rule(:nil) { str('null').as(:nil) } + rule(:true) { str('true').as(:true) >> space?} + rule(:false) { str('false').as(:false) >> space?} + rule(:nil) { str('null').as(:nil) >> space?} + + # identifier must start with lower case + rule(:name) { (match['a-z'] >> match['a-zA-Z0-9'].repeat).as(:name) >> space? } #anything in double quotes rule(:string){ - double_quote >> (escaped_character | double_quote.absent? >> any ).repeat.as(:string) >> double_quote + double_quote >> + (escaped_character | double_quote.absent? >> any ).repeat.as(:string) >> + double_quote >> space? } rule(:integer) { sign.maybe >> digit.repeat(1).as(:integer) >> space? } rule(:float) { integer >> dot >> integer >> - (exponent >> sign.maybe >> digit.repeat).maybe} + (exponent >> sign.maybe >> digit.repeat).maybe >> space?} end end \ No newline at end of file diff --git a/lib/parser/composed.rb b/lib/parser/composed.rb index fda1470f..14fe8506 100644 --- a/lib/parser/composed.rb +++ b/lib/parser/composed.rb @@ -27,17 +27,23 @@ module Parser rule(:expression) { conditional | function_call | integer | name } + def delimited_expressions( delimit ) + ((delimit.absent? >> expression).repeat(1)).as(:expressions) >> delimit + end + rule(:conditional) { keyword_if >> left_parenthesis >> expression.as(:conditional) >> right_parenthesis >> - block.as(:if_true) >> - keyword_else >> - block.as(:if_false) + delimited_expressions(keyword_else).as(:if_true) >> + delimited_expressions(keyword_end).as(:if_false) } - rule(:block) { left_brace >> expression.as(:block) >> right_brace } + rule(:expressions_else) { delimited_expressions(keyword_else) } + rule(:expressions_end) { delimited_expressions(keyword_end) } + +# rule(:expressions_end) { ((keyword_end.absent? >> expression).repeat(1)).as(:expressions) >> keyword_end } rule(:function_definition) { - keyword_def >> name.as(:function_definition) >> parmeter_list >> block + keyword_def >> name.as(:function_definition) >> parmeter_list >> expressions_end } rule(:parmeter_list) { @@ -45,6 +51,6 @@ module Parser ((name.as(:parmeter) >> (comma >> name.as(:parmeter)).repeat(0)).maybe).as(:parmeter_list) >> right_parenthesis } - rule(:root){ function_definition.repeat(0) >> expression | expression | argument_list } + rule(:root){ function_definition | expression } end end diff --git a/lib/parser/keywords.rb b/lib/parser/keywords.rb index 634f9b17..0f9aa6f4 100644 --- a/lib/parser/keywords.rb +++ b/lib/parser/keywords.rb @@ -4,6 +4,6 @@ module Parser rule(:keyword_if) { str('if') >> space? } rule(:keyword_else) { str('else') >> space? } rule(:keyword_def) { str('def') >> space? } - + rule(:keyword_end) { str('end') >> space? } end end \ No newline at end of file diff --git a/test/test_parser.rb b/test/test_parser.rb index b6d7ae59..65829692 100644 --- a/test/test_parser.rb +++ b/test/test_parser.rb @@ -50,30 +50,58 @@ class ParserTest < MiniTest::Test check end - def test_conditional - @input = < {:integer => '0'}, - :if_true => {:block => {:integer => '42'}}, - :if_false => {:block => {:integer => '667'}}} - @parser = @parser.conditional + @expected = {:expressions=>[{:integer=>"4"}, {:integer=>"5"}]} + + @parser = @parser.expressions_else check end + def test_expression_end + @input = < [ { :integer => "5" }, + { :name => "name" }, + { :function_call => { :name => "call" } , + :argument_list => [ {:argument => { :integer => "4" } } , + {:argument => { :integer => "6" } } ] } ]} + @parser = @parser.expressions_end + check + end + + def test_conditional + @input = < { :integer => "0"}, + :if_true => { :expressions => [ { :integer => "42" } ] } , + :if_false => { :expressions => [ { :integer => "667" } ] } } + @parser = @parser.conditional + check + end + def test_function_definition @input = < {:name => 'foo'}, :parmeter_list => {:parmeter => {:name => 'x'}}, - :block => {:integer => '5'}} + :expressions => [{:integer => '5'}]} @parser = @parser.function_definition check end