metasm/parse.rb in metasm-1.0.3 vs metasm/parse.rb in metasm-1.0.4
- old
+ new
@@ -24,23 +24,15 @@
# find prefixes, break on opcode name
while tok = lexer.readtok and parse_prefix(i, tok.raw)
lexer.skip_space_eol
end
+
+ lexer.unreadtok(tok)
+ tok = parse_instruction_mnemonic(lexer)
return if not tok
- # allow '.' in opcode name
- tok = tok.dup
- while ntok = lexer.nexttok and ntok.type == :punct and ntok.raw == '.'
- tok.raw << lexer.readtok.raw
- ntok = lexer.readtok
- raise tok, 'invalid opcode name' if not ntok or ntok.type != :string
- tok.raw << ntok.raw
- end
-
- raise tok, 'invalid opcode' if not opcode_list_byname[tok.raw]
-
i.opname = tok.raw
i.backtrace = tok.backtrace
lexer.skip_space
# find arguments list
@@ -61,10 +53,27 @@
parse_instruction_fixup(i)
i
end
+ # return a lexer token with an instruction mnemonic in #raw
+ # allows '.' in opcode name
+ # return nil at eof
+ def parse_instruction_mnemonic(lexer)
+ return if not tok = lexer.readtok
+ tok = tok.dup
+ while ntok = lexer.nexttok and ntok.type == :punct and ntok.raw == '.'
+ tok.raw << lexer.readtok.raw
+ ntok = lexer.readtok
+ raise tok, 'invalid opcode name' if not ntok or ntok.type != :string
+ tok.raw << ntok.raw
+ end
+
+ raise tok, 'invalid opcode' if not opcode_list_byname[tok.raw]
+ tok
+ end
+
def parse_instruction_checkproto(i)
opcode_list_byname[i.opname].to_a.find { |o|
o.args.length == i.args.length and o.args.zip(i.args).all? { |f, a| parse_arg_valid?(o, f, a) }
}
end
@@ -419,11 +428,11 @@
end
raise tok, 'syntax error' if ntok = @lexer.nexttok and ntok.type != :eol
@cursource << Padding.new(fillwith, tok.backtrace) << Offset.new(e, tok.backtrace)
else
- @cpu.parse_parser_instruction(self, tok)
+ @cpu.parse_parser_instruction(@lexer, tok)
end
end
def parse_data
raise ParseError, 'internal error' if not tok = @lexer.readtok
@@ -744,9 +753,11 @@
val
end
# for boolean operators, true is 1 (or anything != 0), false is 0
def parse(lexer)
+ lexer = Preprocessor.new(lexer) if lexer.kind_of?(::String)
+
opstack = []
stack = []
return if not e = parse_value(lexer)