# File lib/crokus/parser_only.rb, line 934 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 acceptIt when :char_lit return acceptIt when :lparen acceptIt e=expression expect :rparen return Parenth.new(e) when :lbrace return array_or_struct_init() end end
class Crokus::ParserOnly
Constants
- ASSIGN_OP
- STARTERS_ABSTRACT_DECLARATOR
abstract_declarator
: pointer | direct_abstract_declarator | pointer direct_abstract_declarator ;
- STARTERS_ARRAY_OR_STRUCT_INIT
- STARTERS_PRIMARY
- STARTERS_TYPE_QUALIFIER
pointer
: '*' | '*' type_qualifier_list | '*' pointer | '*' type_qualifier_list pointer ;
- STARTERS_TYPE_SPECIFIER
- STARTERS_UNARY
- UNARY_OP
Attributes
str[RW]
tokens[RW]
Public Class Methods
new()
click to toggle source
# File lib/crokus/parser_only.rb, line 15 def initialize @ppr=PrettyPrinter.new @verbose=false #@verbose=true end
Public Instance Methods
abstract_decl()
click to toggle source
# File lib/crokus/parser_only.rb, line 830 def abstract_decl indent "abstract_decl" if showNext.is_a? 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()
click to toggle source
# File lib/crokus/parser_only.rb, line 21 def acceptIt say showNext.kind.to_s+" "+showNext.val tokens.shift end
accu()
click to toggle source
# File lib/crokus/parser_only.rb, line 562 def accu indent "accu" #expect(:ident) lhs=expression case showNext.kind when :addadd,:subsub tok=acceptIt when :addeq,:subeq tok=acceptIt e=expression else show_line(showNext.pos) raise "unknown accumulator at #{showNext.pos}" end dedent Accu.new(lhs,tok,e) end
additive()
click to toggle source
# File lib/crokus/parser_only.rb, line 726 def additive indent "addititve : #{showNext}" multitive while showNext.is_a? [:add,:sub] acceptIt multitive end dedent end
andexp()
click to toggle source
# File lib/crokus/parser_only.rb, line 686 def andexp indent "andexp : #{showNext}" eqexp while showNext.is_a? :and acceptIt eqexp end dedent end
argument_expr_list()
click to toggle source
# File lib/crokus/parser_only.rb, line 956 def argument_expr_list expression while showNext.is_a? :comma acceptIt expression end end
array_or_struct_init()
click to toggle source
# File lib/crokus/parser_only.rb, line 964 def array_or_struct_init indent "array_or_struct_init" expect :lbrace elements=[] while !showNext.is_a? :rbrace elements << (e=expression) if showNext.is_a? :comma acceptIt end end expect :rbrace dedent return ArrayOrStructInit.new(elements) end
arrayed?()
click to toggle source
# File lib/crokus/parser_only.rb, line 399 def arrayed? return if tokens.empty? while showNext.is_a? :lbrack acceptIt if showNext.is_a? :rbrack acceptIt else e=expression expect :rbrack end end end
assign()
click to toggle source
# File lib/crokus/parser_only.rb, line 622 def assign indent "assign : #{showNext}" e1=cond_expr while showNext.is_a? ASSIGN_OP op=acceptIt e2=assign e1=Assign.new(e1,op,e2) end dedent return e1 end
castexp()
click to toggle source
# File lib/crokus/parser_only.rb, line 746 def castexp indent "castexpr : #{showNext}" case showNext.kind when :lparen # parenth expr OR casting ! res=is_casting? puts "casting? : #{res}" if @verbose if res casting else parenthesized end else unary end dedent end
casting()
click to toggle source
# File lib/crokus/parser_only.rb, line 775 def casting indent "casting : #{showNext}" expect :lparen typename expect :rparen unary dedent end
cond_expr()
click to toggle source
# File lib/crokus/parser_only.rb, line 634 def cond_expr indent "cond_expr : #{showNext}" logor while showNext.is_a? :qmark acceptIt expression expect :colon cond_expr end dedent end
dbg_print(node)
click to toggle source
# File lib/crokus/parser_only.rb, line 61 def dbg_print node puts "debug ast node".center(60,'-') puts node.accept(@ppr) puts "-"*60 end
dbg_print_next(n)
click to toggle source
# File lib/crokus/parser_only.rb, line 57 def dbg_print_next n p tokens[0..n-1].collect{|tok| tok.inspect} end
debug()
click to toggle source
declaration()
click to toggle source
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
# File lib/crokus/parser_only.rb, line 365 def declaration ret=[] @current_type=type=parse_type() declarator() arrayed? parenthesized? initialization? while tokens.any? and showNext.is_a?(:comma) acceptIt pointed? declarator arrayed? initialization? end if tokens.any? maybe :semicolon end return ret end
declarator()
click to toggle source
# File lib/crokus/parser_only.rb, line 385 def declarator if showNext.is_a? :ident ret=@current_ident=Ident.new(acceptIt) end return ret end
define()
click to toggle source
# File lib/crokus/parser_only.rb, line 150 def define indent "define" expect :sharp expect :ident #define name=expect :ident e=expression() dedent return Define.new(name,e) end
design_unit()
click to toggle source
# File lib/crokus/parser_only.rb, line 107 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()
click to toggle source
# File lib/crokus/parser_only.rb, line 866 def direct_abstract_declarator raise end
do_while()
click to toggle source
# File lib/crokus/parser_only.rb, line 302 def do_while indent "do_while" expect :do body=statement() expect :while e=expression dedent DoWhile.new(e,body) end
eqexp()
click to toggle source
# File lib/crokus/parser_only.rb, line 696 def eqexp indent "eqexp : #{showNext}" relexp while showNext.is_a? [:eq,:neq] acceptIt relexp end dedent end
exclor()
click to toggle source
# File lib/crokus/parser_only.rb, line 676 def exclor indent "exclor : #{showNext}" andexp while showNext.is_a? :xor acceptIt andexp end dedent end
expect(kind)
click to toggle source
# File lib/crokus/parser_only.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()
click to toggle source
expression_statement()
click to toggle source
# File lib/crokus/parser_only.rb, line 590 def expression_statement if showNext.is_a? :semicolon return SemicolonStmt.new(acceptIt) else e=expression expect :semicolon return e end end
func_call(as_procedure=false)
click to toggle source
# File lib/crokus/parser_only.rb, line 427 def func_call as_procedure=false indent "func_call" name=expect(:ident) expect :lparen args=[] while !showNext.is_a? :rparen args << expression() if showNext.is_a? :comma acceptIt end end expect :rparen dedent FunCall.new(name,args,as_procedure) end
func_formal_arg()
click to toggle source
# File lib/crokus/parser_only.rb, line 219 def func_formal_arg indent "function_arg" @current_type=parse_type() declarator arrayed? parenthesized? dedent #return FormalArg.new(name,type) end
function_body()
click to toggle source
# File lib/crokus/parser_only.rb, line 229 def function_body indent "function_body" body=Body.new expect :lbrace while showNext.kind!=:rbrace body << statement() end expect :rbrace dedent return body end
function_decl(name,type_)
click to toggle source
# File lib/crokus/parser_only.rb, line 189 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()
click to toggle source
# File lib/crokus/parser_only.rb, line 204 def function_formal_args indent "function_formal_args" args=[] expect :lparen while !showNext.is_a? :rparen args << func_formal_arg() if !showNext.is_a? :rparen expect :comma end end expect :rparen dedent return args end
inclor()
click to toggle source
# File lib/crokus/parser_only.rb, line 666 def inclor indent "inclor : #{showNext}" exclor while showNext.is_a? :or acceptIt exclor end dedent end
include()
click to toggle source
# File lib/crokus/parser_only.rb, line 129 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?()
click to toggle source
# File lib/crokus/parser_only.rb, line 412 def initialization? return if tokens.empty? if showNext.is_a? :assign expect :assign expression end end
is_casting?()
click to toggle source
# File lib/crokus/parser_only.rb, line 763 def is_casting? i=0 tok=DUMMY while tok.kind!=:rparen tok=@tokens[i] i+=1 end tok=@tokens[i] return true if tok.is_a? STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT return false end
logand()
click to toggle source
# File lib/crokus/parser_only.rb, line 656 def logand indent "logand : #{showNext}" inclor while showNext.is_a? :andand acceptIt inclor end dedent end
logor()
click to toggle source
# File lib/crokus/parser_only.rb, line 646 def logor indent "logor : #{showNext}" logand while showNext.is_a? :oror acceptIt logand end dedent end
lookahead(n=2)
click to toggle source
# File lib/crokus/parser_only.rb, line 44 def lookahead(n=2) tokens[n] if tokens.any? end
maybe(kind)
click to toggle source
# File lib/crokus/parser_only.rb, line 26 def maybe kind return acceptIt if showNext.is_a? kind end
multitive()
click to toggle source
# File lib/crokus/parser_only.rb, line 736 def multitive indent "multitive : #{showNext}" castexp while showNext.is_a? [:mul,:div,:mod] acceptIt castexp end dedent end
parenthesized()
click to toggle source
# File lib/crokus/parser_only.rb, line 784 def parenthesized indent "parenthesized : #{showNext}" expect :lparen expression expect :rparen dedent end
parenthesized?()
click to toggle source
# File lib/crokus/parser_only.rb, line 420 def parenthesized? return if tokens.empty? if showNext.is_a? :lparen function_decl(@current_ident,@current_type) end end
parse(str)
click to toggle source
.….….… parsing methods .….……
# File lib/crokus/parser_only.rb, line 67 def parse str begin @str=str @tokens=Lexer.new.tokenize(str) @tokens=remove_comments() warnings=@tokens.select{|tok| tok.is_a? :lexer_warning} show_lexer_warnings(warnings) @tokens=@tokens.select{|tok| !tok.is_a? [: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
parseLoopCond()
click to toggle source
# File lib/crokus/parser_only.rb, line 548 def parseLoopCond indent "parseLoopCond" e=expression() dedent return e end
parseLoopEnd()
click to toggle source
# File lib/crokus/parser_only.rb, line 555 def parseLoopEnd indent "parseLoopEnd" s=statement() dedent return s end
parseLoopInit()
click to toggle source
# File lib/crokus/parser_only.rb, line 540 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
parse_body()
click to toggle source
# File lib/crokus/parser_only.rb, line 580 def parse_body body=Body.new expect :lbrace while !showNext.is_a? :rbrace body << statement() end expect :rbrace return body end
parse_else()
click to toggle source
# File lib/crokus/parser_only.rb, line 507 def parse_else indent "parse else" expect :else ret=Else.new ret.body=statement() dedent return ret end
parse_for()
click to toggle source
# File lib/crokus/parser_only.rb, line 526 def parse_for indent "parse_for" forloop=For.new expect :for expect :lparen forloop.init=expression_statement() forloop.cond=expression_statement() forloop.increment=expression() expect :rparen forloop.body=statement() dedent forloop end
parse_goto()
click to toggle source
# File lib/crokus/parser_only.rb, line 294 def parse_goto indent "goto" expect :goto #label id=expect(:ident) dedent Goto.new(id) end
parse_if()
click to toggle source
# File lib/crokus/parser_only.rb, line 490 def parse_if indent "parse_if" expect :if if showNext.is_a? :lparen # helps wrt casting. acceptIt lparen=true end cond=expression() expect :rparen if lparen body=statement() if showNext.is_a? :else else_=parse_else() end dedent return If.new(cond,body,else_) end
parse_label()
click to toggle source
# File lib/crokus/parser_only.rb, line 289 def parse_label expect :ident expect :colon end
parse_return()
click to toggle source
# File lib/crokus/parser_only.rb, line 342 def parse_return indent "parse_return" expect :return if showNext.is_a? :semicolon else e=expression end dedent Return.new(e) end
parse_struct()
click to toggle source
# File lib/crokus/parser_only.rb, line 160 def parse_struct indent "struct" expect :struct name=nil if showNext.is_a? :ident name=acceptIt end ret=Struct.new(name) if showNext.is_a? :lbrace acceptIt while !showNext.is_a? :rbrace ret.decls << declaration() end ret.decls.flatten! expect :rbrace end dedent return ret end
parse_type()
click to toggle source
# File lib/crokus/parser_only.rb, line 443 def parse_type indent "parse_type" qualifier=type_qualifier?() case showNext.kind when :signed,:unsigned acceptIt when :ident,:char,:int,:short,:long,:float,:double,:void tok=acceptIt ret=Type.new(tok) (ret.specifiers << qualifier) if qualifier when :struct struct=parse_struct() when :typedef typedef() else raise "Parsing ERROR in type declaration: '#{showNext}'" end while showNext.is_a? [:mul,:lparen] case showNext.kind when :mul acceptIt when :lparen acceptIt if showNext.is_a? :rparen acceptIt else expression expect :rparen end end end dedent return ret end
parse_while()
click to toggle source
# File lib/crokus/parser_only.rb, line 516 def parse_while indent "parse_while" expect :while cond=expression() body=[] body << statement() dedent return While.new(cond,body) end
pointed?()
click to toggle source
# File lib/crokus/parser_only.rb, line 392 def pointed? return if tokens.empty? while showNext.is_a? :mul acceptIt end end
pointer()
click to toggle source
# File lib/crokus/parser_only.rb, line 852 def pointer expect :mul while showNext.is_a? STARTERS_TYPE_QUALIFIER+[:mul] case showNext.kind when :volatile acceptIt when :const acceptIt when :mult acceptIt end end end
postfix()
click to toggle source
# File lib/crokus/parser_only.rb, line 904 def postfix indent "postfix : #{showNext}" primary while showNext.is_a? [:lbrack,:lparen,:dot,:inc_op,:dec_op,:ptr_op] case showNext.kind when :lbrack acceptIt expression expect :rbrack when :lparen acceptIt if !showNext.is_a? :rparen argument_expr_list end expect :rparen when :dot acceptIt expect :ident when :ptr_op acceptIt expect :ident when :inc_op acceptIt when :dec_op acceptIt end end dedent end
primary()
click to toggle source
relexp()
click to toggle source
# File lib/crokus/parser_only.rb, line 706 def relexp indent "relexp : #{showNext}" shiftexp while showNext.is_a? [:lte,:lt,:gte,:gt ] acceptIt shiftexp end dedent end
remove_comments()
click to toggle source
# File lib/crokus/parser_only.rb, line 90 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()
click to toggle source
# File lib/crokus/parser_only.rb, line 716 def shiftexp indent "shiftexp : #{showNext}" additive while showNext.is_a? [:shift_l,:shift_r] acceptIt additive end dedent end
showNext(n=1)
click to toggle source
# File lib/crokus/parser_only.rb, line 40 def showNext(n=1) tokens[n-1] if tokens.any? end
show_lexer_warnings(warnings)
click to toggle source
# File lib/crokus/parser_only.rb, line 84 def show_lexer_warnings warnings warnings.each do |warn| puts "lexer warning : #{warn.val} at #{warn.pos}" end end
show_line(pos)
click to toggle source
# File lib/crokus/parser_only.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
sizeof()
click to toggle source
# File lib/crokus/parser_only.rb, line 892 def sizeof expect :sizeof case showNext.kind when :lparen acceptIt typename expect :rparen else unary end end
spec_qualifier_list()
click to toggle source
# File lib/crokus/parser_only.rb, line 801 def spec_qualifier_list indent "spec_qualifier_list #{showNext.inspect}" while showNext.is_a? STARTERS_TYPE_SPECIFIER+STARTERS_TYPE_QUALIFIER if showNext.is_a? STARTERS_TYPE_SPECIFIER type_specifier else type_qualifier end end dedent end
statement(arg=nil)
click to toggle source
# File lib/crokus/parser_only.rb, line 241 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 :do ret=do_while() when :goto ret=parse_goto() when :ident case showNext(2).kind when :ident declaration when :colon parse_label statement else expression_statement end when :const,:volatile declaration when :semicolon expression_statement else show_line(showNext.pos) raise "unknown statement start at #{showNext.pos} .Got #{showNext.kind} #{showNext.val}" end dedent return ret end
switch()
click to toggle source
# File lib/crokus/parser_only.rb, line 312 def switch indent "switch" expect :switch expect :lparen e=expression ret=Switch.new(e,cases=[]) expect :rparen expect :lbrace while showNext.is_a? :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_a? :default acceptIt expect :colon while showNext.kind!=:rbrace statement() end end expect :rbrace dedent return ret end
type_qualifier?()
click to toggle source
# File lib/crokus/parser_only.rb, line 478 def type_qualifier? while showNext.is_a? STARTERS_TYPE_QUALIFIER case showNext.kind when :volatile acceptIt when :const acceptIt end end nil end
type_specifier()
click to toggle source
# File lib/crokus/parser_only.rb, line 814 def type_specifier indent "type_specifier #{showNext}" if showNext.is_a? STARTERS_TYPE_SPECIFIER acceptIt else raise "ERROR : type_specifier. Expecting one of '#{STARTERS_TYPE_SPECIFIER}' at #{showNext.pos}" end dedent end
typedef()
click to toggle source
# File lib/crokus/parser_only.rb, line 180 def typedef indent "typedef" expect :typedef type=parse_type() id=expect(:ident) dedent return Typedef.new(type,id) end
typename()
click to toggle source
# File lib/crokus/parser_only.rb, line 792 def typename indent "typename" spec_qualifier_list while showNext.is_a? STARTERS_ABSTRACT_DECLARATOR abstract_decl end dedent end
unary()
click to toggle source
# File lib/crokus/parser_only.rb, line 870 def unary if STARTERS_PRIMARY.include? showNext.kind postfix elsif showNext.is_a? [:and,:mul,:add,:sub,:tilde,:not] acceptIt castexp else case showNext.kind when :inc_op acceptIt unary when :dec_op acceptIt unary when :sizeof sizeof() else raise "not an unary" end end end