cx86/lexer.rb
2019-06-23 10:40:25 -05:00

206 lines
4.1 KiB
Ruby

#--
# DO NOT MODIFY!!!!
# This file is automatically generated by rex 1.0.5
# from lexical definition file "lexer.rex".
#++
require 'racc/parser'
class CX86 < Racc::Parser
require 'strscan'
class ScanError < StandardError ; end
attr_reader :lineno
attr_reader :filename
attr_accessor :state
def scan_setup(str)
@ss = StringScanner.new(str)
@lineno = 1
@state = nil
end
def action
yield
end
def scan_str(str)
scan_setup(str)
do_parse
end
alias :scan :scan_str
def load_file( filename )
@filename = filename
open(filename, "r") do |f|
scan_setup(f.read)
end
end
def scan_file( filename )
load_file(filename)
do_parse
end
def next_token
return if @ss.eos?
# skips empty actions
until token = _next_token or @ss.eos?; end
token
end
def _next_token
text = @ss.peek(1)
@lineno += 1 if text == "\n"
token = case @state
when nil
case
when (text = @ss.scan(/int/))
action {[:TYPE,:INT]}
when (text = @ss.scan(/\(/))
action {[:OPEN_PAREN,"("]}
when (text = @ss.scan(/\)/))
action {[:CLOSE_PAREN,")"]}
when (text = @ss.scan(/\{/))
action {[:OPEN_CURLY,"{"]}
when (text = @ss.scan(/\}/))
action {[:CLOSE_CURLY,"}"]}
when (text = @ss.scan(/;/))
action {[:SEMICOLON,";"]}
when (text = @ss.scan(/-/))
action {[:MINUS,"-"]}
when (text = @ss.scan(/~/))
action {[:COMP,"~"]}
when (text = @ss.scan(/!/))
action {[:LNEG,"!"]}
when (text = @ss.scan(/\+=/))
action {[:SETEQ,:plus]}
when (text = @ss.scan(/\-\=/))
action {[:SETEQ,:minus]}
when (text = @ss.scan(/\/\=/))
action {[:SETEQ,:mul]}
when (text = @ss.scan(/\*\=/))
action {[:SETEQ,:div]}
when (text = @ss.scan(/\%\=/))
action {[:SETEQ,:mod]}
when (text = @ss.scan(/\<\<\=/))
action {[:SETEQ,:shl]}
when (text = @ss.scan(/\>\>\=/))
action {[:SETEQ,:shr]}
when (text = @ss.scan(/\&\=/))
action {[:SETEQ,:and]}
when (text = @ss.scan(/\|\=/))
action {[:SETEQ,:or]}
when (text = @ss.scan(/\^\=/))
action {[:SETEQ,:xor]}
when (text = @ss.scan(/\+/))
action {[:PLUS,"+"]}
when (text = @ss.scan(/\*/))
action {[:MUL,"*"]}
when (text = @ss.scan(/\//))
action {[:DIV,"/"]}
when (text = @ss.scan(/%/))
action {[:MOD,"%"]}
when (text = @ss.scan(/\&/))
action {[:AND,"&"]}
when (text = @ss.scan(/\|/))
action {[:OR,"|"]}
when (text = @ss.scan(/\^/))
action {[:XOR,"^"]}
when (text = @ss.scan(/<</))
action {[:SHL,"<<"]}
when (text = @ss.scan(/>>/))
action {[:SHR,">>"]}
when (text = @ss.scan(/\&\&/))
action {[:LAND,"&&"]}
when (text = @ss.scan(/\|\|/))
action {[:LOR,"||"]}
when (text = @ss.scan(/\=\=/))
action {[:EQ,"=="]}
when (text = @ss.scan(/\!\=/))
action {[:NE,"!="]}
when (text = @ss.scan(/\</))
action {[:LT,"<"]}
when (text = @ss.scan(/\<\=/))
action {[:LE,"<="]}
when (text = @ss.scan(/\>/))
action {[:GT,">"]}
when (text = @ss.scan(/\>\=/))
action {[:GE,">="]}
when (text = @ss.scan(/=/))
action {[:EQUALS,"="]}
when (text = @ss.scan(/,/))
action {[:COMMA,","]}
when (text = @ss.scan(/return/))
action {[:RETURN,"return"]}
when (text = @ss.scan(/\d+/))
action {[:NUM,text.to_i]}
when (text = @ss.scan(/\w+/))
action {[:IDENT,text]}
when (text = @ss.scan(/[ \t\n]+/))
action {}
else
text = @ss.string[@ss.pos .. -1]
raise ScanError, "can not match: '" + text + "'"
end # if
else
raise ScanError, "undefined state: '" + state.to_s + "'"
end # case state
token
end # def _next_token
def tokenize(code)
scan_setup(code)
tokens = []
while token = next_token
tokens << token
end
tokens
end # class
end