require 'set' class Grammardef def initialize @rules = Hash.new() end def setexiom(axiom) @axiom = axiom #print "axiom:\n", @axiom, "\n", "setted\n" end def setnterm(nterms) @nterms = nterms.split(/ +/).delete_if {|x| x == ""} #print "nterms:\n", @nterms, "\n", "setted\n" end def setterm(terms) @terms = terms.split(/ +|\"/).delete_if {|x| x == ""} #print "terms:\n", @terms, "\n", "setted\n" end def setrules(rules) #print "rules:\n", rules.split(/( *|\\n)\$RULE /).delete_if {|x| (x == "") || (x == "\\n")}, "\n", "setted\n" rulesregexp = Regexp.new(/\$RULE (([A-Z]\'{0,1}) =(([( [A-Z]\'{0,1})( \"[a-z]\"| \"\*\"| \"\+\"| \"\(\"| \"\)\")]+\\n| \$EPS\\n)+))/) a = rulesregexp.match(rules)[0] #print "rules:\n", a, "\n" self.setrule(a) while rulesregexp.match(rules) != nil rules = rules[rulesregexp.match(rules)[0].length, rules.length] if (rulesregexp.match(rules) != nil) a = rulesregexp.match(rules)[0] #print a, "\n" self.setrule(a) end end #print "rules hash:\n", @rules, "\n" end def setrule(rule) ruleregexp = Regexp.new(/\$RULE (([A-Z]\'{0,1}) =(([( [A-Z]\'{0,1})( \"[a-z]\"| \"\*\"| \"\+\"| \"\(\"| \"\)\")]+\\n| \$EPS\\n)+))/) leftpart = ruleregexp.match(rule)[2] rightparts = ruleregexp.match(rule)[3] #print "rule left:\n", leftpart, "\nrule rights:\n", rightparts, "\n" rightpartsarr = rightparts.split(/\\n/).delete_if {|x| x == ""} #print "right parts array\n", rightpartsarr, "\n******************************************************\n" rightpartsset = Set.new() (rightpartsarr).each do |x| onealt = x.split(/ +|\"/).delete_if {|x| x == ""} rightpartsset.add(onealt) #print onealt, "\n******************************************************\n" @rules[leftpart] = rightpartsset end end def axiom @axiom end def nterms @nterms end def terms @terms end def rules @rules end def rulebynterm(nterm) @rules[nterm] end end class Progreader def initialize(exampleprog) #exampleprog = "$AXIOM E\\n$NTERM E' T T' F\\n$TERM \"+\" \"*\" \"(\" \")\" \"n\"\\n$RULE E = T\\n$RULE E' = \"+\" T E'\\n $EPS\\n" progregexp = Regexp.new(/\$AXIOM ([A-Z]\'{0,1})\\n\$NTERM(( [A-Z]\'{0,1})+)\\n\$TERM(( "[a-z\*\+\(\)]")+)\\n((\$RULE (([A-Z]\'{0,1}) =(([( [A-Z]\'{0,1})( \"[a-z]\"| \"\*\"| \"\+\"| \"\(\"| \"\)\")]+\\n| \$EPS\\n)+)))+)/) prog = progregexp.match(exampleprog) @arifmGrammar = Grammardef.new #print "allprogram:\n", prog[0], "\n" #print "axiom:\n", prog[1], "\n" @arifmGrammar.setexiom(prog[1]) #print "nterm:\n", prog[2], "\n" @arifmGrammar.setnterm(prog[2]) #print "term:\n", prog[4], "\n" @arifmGrammar.setterm(prog[4]) #print "rules:\n", prog[6], "\n" @arifmGrammar.setrules(prog[6]) end def arifmGrammar @arifmGrammar end end class Filecustomreader def initialize(filename) #read from file file = File.new(filename, "r") @mygram = ""; while line = file.gets @mygram += line.chomp + "\n" end #print mygram #print "\nqqqqq\n" end def mygram @mygram end end exampleprog = "$AXIOM E\\n$NTERM E' T T' F\\n$TERM \"+\" \"*\" \"(\" \")\" \"n\"\\n$RULE E = T\\n$RULE E' = \"+\" T E'\\n $EPS\\n$RULE T = F T'\\n$RULE T' = \"*\" F T'\\n $EPS\\n$RULE F = \"n\"\\n \"(\" E \")\"\\n" progreader = Progreader.new(exampleprog) arifmGrammar = progreader.arifmGrammar #print arifmGrammar, "\n"