سلام دوستان!
همون طور که توضیح دادم فایل theparser.rb که در Ruby نوشته شده نام فایل ورودی رو که در این جا source.txt هست رو می گیره و کدش رو تجزیه می کنه...
توی پست 214 توضیح دادم...
تا این جای کار:
فایل theparser.rb که کد تجزیه گرمون هست:
require 'whittle'
require 'pp'
#https://barnamenevis.org/member.php?72921-IamOverlord (masood.lapeh@gmail.com)
class TheParser < Whittle::Parser
rule("(")
rule(")")
rule("&") % :left ^ 1
rule("+") % :left ^ 2
rule("-") % :left ^ 2
rule("mod"=>/mod/i) % :left ^ 3
rule("%") % :left ^ 3
rule("*") % :left ^ 5
rule("/") % :left ^ 5
rule("\\") % :left ^ 4
rule("^") % :left ^ 6
rule("=")
rule(",")
rule("call"=>/call/i)
rule("sub"=>/sub/i)
rule("function"=>/function/i)
rule("module"=>/module/i)
rule("as"=>/as/i)
rule("end"=>/end/i)
rule(:identifier => /[_a-zA-Z][_a-zA-Z0-9]*/)
rule(:unsigned_number => /[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/)
rule(:number) do |r|
r[:unsigned_number]
r["+",:unsigned_number].as {|_,unsigned_number| "+" << unsigned_number}
r["-",:unsigned_number].as {|_,unsigned_number| "-" << unsigned_number}
end
rule(:string => /"[^"]*"/ )
rule(:expression) do |r|
r["(",:expression,")"]
r[:expression, "&", :expression].as {|left,_,right| {:item=>"concatention_expression", :left=>left, :right=>right}}
r[:expression, "+", :expression].as {|left,_,right| {:item=>"addition_expression", :left=>left, :right=>right}}
r[:expression, "-", :expression].as {|left,_,right| {:item=>"subtraction_expression", :left=>left, :right=>right}}
r[:expression,"mod",:expression].as {|left,_,right| {:item=>"modulus_expression", :left=>left, :right=>right}}
r[:expression, "%", :expression].as {|left,_,right| {:item=>"modulus_expression", :left=>left, :right=>right}}
r[:expression, "*", :expression].as {|left,_,right| {:item=>"multiplication_expression", :left=>left, :right=>right}}
r[:expression, "/", :expression].as {|left,_,right| {:item=>"integer_division_expression", :left=>left, :right=>right}}
r[:expression,"\\", :expression].as {|left,_,right| {:item=>"division_expression", :left=>left, :right=>right}}
r[:expression, "^", :expression].as {|left,_,right| {:item=>"exponential_expression", :left=>left, :right=>right}}
r[:identifier,:p_arguments_p].as{|identifier,arguments| {:item=>"function_or_object_expression",:identifie r=>identifier,:arguments=>arguments}}
r[:number]
r[:string]
end
rule(:assignment_statement) do |r|
r[:identifier,"=",:expression,:eol].as {|left,_,right,_| {:item=>"assignment_statement",:left=>left,:right= >right}}
end
rule(:call_statement) do |r|
r["call", :identifier,:p_arguments_p,:eol].as { |_,identifier,arguments,_| {:item=>"call_statement",:identifier=>identifier,: arguments=>arguments} }
r[:identifier,:p_arguments_p,:eol].as { |identifier,arguments,_| {:item=>"call_statement",:identifier=>identifier,: arguments=>arguments} }
end
rule(:statement) do |r|
r[:eol].as{|_| {}}
r[:call_statement]
r[:assignment_statement]
end
rule(:arguments) do |r|
r[:expression].as {|expression| [expression]}
r[:expression,",",:arguments].as {|expression,_,arguments_| [expression]+arguments}
r[",",:arguments].as {|_,arguments| []+arguments}
r[].as {|| []}
end
rule(:p_arguments_p) do |r|
r["(",:arguments,")"].as {|_,arguments,_| arguments}
r[].as {|| []}
end
rule(:arguments_definition) do |r|
r[:expression].as {|expression| [expression]}
r[:expression,",",:arguments_definition].as {|expression,_,arguments_definition| [expression]+arguments_definition}
r[",",:arguments_definition].as {|_,arguments_definition| []+arguments_definition}
r[].as {|| []}
end
rule(:p_arguments_definition_p) do |r|
r["(",:arguments_definition,")"].as {|_,arguments_definition,_| arguments_definition}
r[].as {|| []}
end
rule(:sub_content) do |r|
r[:eol,:sub_content].as {|_,sub_content| []+sub_content}
r[:assignment_statement,:sub_content].as {|assignment_statement,sub_content| [assignment_statement]+sub_content}
r[:call_statement,:sub_content].as {|call_statement,sub_content| [call_statement]+sub_content}
r[].as{|| []}
end
rule(:sub_block) do |r|
r["sub",:identifier,:p_arguments_definition_p,:eol,: sub_content,"end","sub"].as{|_,identifier,arguments_definition,_,sub_conte nt,_,_| {:item=>"sub_block",:identifier=>identifier,:argum ents_definition=>arguments_definition,:sub_content =>sub_content}}
end
rule(:function_content) do |r|
r[:eol,:function_content].as {|_,function_content| []+function_content}
r[:assignment_statement,:function_content].as {|assignment_statement,function_content| [assignment_statement]+function_content}
r[:call_statement,:function_content].as {|call_statement,function_content| [call_statement]+function_content}
r[].as{|| []}
end
rule(:function_block) do |r|
r["function",:identifier,:p_arguments_definition_p,: eol,:function_content,"end","function"].as{|_,identifier,arguments_definition,_,function_ content,_,_| {:item=>"function_block",:identifier=>identifier,: arguments_definition=>arguments_definition,:functi on_content=>function_content}}
end
rule(:class_block) do |r|
end
rule(:module_content) do |r|
r[:eol,:module_content].as {|_,module_content| []+module_content}
r[:module_block,:module_content].as {|module_block,module_content| [module_block]+module_content}
#r[:class_block,:module_content].as {|class_block,module_content| [class_block]+module_content}
r[:sub_block,:module_content].as {|sub_block,module_content| [sub_block]+module_content}
r[:function_block,:module_content].as {|function_block,module_content| [function_block]+module_content}
r[].as{|| []}
end
rule(:module_block) do |r|
r["module",:identifier,:eol,:module_content,"end","m odule",:eol].as{|_,identifier,_,module_content,_,_,_| {:item=>"module_block",:identifier=>identifier,:mo dule_content=>module_content}}
end
rule(:program) do |r|
r[:eol,:program].as {|_,program| []+program}
r[:module_block,:program].as {|module_block,program| [module_block]+program}
r[:sub_block,:program].as {|sub_block,program| [sub_block]+program}
r[:function_block,:program].as {|function_block,program| [function_block]+program}
r[:assignment_statement,:program].as {|assignment_statement,program| [assignment_statement]+program}
r[:call_statement,:program].as {|call_statement,program| [call_statement]+program}
r[].as{|| []}
end
rule(:eol=>/\n/)
rule(:space=>/[^\S\n]*/).skip!
start(:program)
end
if ARGV[0] then
print "Parsing #{ARGV[0]}...\n"
source_code = IO.read(ARGV[0])
else
print "File Path argument is empty!\n"
source_code="a=b+c"<<"\n"
end
output = TheParser.new.parse(source_code)
pp output
فایل source.txt که مثال هست:
module a
module b
sub eoe()
x= y - -3.2
z = x^y ^z
end sub
function func1 (arg1,arg2)
call something56
end function
end module
sub hellowo(b,c,ss)
a=b
b=c
end sub
end module
sub main3(t)
end_st=3
end_end_end
end sub
a=b+c-x-y*z^a
function func3(x)
call main3
call main334(x+y)
end function
a= func3(a)
خروجی تجزیه گر برای مثال بالا:
Parsing source.txt...
[{:item=>"module_block",
:identifier=>"a",
:module_content=>
[{:item=>"module_block",
:identifier=>"b",
:module_content=>
[{:item=>"sub_block",
:identifier=>"eoe",
:arguments_definition=>[],
:sub_content=>
[{:item=>"assignment_statement",
:left=>"x",
:right=>
{:item=>"subtraction_expression",
:left=>
{:item=>"function_or_object_expression",
:identifier=>"y",
:arguments=>[]},
:right=>"-3.2"}},
{:item=>"assignment_statement",
:left=>"z",
:right=>
{:item=>"exponential_expression",
:left=>
{:item=>"exponential_expression",
:left=>
{:item=>"function_or_object_expression",
:identifier=>"x",
:arguments=>[]},
:right=>
{:item=>"function_or_object_expression",
:identifier=>"y",
:arguments=>[]}},
:right=>
{:item=>"function_or_object_expression",
:identifier=>"z",
:arguments=>[]}}}]},
{:item=>"function_block",
:identifier=>"func1",
:arguments_definition=>
[{:item=>"function_or_object_expression",
:identifier=>"arg1",
:arguments=>[]},
{:item=>"function_or_object_expression",
:identifier=>"arg2",
:arguments=>[]}],
:function_content=>
[{:item=>"call_statement",
:identifier=>"something56",
:arguments=>[]}]}]},
{:item=>"sub_block",
:identifier=>"hellowo",
:arguments_definition=>
[{:item=>"function_or_object_expression",
:identifier=>"b",
:arguments=>[]},
{:item=>"function_or_object_expression",
:identifier=>"c",
:arguments=>[]},
{:item=>"function_or_object_expression",
:identifier=>"ss",
:arguments=>[]}],
:sub_content=>
[{:item=>"assignment_statement",
:left=>"a",
:right=>
{:item=>"function_or_object_expression",
:identifier=>"b",
:arguments=>[]}},
{:item=>"assignment_statement",
:left=>"b",
:right=>
{:item=>"function_or_object_expression",
:identifier=>"c",
:arguments=>[]}}]}]},
{:item=>"sub_block",
:identifier=>"main3",
:arguments_definition=>
[{:item=>"function_or_object_expression",
:identifier=>"t",
:arguments=>[]}],
:sub_content=>
[{:item=>"assignment_statement", :left=>"end_st", :right=>"3"},
{:item=>"call_statement", :identifier=>"end_end_end", :arguments=>[]}]},
{:item=>"assignment_statement",
:left=>"a",
:right=>
{:item=>"subtraction_expression",
:left=>
{:item=>"subtraction_expression",
:left=>
{:item=>"addition_expression",
:left=>
{:item=>"function_or_object_expression",
:identifier=>"b",
:arguments=>[]},
:right=>
{:item=>"function_or_object_expression",
:identifier=>"c",
:arguments=>[]}},
:right=>
{:item=>"function_or_object_expression",
:identifier=>"x",
:arguments=>[]}},
:right=>
{:item=>"multiplication_expression",
:left=>
{:item=>"function_or_object_expression",
:identifier=>"y",
:arguments=>[]},
:right=>
{:item=>"exponential_expression",
:left=>
{:item=>"function_or_object_expression",
:identifier=>"z",
:arguments=>[]},
:right=>
{:item=>"function_or_object_expression",
:identifier=>"a",
:arguments=>[]}}}}},
{:item=>"function_block",
:identifier=>"func3",
:arguments_definition=>
[{:item=>"function_or_object_expression",
:identifier=>"x",
:arguments=>[]}],
:function_content=>
[{:item=>"call_statement", :identifier=>"main3", :arguments=>[]},
{:item=>"call_statement",
:identifier=>"main334",
:arguments=>
[{:item=>"addition_expression",
:left=>
{:item=>"function_or_object_expression",
:identifier=>"x",
:arguments=>[]},
:right=>
{:item=>"function_or_object_expression",
:identifier=>"y",
:arguments=>[]}}]}]},
{:item=>"assignment_statement",
:left=>"a",
:right=>
{:item=>"function_or_object_expression",
:identifier=>"func3",
:arguments=>
[{:item=>"function_or_object_expression",
:identifier=>"a",
:arguments=>[]}]}}]
فعلا هر برنامه تشکیل شده از یه سری module - sub - function و عبارت انتساب و عبارت call...
هر module تشکیل شده از یه سری module - sub - function...
هر sub تشکیل شده از یه سری عبارت انتساب و عبارت call...
همچنین هر function تشکیل شده از یه سری عبارت انتساب و عبارت call...