Class: Crokus::Parser
Constant Summary collapse
- STARTERS_ARRAY_OR_STRUCT_INIT =
[:lbrace]
- STARTERS_PRIMARY =
[:ident,:integer_lit,:float_lit,:string_lit,:char_lit,:lparen]+STARTERS_ARRAY_OR_STRUCT_INIT
- UNARY_OP =
[:and,:mul,:add,:sub,:tilde,:not]
- STARTERS_UNARY =
[:inc_op,:dec_op,:sizeof]+STARTERS_PRIMARY+UNARY_OP
- ASSIGN_OP =
[:assign,:add_assign,:sub_assign,:mul_assign,:div_assign,:mod_assign,:xor_assign]
- STARTERS_TYPE_SPECIFIER =
[:void,:char,:short,:int,:long,:float,:signed,:unsigned,:struct,:union,:enum,:ident]
- STARTERS_ABSTRACT_DECLARATOR =
: pointer
| direct_abstract_declarator | pointer direct_abstract_declarator ;
[:mul,:lparen,:lbrack]
- STARTERS_TYPE_QUALIFIER =
pointer : ‘*’ | ‘*’ type_qualifier_list | ‘*’ pointer | ‘*’ type_qualifier_list pointer ;
[:const,:volatile]
Constants included from Indent
Instance Attribute Summary collapse
-
#str ⇒ Object
Returns the value of attribute str.
-
#tokens ⇒ Object
Returns the value of attribute tokens.
Instance Method Summary collapse
- #abstract_decl ⇒ Object
- #acceptIt ⇒ Object
- #additive ⇒ Object
- #andexp ⇒ Object
- #argument_expr_list ⇒ Object
- #array_or_struct_init ⇒ Object
- #arrayed?(type) ⇒ Boolean
- #assign ⇒ Object
- #castexp ⇒ Object
-
#casting ⇒ Object
def is_casting? i=0 tok=DUMMY while tok.kind!=:rparen tok=@tokens i+=1 end pp tok=@tokens return false if tok.is? [:mul,:add,:sub] pp cond=STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT return true if tok.is? cond return false end.
- #cond_expr ⇒ Object
- #dbg_print(node) ⇒ Object
-
#dbg_print_next(n) ⇒ Object
————————————————–.
-
#debug ⇒ Object
.
-
#declaration ⇒ Object
int a int * a int a=1,b=2; int a[] int* f() struct name *ptr; paire_t paire = 1,2; int a,b,*c —————————— TYPE ident ident ident.
- #declarator ⇒ Object
- #define ⇒ Object
- #design_unit ⇒ Object
- #direct_abstract_declarator ⇒ Object
- #do_while ⇒ Object
- #eqexp ⇒ Object
- #exclor ⇒ Object
- #expect(kind) ⇒ Object
-
#expression ⇒ Object
.
- #expression_statement ⇒ Object
- #func_formal_arg ⇒ Object
- #function_body ⇒ Object
- #function_decl(name, type_) ⇒ Object
- #function_formal_args ⇒ Object
- #inclor ⇒ Object
- #include ⇒ Object
- #initialization? ⇒ Boolean
-
#initialize ⇒ Parser
constructor
A new instance of Parser.
- #is_casting? ⇒ Boolean
- #linearize_comma_stmt(ary) ⇒ Object
- #logand ⇒ Object
- #logor ⇒ Object
- #lookahead(n = 2) ⇒ Object
- #maybe(kind) ⇒ Object
- #multitive ⇒ Object
- #parenthesized ⇒ Object
- #parenthesized? ⇒ Boolean
-
#parse(str) ⇒ Object
.….….…
- #parse_body ⇒ Object
- #parse_else ⇒ Object
- #parse_for ⇒ Object
- #parse_goto ⇒ Object
- #parse_if ⇒ Object
- #parse_label ⇒ Object
- #parse_return ⇒ Object
- #parse_struct ⇒ Object
- #parse_type ⇒ Object
- #parse_while ⇒ Object
- #parseLoopCond ⇒ Object
- #parseLoopEnd ⇒ Object
- #parseLoopInit ⇒ Object
- #pointed? ⇒ Boolean
- #pointer ⇒ Object
- #postfix ⇒ Object
- #primary ⇒ Object
- #relexp ⇒ Object
- #remove_comments ⇒ Object
- #shiftexp ⇒ Object
- #show_lexer_warnings(warnings) ⇒ Object
- #show_line(pos) ⇒ Object
- #showNext(n = 1) ⇒ Object
- #sizeof ⇒ Object
- #spec_qualifier? ⇒ Boolean
- #spec_qualifier_list ⇒ Object
- #statement(arg = nil) ⇒ Object
- #switch ⇒ Object
- #type_specifier ⇒ Object
- #typedef ⇒ Object
- #typename ⇒ Object
- #unary ⇒ Object
Methods included from Indent
Constructor Details
#initialize ⇒ Parser
Returns a new instance of Parser.
15 16 17 18 19 |
# File 'lib/crokus/parser.rb', line 15 def initialize @ppr=PrettyPrinter.new @verbose=false #@verbose=true end |
Instance Attribute Details
#str ⇒ Object
Returns the value of attribute str.
12 13 14 |
# File 'lib/crokus/parser.rb', line 12 def str @str end |
#tokens ⇒ Object
Returns the value of attribute tokens.
12 13 14 |
# File 'lib/crokus/parser.rb', line 12 def tokens @tokens end |
Instance Method Details
#abstract_decl ⇒ Object
931 932 933 934 935 936 937 938 939 940 941 942 943 944 |
# File 'lib/crokus/parser.rb', line 931 def abstract_decl indent "abstract_decl" if showNext.is? STARTERS_ABSTRACT_DECLARATOR case showNext.kind when :mul pointer else direct_abstract_declarator end else raise "ERROR : in abstract_declarator. Expecting one of #{STARTERS_ABSTRACT_DECLARATOR}" end dedent end |
#acceptIt ⇒ Object
21 22 23 24 |
# File 'lib/crokus/parser.rb', line 21 def acceptIt say showNext.kind.to_s+" "+showNext.val tokens.shift end |
#additive ⇒ Object
790 791 792 793 794 795 796 797 798 799 800 |
# File 'lib/crokus/parser.rb', line 790 def additive indent "addititve : #{showNext}" e1=multitive while showNext.is? [:add,:sub] op=acceptIt e2=multitive e1=Binary.new(e1,op,e2) end dedent e1 end |
#andexp ⇒ Object
742 743 744 745 746 747 748 749 750 751 752 |
# File 'lib/crokus/parser.rb', line 742 def andexp indent "andexp : #{showNext}" e1=eqexp while showNext.is? :and op=acceptIt e2=eqexp e1=Binary.new(e1,op,e2) end dedent e1 end |
#argument_expr_list ⇒ Object
1080 1081 1082 1083 1084 1085 1086 1087 1088 |
# File 'lib/crokus/parser.rb', line 1080 def argument_expr_list list=[] list << expression while showNext.is? :comma acceptIt list << expression end list end |
#array_or_struct_init ⇒ Object
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 |
# File 'lib/crokus/parser.rb', line 1090 def array_or_struct_init indent "array_or_struct_init" expect :lbrace elements=[] while !showNext.is? :rbrace elements << (e=expression) if showNext.is? :comma acceptIt end end expect :rbrace dedent return ArrayOrStructInit.new(elements) end |
#arrayed?(type) ⇒ Boolean
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
# File 'lib/crokus/parser.rb', line 436 def arrayed?(type) return if tokens.empty? while showNext.is? :lbrack acceptIt if showNext.is? :rbrack acceptIt type=ArrayOf.new(type,IntLit.new(ZERO)) else e=expression type=ArrayOf.new(type,e) expect :rbrack end end return type end |
#assign ⇒ Object
668 669 670 671 672 673 674 675 676 677 678 |
# File 'lib/crokus/parser.rb', line 668 def assign indent "assign : #{showNext}" e1=cond_expr while showNext.is? ASSIGN_OP op=acceptIt e2=assign e1=Assign.new(e1,op,e2) end dedent return e1 end |
#castexp ⇒ Object
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 |
# File 'lib/crokus/parser.rb', line 814 def castexp indent "castexpr : #{showNext}" case showNext.kind when :lparen # parenth expr OR casting ! res=is_casting? if res e=casting else e=parenthesized end else e=unary end dedent return e end |
#casting ⇒ Object
def is_casting?
i=0
tok=DUMMY
while tok.kind!=:rparen
tok=@tokens[i]
i+=1
end
pp tok=@tokens[i]
return false if tok.is? [:mul,:add,:sub]
pp cond=STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT
return true if tok.is? cond
return false
end
870 871 872 873 874 875 876 877 |
# File 'lib/crokus/parser.rb', line 870 def casting puts "casting : #{showNext}" if $options[:verbose] expect :lparen t=parse_type expect :rparen u=unary CastedExpr.new(t,u) end |
#cond_expr ⇒ Object
680 681 682 683 684 685 686 687 688 689 690 691 692 |
# File 'lib/crokus/parser.rb', line 680 def cond_expr indent "cond_expr : #{showNext}" e1=logor while showNext.is? :qmark acceptIt e2=expression expect :colon e3=cond_expr e1=CondExpr.new(e1,e2,e3) end dedent return e1 end |
#dbg_print(node) ⇒ Object
61 62 63 64 65 |
# File 'lib/crokus/parser.rb', line 61 def dbg_print node puts "debug ast node".center(60,'-') puts node.accept(@ppr) puts "-"*60 end |
#dbg_print_next(n) ⇒ Object
57 58 59 |
# File 'lib/crokus/parser.rb', line 57 def dbg_print_next n pp tokens[0..n-1].collect{|tok| tok.inspect} end |
#debug ⇒ Object
646 647 648 |
# File 'lib/crokus/parser.rb', line 646 def debug puts " "*@indentation+@tokens[0..4].map{|t| "'#{t.val}'"}.join(" ") end |
#declaration ⇒ Object
int a int * a int a=1,b=2; int a[] int* f() struct name *ptr; paire_t paire = 1,2; int a,b,*c
TYPE ident ident ident
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 |
# File 'lib/crokus/parser.rb', line 389 def declaration ret=[] @current_type=type=parse_type() d=declarator() a=arrayed?(type) if a type=a end func=parenthesized? if func func.type=type ret << func #func return ret end init=initialization? ret << Decl.new(type,d,init) while tokens.any? and showNext.is?(:comma) acceptIt ptr=pointed? if ptr type2=PointerTo.new(type) end d2=declarator a2=arrayed?(type) i2=initialization? ret << Decl.new(type2||type,d2) end if tokens.any? maybe :semicolon end return ret end |
#declarator ⇒ Object
422 423 424 425 426 427 |
# File 'lib/crokus/parser.rb', line 422 def declarator if showNext.is? :ident ret=@current_ident=Ident.new(acceptIt) end return ret end |
#define ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/crokus/parser.rb', line 152 def define indent "define" expect :sharp expect :ident #define name=expect :ident args=[] if showNext.is? :lparen acceptIt while !showNext.is?(:rparen) args << acceptIt if showNext.is?(:comma) acceptIt end end expect :rparen end e=expression() dedent return Define.new(name,args,e) end |
#design_unit ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/crokus/parser.rb', line 109 def design_unit indent "designUnit" du=DesignUnit.new while tokens.any? case showNext.kind when :sharp case showNext(2).val when "include" du << include() when "define" du << define() end else du << declaration maybe :semicolon if tokens.any? end end dedent du.list.flatten! return du end |
#direct_abstract_declarator ⇒ Object
967 968 969 |
# File 'lib/crokus/parser.rb', line 967 def direct_abstract_declarator raise end |
#do_while ⇒ Object
325 326 327 328 329 330 331 332 333 |
# File 'lib/crokus/parser.rb', line 325 def do_while indent "do_while" expect :do body=statement() expect :while e=expression dedent DoWhile.new(e,body) end |
#eqexp ⇒ Object
754 755 756 757 758 759 760 761 762 763 764 |
# File 'lib/crokus/parser.rb', line 754 def eqexp indent "eqexp : #{showNext}" e1=relexp while showNext.is? [:eq,:neq] op=acceptIt e2=relexp e1=Binary.new(e1,op,e2) end dedent e1 end |
#exclor ⇒ Object
730 731 732 733 734 735 736 737 738 739 740 |
# File 'lib/crokus/parser.rb', line 730 def exclor indent "exclor : #{showNext}" e1=andexp while showNext.is? :xor op=acceptIt e2=andexp e1=Binary.new(e1,op,e2) end dedent e1 end |
#expect(kind) ⇒ Object
30 31 32 33 34 35 36 37 38 |
# File 'lib/crokus/parser.rb', line 30 def expect kind if ((actual=tokens.shift).kind)!=kind puts "ERROR :" show_line(actual.pos) raise "expecting '#{kind}'. Received '#{actual.val}' around #{actual.pos}" end say actual.kind.to_s+" "+actual.val return actual end |
#expression ⇒ Object
650 651 652 653 654 655 656 657 658 659 660 |
# File 'lib/crokus/parser.rb', line 650 def expression indent "expression : #{showNext}" e1=assign() while showNext.is? :comma acceptIt e2=assign() e1=CommaStmt.new(e1,e2) end dedent return e1 end |
#expression_statement ⇒ Object
636 637 638 639 640 641 642 643 644 |
# File 'lib/crokus/parser.rb', line 636 def expression_statement if showNext.is? :semicolon acceptIt else e=expression expect :semicolon return e end end |
#func_formal_arg ⇒ Object
232 233 234 235 236 237 238 239 240 |
# File 'lib/crokus/parser.rb', line 232 def func_formal_arg @current_type=type=parse_type() d=declarator a=arrayed?(type) if a type=a end return FormalArg.new(type,d) end |
#function_body ⇒ Object
242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/crokus/parser.rb', line 242 def function_body indent "function_body" body=Body.new expect :lbrace while showNext.kind!=:rbrace s=statement() body << s if s end expect :rbrace dedent return body end |
#function_decl(name, type_) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/crokus/parser.rb', line 202 def function_decl name,type_ indent "function" args=function_formal_args() case showNext.kind when :semicolon acceptIt ret =FunctionProto.new(name,type_,args) else body=function_body() ret= Function.new(name,type_,args,body) end dedent return ret end |
#function_formal_args ⇒ Object
217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/crokus/parser.rb', line 217 def function_formal_args indent "function_formal_args" args=[] expect :lparen while !showNext.is? :rparen args << func_formal_arg() if !showNext.is? :rparen expect :comma end end expect :rparen dedent return args end |
#inclor ⇒ Object
718 719 720 721 722 723 724 725 726 727 728 |
# File 'lib/crokus/parser.rb', line 718 def inclor indent "inclor : #{showNext}" e1=exclor while showNext.is? :or op=acceptIt e2=exclor e1=Binary.new(e1,op,e2) end dedent e1 end |
#include ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/crokus/parser.rb', line 131 def include indent "include" expect :sharp expect :ident #include case showNext.kind when :lt acceptIt id1=expect :ident expect :dot id2=expect :ident expect :gt name=Token.new [:ident,id1.val+"."+id2.val,id1.pos] env=:env when :string_lit name=acceptIt env=:local end dedent return Include.new(name,env) end |
#initialization? ⇒ Boolean
452 453 454 455 456 457 458 459 |
# File 'lib/crokus/parser.rb', line 452 def initialization? return if tokens.empty? if showNext.is? :assign expect :assign e=expression return e end end |
#is_casting? ⇒ Boolean
849 850 851 852 853 854 |
# File 'lib/crokus/parser.rb', line 849 def is_casting? #puts "is_casting? : #{pp @tokens[0..1]}" cond1= @tokens[0].is?(:lparen) cond2= @tokens[1].is?([:int,:uint,:short,:byte,:float,:long,:double]) cond1 and cond2 end |
#linearize_comma_stmt(ary) ⇒ Object
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 |
# File 'lib/crokus/parser.rb', line 1047 def linearize_comma_stmt ary ary.collect do |stmt| case stmt when CommaStmt stmt.to_list else stmt end end.flatten end |
#logand ⇒ Object
706 707 708 709 710 711 712 713 714 715 716 |
# File 'lib/crokus/parser.rb', line 706 def logand indent "logand : #{showNext}" e1=inclor while showNext.is? :andand op=acceptIt e2=inclor e1=Binary.new(e1,op,e2) end dedent e1 end |
#logor ⇒ Object
694 695 696 697 698 699 700 701 702 703 704 |
# File 'lib/crokus/parser.rb', line 694 def logor indent "logor : #{showNext}" e1=logand while showNext.is? :oror op=acceptIt e2=logand e1=Binary.new(e1,op,e2) end dedent return e1 end |
#lookahead(n = 2) ⇒ Object
44 45 46 |
# File 'lib/crokus/parser.rb', line 44 def lookahead(n=2) tokens[n] if tokens.any? end |
#maybe(kind) ⇒ Object
26 27 28 |
# File 'lib/crokus/parser.rb', line 26 def maybe kind return acceptIt if showNext.is? kind end |
#multitive ⇒ Object
802 803 804 805 806 807 808 809 810 811 812 |
# File 'lib/crokus/parser.rb', line 802 def multitive indent "multitive : #{showNext}" e1=castexp while showNext.is? [:mul,:div,:mod] op=acceptIt e2=castexp e1=Binary.new(e1,op,e2) end dedent e1 end |
#parenthesized ⇒ Object
879 880 881 882 883 884 885 886 |
# File 'lib/crokus/parser.rb', line 879 def parenthesized indent "parenthesized : #{showNext}" expect :lparen e=expression expect :rparen dedent return Parenth.new(e) end |
#parenthesized? ⇒ Boolean
461 462 463 464 465 466 467 |
# File 'lib/crokus/parser.rb', line 461 def parenthesized? return if tokens.empty? if showNext.is? :lparen f=function_decl(@current_ident,@current_type) return f end end |
#parse(str) ⇒ Object
.….….… parsing methods .….……
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/crokus/parser.rb', line 67 def parse str begin @str=str @tokens=Lexer.new.tokenize(str) #pp @tokens @tokens=@tokens.reject{|tok| tok==[nil,nil,nil]} @tokens=remove_comments() warnings=@tokens.select{|tok| tok.is? :lexer_warning} show_lexer_warnings(warnings) @tokens=@tokens.select{|tok| !tok.is? [:newline]} ast=design_unit() rescue Exception => e puts "PARSING ERROR : #{e}" puts "in C source at line/col #{showNext.pos}" puts e.backtrace abort end end |
#parse_body ⇒ Object
626 627 628 629 630 631 632 633 634 |
# File 'lib/crokus/parser.rb', line 626 def parse_body body=Body.new expect :lbrace while !showNext.is? :rbrace body << statement() end expect :rbrace return body end |
#parse_else ⇒ Object
553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
# File 'lib/crokus/parser.rb', line 553 def parse_else indent "parse else" expect :else ret=Else.new stmt=statement() case stmt when Body ret.body=stmt else ret.body=Body.new([stmt]) end dedent return ret end |
#parse_for ⇒ Object
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 |
# File 'lib/crokus/parser.rb', line 583 def parse_for indent "parse_for" forloop=For.new expect :for expect :lparen forloop.init << expression_statement forloop.cond = expression() expect :semicolon forloop.increment=expression() expect :rparen stmt=statement() case stmt when Body forloop.body=stmt else forloop.body=Body.new([stmt]) end dedent forloop end |
#parse_goto ⇒ Object
317 318 319 320 321 322 323 |
# File 'lib/crokus/parser.rb', line 317 def parse_goto indent "goto" expect :goto #label id=expect(:ident) dedent Goto.new(id) end |
#parse_if ⇒ Object
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 |
# File 'lib/crokus/parser.rb', line 526 def parse_if indent "parse_if" expect :if if showNext.is? :lparen # helps wrt casting. acceptIt lparen=true end cond=expression() expect :rparen if lparen body=Body.new if showNext.is? :lbrace lbrace=acceptIt end body << statement() if lbrace until showNext.is? :rbrace body << statement end expect :rbrace end if showNext.is? :else else_=parse_else() end dedent return If.new(cond,body,else_) end |
#parse_label ⇒ Object
311 312 313 314 315 |
# File 'lib/crokus/parser.rb', line 311 def parse_label id=expect(:ident) expect(:colon) Ident.new(id) end |
#parse_return ⇒ Object
367 368 369 370 371 372 373 374 375 |
# File 'lib/crokus/parser.rb', line 367 def parse_return indent "parse_return" expect :return unless showNext.is? :semicolon e=expression end dedent Return.new(e) end |
#parse_struct ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/crokus/parser.rb', line 173 def parse_struct indent "struct" expect :struct name=nil if showNext.is? :ident name=acceptIt end ret=Struct.new(name) if showNext.is? :lbrace acceptIt while !showNext.is? :rbrace ret.decls << declaration() end ret.decls.flatten! expect :rbrace end dedent return ret end |
#parse_type ⇒ Object
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 |
# File 'lib/crokus/parser.rb', line 469 def parse_type indent "parse_type" ret=Type.new(nil) ret.precisions << spec_qualifier?() # const, volatile if showNext.is? [:signed,:unsigned] ret.precisions << acceptIt end case showNext.kind when :ident,:char,:int,:short,:long,:float,:double,:void ret.name=acceptIt while showNext.is? [:char,:int,:short,:long,:float,:double,:void] ret.precisions << ret.name ret.name=acceptIt end ret.precisions.flatten! when :struct ret=parse_struct() when :typedef ret=typedef() else raise "Parsing ERROR in type declaration: '#{showNext}' #{showNext.pos}" end while showNext.is? [:mul,:lparen] case showNext.kind when :mul acceptIt ret=PointerTo.new(ret) when :lparen acceptIt if showNext.is? :rparen acceptIt else expression expect :rparen end end end dedent return ret end |
#parse_while ⇒ Object
568 569 570 571 572 573 574 575 576 577 578 579 580 581 |
# File 'lib/crokus/parser.rb', line 568 def parse_while indent "parse_while" expect :while cond=expression() stmt=statement() case stmt when Body body=stmt else body=Body.new([stmt]) end dedent return While.new(cond,body) end |
#parseLoopCond ⇒ Object
612 613 614 615 616 617 |
# File 'lib/crokus/parser.rb', line 612 def parseLoopCond indent "parseLoopCond" e=expression() dedent return e end |
#parseLoopEnd ⇒ Object
619 620 621 622 623 624 |
# File 'lib/crokus/parser.rb', line 619 def parseLoopEnd indent "parseLoopEnd" s=statement() dedent return s end |
#parseLoopInit ⇒ Object
604 605 606 607 608 609 610 |
# File 'lib/crokus/parser.rb', line 604 def parseLoopInit indent "parseLoopInit" ret=statement() dedent return [ret] # because for (int a,b=0;i<10;i++) is also possible. # then parser returns an array of Decl end |
#pointed? ⇒ Boolean
429 430 431 432 433 434 |
# File 'lib/crokus/parser.rb', line 429 def pointed? return if tokens.empty? while showNext.is? :mul acceptIt end end |
#pointer ⇒ Object
953 954 955 956 957 958 959 960 961 962 963 964 965 |
# File 'lib/crokus/parser.rb', line 953 def pointer expect :mul while showNext.is? STARTERS_TYPE_QUALIFIER+[:mul] case showNext.kind when :volatile acceptIt when :const acceptIt when :mult acceptIt end end end |
#postfix ⇒ Object
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 |
# File 'lib/crokus/parser.rb', line 1012 def postfix indent "postfix : #{showNext}" e1=primary while showNext.is? [:lbrack,:lparen,:dot,:inc_op,:dec_op,:ptr_op] case showNext.kind when :lbrack acceptIt e2=expression expect :rbrack e1=Indexed.new(e1,e2) when :lparen acceptIt args=[] if !showNext.is? :rparen args=argument_expr_list end expect :rparen args=linearize_comma_stmt(args) e1=FunCall.new(e1,args) when :dot acceptIt e2=Ident.new(expect :ident) e1=Dotted.new(e1,e2) when :ptr_op op=acceptIt expect :ident when :inc_op,:dec_op op=acceptIt e1=PostFixAccu.new(e1,op) end end dedent e1 end |
#primary ⇒ Object
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 |
# File 'lib/crokus/parser.rb', line 1058 def primary case showNext.kind when :ident return Ident.new(acceptIt) when :integer_lit return IntLit.new(acceptIt) when :float_lit return FloatLit.new(acceptIt) when :string_lit return StrLit.new(acceptIt) when :char_lit return CharLit.new(acceptIt) when :lparen acceptIt e=expression expect :rparen return Parenth.new(e) when :lbrace return array_or_struct_init() end end |
#relexp ⇒ Object
766 767 768 769 770 771 772 773 774 775 776 |
# File 'lib/crokus/parser.rb', line 766 def relexp indent "relexp : #{showNext}" e1=shiftexp while showNext.is? [:lte,:lt,:gte,:gt ] op=acceptIt e2=shiftexp e1=Binary.new(e1,op,e2) end dedent e1 end |
#remove_comments ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/crokus/parser.rb', line 92 def remove_comments ret=[] in_comment=false tokens.each do |tok| case tok.kind when :comment when :lcomment in_comment=true when :rcomment in_comment=false else ret << tok unless in_comment end end ret end |
#shiftexp ⇒ Object
778 779 780 781 782 783 784 785 786 787 788 |
# File 'lib/crokus/parser.rb', line 778 def shiftexp indent "shiftexp : #{showNext}" e1=additive while showNext.is? [:shift_l,:shift_r] op=acceptIt e2=additive e1=Binary.new(e1,op,e2) end dedent e1 end |
#show_lexer_warnings(warnings) ⇒ Object
86 87 88 89 90 |
# File 'lib/crokus/parser.rb', line 86 def show_lexer_warnings warnings warnings.each do |warn| puts "lexer warning : #{warn.val} at #{warn.pos}" end end |
#show_line(pos) ⇒ Object
48 49 50 51 52 53 54 55 |
# File 'lib/crokus/parser.rb', line 48 def show_line pos l,c=*pos show_lines(str,l-2) line=str.split(/\n/)[l-1] pointer="-"*(5+c)+ "^" puts "#{l.to_s.ljust(5)}|#{line}" puts pointer end |
#showNext(n = 1) ⇒ Object
40 41 42 |
# File 'lib/crokus/parser.rb', line 40 def showNext(n=1) tokens[n-1] if tokens.any? end |
#sizeof ⇒ Object
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 |
# File 'lib/crokus/parser.rb', line 997 def sizeof expect :sizeof case showNext.kind when :lparen acceptIt #e=typename e=parse_type expect :rparen else #e=unary e=expression end Sizeof.new(e) end |
#spec_qualifier? ⇒ Boolean
513 514 515 516 517 518 519 520 521 522 523 524 |
# File 'lib/crokus/parser.rb', line 513 def spec_qualifier? list=[] while showNext.is? STARTERS_TYPE_QUALIFIER case showNext.kind when :volatile list << acceptIt when :const list << acceptIt end end list end |
#spec_qualifier_list ⇒ Object
898 899 900 901 902 903 904 905 906 907 908 909 |
# File 'lib/crokus/parser.rb', line 898 def spec_qualifier_list indent "spec_qualifier_list #{showNext.inspect}" while showNext.is? STARTERS_TYPE_SPECIFIER+STARTERS_TYPE_QUALIFIER if showNext.is? STARTERS_TYPE_SPECIFIER list << type_specifier else list << type_qualifier end end dedent list end |
#statement(arg = nil) ⇒ Object
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/crokus/parser.rb', line 255 def statement(arg=nil) indent "statement ...#{showNext.kind} #{showNext.pos.first}" case showNext.kind when :lbrace ret=parse_body() when :unsigned,:signed,:int,:short,:float,:double,:long,:char,:void ret=declaration() when :struct ret=declaration() when :if ret=parse_if() when :while ret=parse_while() when :for ret=parse_for() when :switch ret=switch() when :return ret=parse_return when :break acceptIt ret=Break.new when :continue acceptIt ret=Continue.new when :do ret=do_while() when :goto ret=parse_goto() when :ident case showNext(2).kind when :ident ret=declaration when :colon l=parse_label s=statement ret=LabeledStmt.new(l,s) else ret=expression_statement end when :const,:volatile ret=declaration() when :semicolon acceptIt #ret=expression_statement when :inc_op,:dec_op,:mul ret=expression_statement else show_line(showNext.pos) raise "unknown statement start at #{showNext.pos} .Got #{showNext.kind} #{showNext.val}" end maybe :semicolon dedent return ret end |
#switch ⇒ Object
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/crokus/parser.rb', line 335 def switch indent "switch" expect :switch expect :lparen e=expression ret=Switch.new(e,cases=[],default=nil) expect :rparen expect :lbrace while showNext.is? :case expect :case case_e=expression case_body=Body.new expect :colon while showNext.kind!=:rbrace and showNext.kind!=:case and showNext.kind!=:default case_body << statement() end cases << Case.new(case_e,case_body) end if showNext.is? :default acceptIt expect :colon default_body=Body.new while showNext.kind!=:rbrace default_body << statement() end ret.default=default_body end expect :rbrace dedent return ret end |
#type_specifier ⇒ Object
912 913 914 915 916 917 918 919 920 921 922 923 |
# File 'lib/crokus/parser.rb', line 912 def type_specifier type=Type.new(nil,[]) indent "type_specifier #{showNext}" if showNext.is? STARTERS_TYPE_SPECIFIER ret=acceptIt type.name=ret else raise "ERROR : type_specifier. Expecting one of '#{STARTERS_TYPE_SPECIFIER}' at #{showNext.pos}" end dedent type end |
#typedef ⇒ Object
193 194 195 196 197 198 199 200 |
# File 'lib/crokus/parser.rb', line 193 def typedef indent "typedef" expect :typedef type=parse_type() id=expect(:ident) dedent return Typedef.new(type,id) end |
#typename ⇒ Object
888 889 890 891 892 893 894 895 896 |
# File 'lib/crokus/parser.rb', line 888 def typename indent "typename" type=specifier_qualifier while showNext.is? STARTERS_ABSTRACT_DECLARATOR list << abstract_decl end dedent list end |
#unary ⇒ Object
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 |
# File 'lib/crokus/parser.rb', line 971 def unary if STARTERS_PRIMARY.include? showNext.kind u=postfix elsif showNext.is? [:and,:mul,:add,:sub,:tilde,:not] op=acceptIt e=castexp u=Unary.new(op,e) else case showNext.kind when :inc_op op=acceptIt u=unary u=PreFixAccu.new(op,u) when :dec_op op=acceptIt u=unary u=PreFixAccu.new(op,u) when :sizeof u=sizeof() else raise "not an unary. showNext : #{showNext}" end end return u end |