From 956d1eb13578dbfec408d1c7b8846d9de1e6ca6a Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Mon, 12 May 2014 13:47:47 +0300 Subject: [PATCH] newline fiddling in the parser yields goods results --- lib/parser/control.rb | 8 ++-- lib/parser/expression.rb | 5 ++- lib/parser/function_definition.rb | 2 +- lib/parser/operators.rb | 2 +- lib/parser/transform.rb | 4 +- test/parser/test_conditional.rb | 1 + test/parser/test_expressions.rb | 27 ++++++----- test/parser/test_function_definition.rb | 60 ++++++++++++++++--------- test/parser/test_root.rb | 2 +- test/parser/test_while.rb | 2 +- 10 files changed, 69 insertions(+), 44 deletions(-) diff --git a/lib/parser/control.rb b/lib/parser/control.rb index 71302f96..e264eda1 100644 --- a/lib/parser/control.rb +++ b/lib/parser/control.rb @@ -2,13 +2,13 @@ module Parser module Control include Parslet rule(:conditional) do - keyword_if >> left_parenthesis >> expression.as(:conditional) >> right_parenthesis >> newline >> - expressions_else.as(:if_true) >> expressions_end.as(:if_false) + keyword_if >> left_parenthesis >> (simple_expression|operator_expression).as(:conditional) >> right_parenthesis >> newline >> + expressions_else.as(:if_true) >> newline >> expressions_end.as(:if_false) end rule(:while_do) do - keyword_while >> left_parenthesis >> expression.as(:while_cond) >> right_parenthesis >> - keyword_do >> newline >> + keyword_while >> left_parenthesis >> (simple_expression|operator_expression).as(:while_cond) >> + right_parenthesis >> keyword_do >> newline >> expressions_end.as(:body) end end diff --git a/lib/parser/expression.rb b/lib/parser/expression.rb index 600ab65d..dfebdf16 100644 --- a/lib/parser/expression.rb +++ b/lib/parser/expression.rb @@ -3,10 +3,11 @@ module Parser include Parslet rule(:simple_expression) { function_call | integer | string | name } - rule(:expression) { (while_do | conditional | simple_expression ) >> newline.maybe } + + rule(:expression) { (while_do | conditional | operator_expression | function_call ) >> newline } def delimited_expressions( delimit ) - ( (delimit.absent? >> (operator_expression | expression)).repeat(1)).as(:expressions) >> delimit >> newline.maybe + ( (delimit.absent? >> expression).repeat(1)).as(:expressions) >> delimit end rule(:expressions_do) { delimited_expressions(keyword_do) } diff --git a/lib/parser/function_definition.rb b/lib/parser/function_definition.rb index 973880ac..47a80e76 100644 --- a/lib/parser/function_definition.rb +++ b/lib/parser/function_definition.rb @@ -3,7 +3,7 @@ module Parser include Parslet rule(:function_definition) { - keyword_def >> name.as(:function_definition) >> parmeter_list >> newline >> expressions_end + keyword_def >> name.as(:function_name) >> parmeter_list >> newline >> expressions_end >> newline } rule(:parmeter_list) { diff --git a/lib/parser/operators.rb b/lib/parser/operators.rb index 74d026b4..4098b278 100644 --- a/lib/parser/operators.rb +++ b/lib/parser/operators.rb @@ -23,7 +23,7 @@ module Parser #infix doing the heavy lifting here, # is defined as an expressions and array of [atoms,priority,binding] triples - rule(:operator_expression) do infix_expression(expression, + rule(:operator_expression) do infix_expression(simple_expression, [exponent, 120, :left] , [multiply, 120, :left] , [plus, 110, :left], diff --git a/lib/parser/transform.rb b/lib/parser/transform.rb index ee5f81be..3938b541 100644 --- a/lib/parser/transform.rb +++ b/lib/parser/transform.rb @@ -33,10 +33,10 @@ module Parser rule(:parmeter => simple(:parmeter)) { parmeter } rule(:parmeter_list => sequence(:parmeter_list)) { parmeter_list } - rule(:function_definition => simple(:function_definition), + rule(:function_name => simple(:function_name), :parmeter_list => sequence(:parmeter_list), :expressions => sequence(:expressions) , :end => simple(:e)) do - Ast::FunctionExpression.new(function_definition.name, parmeter_list, expressions) + Ast::FunctionExpression.new(function_name.name, parmeter_list, expressions) end rule(l: simple(:l), o: simple(:o) , r: simple(:r)) do diff --git a/test/parser/test_conditional.rb b/test/parser/test_conditional.rb index 8c48044b..98735783 100644 --- a/test/parser/test_conditional.rb +++ b/test/parser/test_conditional.rb @@ -12,6 +12,7 @@ else 667 end HERE +@string_input.chop! @parse_output = {:if=>"if", :conditional=>{:integer=>"0"}, :if_true=>{:expressions=>[{:integer=>"42"}], :else=>"else"}, :if_false=>{:expressions=>[{:integer=>"667"}], :end=>"end"}} diff --git a/test/parser/test_expressions.rb b/test/parser/test_expressions.rb index 750fff85..1688311e 100644 --- a/test/parser/test_expressions.rb +++ b/test/parser/test_expressions.rb @@ -6,29 +6,32 @@ class TestExpressions < MiniTest::Test def test_expression_else @string_input = <[{:integer=>"4"}, {:integer=>"5"}], :else=>"else"} - @transform_output = {:expressions=>[ Ast::IntegerExpression.new(4), Ast::IntegerExpression.new(5)], :else=>"else"} + @string_input.chop! + @parse_output = {:expressions=>[{:name=>"dud"}, + {:function_call=>{:name=>"fuu"}, :argument_list=>[{:argument=>{:integer=>"3"}}]}], + :else=>"else"} + @transform_output ={:expressions=>[Ast::NameExpression.new("dud"), + Ast::FuncallExpression.new("fuu", [Ast::IntegerExpression.new(3)] )], :else=>"else"} @parser = @parser.expressions_else end def test_expression_end @string_input = <[{:integer=>"5"}, {:name=>"name"}, - {:function_call=>{:name=>"call"}, :argument_list=>[{:argument=>{:integer=>"4"}}, - {:argument=>{:integer=>"6"}}]}], :end=>"end"} - args = [ Ast::IntegerExpression.new(4) , Ast::IntegerExpression.new(6) ] - @transform_output = {:expressions=>[ Ast::IntegerExpression.new(5), - Ast::NameExpression.new("name") , - Ast::FuncallExpression.new("call", args ) ] , :end=>"end"} + @string_input.chop! + @parse_output = {:expressions=>[{:name=>"name"}, + {:function_call=>{:name=>"call"}, :argument_list=>[{:argument=>{:integer=>"4"}}, {:argument=>{:integer=>"6"}}]}], + :end=>"end"} + @transform_output = {:expressions=>[Ast::NameExpression.new("name"), + Ast::FuncallExpression.new("call", [Ast::IntegerExpression.new(4),Ast::IntegerExpression.new(6)] )], + :end=>"end"} @parser = @parser.expressions_end end diff --git a/test/parser/test_function_definition.rb b/test/parser/test_function_definition.rb index aa1b6aca..ec29428a 100644 --- a/test/parser/test_function_definition.rb +++ b/test/parser/test_function_definition.rb @@ -10,7 +10,7 @@ def foo(x) 5 end HERE - @parse_output = {:function_definition=>{:name=>"foo"}, + @parse_output ={:function_name=>{:name=>"foo"}, :parmeter_list=>[{:parmeter=>{:name=>"x"}}], :expressions=>[{:integer=>"5"}], :end=>"end"} @transform_output = Ast::FunctionExpression.new('foo', [Ast::NameExpression.new('x')], @@ -18,40 +18,46 @@ HERE @parser = @parser.function_definition end - def test_function_assignment + def test_function_ops @string_input = <{:name=>"foo"}, + @parse_output = {:function_name=>{:name=>"foo"}, :parmeter_list=>[{:parmeter=>{:name=>"x"}}], - :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}], :end=>"end"} - @transform_output = Ast::FunctionExpression.new(:foo, [Ast::NameExpression.new("x")] , [Ast::OperatorExpression.new("=", Ast::NameExpression.new("abba"),Ast::IntegerExpression.new(5))] ) + :expressions=>[{:l=>{:name=>"abba"}, :o=>"= ", :r=>{:integer=>"5"}}, + {:l=>{:integer=>"2"}, :o=>"+ ", :r=>{:integer=>"5"}}], :end=>"end"} + @transform_output = Ast::FunctionExpression.new(:foo, + [Ast::NameExpression.new("x")] , + [Ast::OperatorExpression.new("=", Ast::NameExpression.new("abba"),Ast::IntegerExpression.new(5)), + Ast::OperatorExpression.new("+", Ast::IntegerExpression.new(2),Ast::IntegerExpression.new(5))] ) @parser = @parser.function_definition end def test_function_if @string_input = <{:name=>"ofthen"}, - :parmeter_list=>[{:parmeter=>{:name=>"n"}}], - :expressions=>[ - {:if=>"if", :conditional=>{:integer=>"0"}, - :if_true=>{:expressions=>[{:integer=>"42"}], - :else=>"else"}, - :if_false=>{:expressions=>[{:integer=>"667"}], :end=>"end"}}], :end=>"end"} + @parse_output = {:function_name=>{:name=>"ofthen"}, + :parmeter_list=>[{:parmeter=>{:name=>"n"}}], + :expressions=>[{:if=>"if", :conditional=>{:integer=>"0"}, + :if_true=>{:expressions=>[{:l=>{:name=>"isit"}, :o=>"= ", :r=>{:integer=>"42"}}], :else=>"else"}, + :if_false=>{:expressions=>[{:l=>{:name=>"maybenot"}, :o=>"= ", :r=>{:integer=>"667"}}], :end=>"end"}}], + :end=>"end"} @transform_output = Ast::FunctionExpression.new(:ofthen, [Ast::NameExpression.new("n")] , [Ast::ConditionalExpression.new(Ast::IntegerExpression.new(0), - [Ast::IntegerExpression.new(42)],[Ast::IntegerExpression.new(667)] )] ) + [Ast::OperatorExpression.new("=", Ast::NameExpression.new("isit"), + Ast::IntegerExpression.new(42))], + [Ast::OperatorExpression.new("=", Ast::NameExpression.new("maybenot"),Ast::IntegerExpression.new(667))] )] ) @parser = @parser.function_definition end @@ -59,12 +65,26 @@ HERE @string_input = <{:name=>"fibonaccit"}, + :parmeter_list=>[{:parmeter=>{:name=>"n"}}], + :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"0"}}, + {:while=>"while", :while_cond=>{:name=>"n"}, :do=>"do", + :body=>{:expressions=>[{:l=>{:name=>"some"}, :o=>"= ", :r=>{:integer=>"43"}}, + {:l=>{:name=>"other"}, :o=>"= ", :r=>{:l=>{:name=>"some"}, :o=>"* ", :r=>{:integer=>"4"}}}], + :end=>"end"}}], + :end=>"end"} + @transform_output = Ast::FunctionExpression.new(:fibonaccit, + [Ast::NameExpression.new("n")] , + [Ast::OperatorExpression.new("=", Ast::NameExpression.new("a"),Ast::IntegerExpression.new(0)), + Ast::WhileExpression.new(Ast::NameExpression.new("n"), + [Ast::OperatorExpression.new("=", Ast::NameExpression.new("some"),Ast::IntegerExpression.new(43)), + Ast::OperatorExpression.new("=", Ast::NameExpression.new("other"),Ast::OperatorExpression.new("*", Ast::NameExpression.new("some"),Ast::IntegerExpression.new(4)))] )] ) @parser = @parser.function_definition end end \ No newline at end of file diff --git a/test/parser/test_root.rb b/test/parser/test_root.rb index 8648ff06..5fd5593f 100644 --- a/test/parser/test_root.rb +++ b/test/parser/test_root.rb @@ -12,7 +12,7 @@ end foo( 3 ) HERE - @parse_output = [{:function_definition=>{:name=>"foo"}, + @parse_output = [{:function_name=>{:name=>"foo"}, :parmeter_list=>[{:parmeter=>{:name=>"x"}}], :expressions=>[{:l=>{:name=>"a"}, :o=>"= ", :r=>{:integer=>"5"}}], :end=>"end"}, {:function_call=>{:name=>"foo"}, :argument_list=>[{:argument=>{:integer=>"3"}}]}] diff --git a/test/parser/test_while.rb b/test/parser/test_while.rb index f331f9d9..79c6f227 100644 --- a/test/parser/test_while.rb +++ b/test/parser/test_while.rb @@ -11,7 +11,7 @@ while(1) do puts(b) end HERE - + @string_input.chop! @parse_output = {:while=>"while", :while_cond=>{:integer=>"1"}, :do=>"do",