206 lines
4.1 KiB
Ruby
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
|