루비로 코딩했구....사칙연산하고 괄호를 지원한다능. RDP Recursive Descent Parser 를 만들어서 바꿔봤다능.
더보기
|
|
# id -> [0-9]+
# Expr -> Term Expr'
# Expr' -> + Term Expr' | - Term Expr' | ε
# Term -> Factor Term'
# Term' -> * Factor Term' | / Factor Term' | ε
# Factor -> ( Expr ) | id
class InfixParser
def initialize(src)
@lexer = InfixLexer.new src
@lookahead = @lexer.get_token
expr
puts
end
def expr
term
expr_prime
end
def term
factor
term_prime
end
def term_prime
if match "*"
factor
term_prime
print " * "
elsif match "/"
factor
term_prime
print " / "
else
# do nothing
end
end
def expr_prime
if match "+"
term
expr_prime
print " + "
elsif match "-"
term
expr_prime
print " - "
else
# do nothing
end
end
def factor
if match "("
expr
error "unexptected symbol #{@lookahead}" unless match ")"
else
error "syntex error" unless id
end
end
def id
if @lookahead =~ /[0-9]+/
print " #{@lookahead} "
@lookahead = @lexer.get_token
return true
end
return false
end
private
def match(t)
if @lookahead == t
@lookahead = @lexer.get_token
return true
end
return false
end
def error(message)
raise message
end
end
class InfixLexer
def initialize(src)
@src = src
@tokens = []
@position = 0
toknize
end
def get_token
result = @tokens[@position]
@position += 1
return result
end
private
def toknize
while true
skip_whiteword
case
when current_char =~ /[()+\-*\/]/
@tokens << current_char
@position += 1
when current_char =~ /[0-9]/
temp_token = ""
while true
temp_token << current_char
@position += 1
break unless current_char =~ /[0-9]/
end
@tokens << temp_token
when @position >= @src.size
break
else
error "syntex error"
end
end
@position = 0
end
def skip_whiteword
while current_char =~ /\s/
@position += 1
end
end
def current_char
@src[@position..@position]
end
def error(message)
raise message
end
end
puts "infix : 66+7+(647/ 353 * 33 -1)/ 985"
print "postfix : "
par = InfixParser.new "66+7+(647/ 353 * 33 -1)/ 985"
|
Output:
|
|
infix : 66+7+(647/ 353 * 33 -1)/ 985
postfix : 66 7 647 353 33 * / 1 - 985 / + +
|
댓글을 달아 주세요