buf=[]
token=[]
def lex():
def read():
f=open('lex.txt','r')
data=f.readline()
data=data.split(' ')
return data
lex=read()
def operator(i):
op=[' ','-','/','*','<','>','>=','<=']
if i in op:
buf.append(i)
token.append('RELOP')
return True
def error(i):
digit=[0,1,2,3,4,5,6,7,8,9,0]
try:
if i[0] in digit:
buf.append(i)
token.append('ERROR')
return True
except:
pass
def keyword(i):
keyword=['if','while','for']
if i in keyword:
buf.append(i)
x=i.upper()
token.append(x '_TOKEN')
return True
def ident(i):
alph=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','q','r','s','t','u','v','w','x','y','z']
try:
if i[0] in alph:
buf.append(i)
token.append('ID')
return True
except:
pass
def floati(i):
try:
res = i.replace('.', '', 1).isdigit()
if res:
buf.append(i)
token.append('FLOAT')
return True
except:
pass
def integ(i):
try:
x=int(i)
buf.append(i)
token.append('INTEGER')
return True
except:
pass
count=0
for i in lex:
if keyword(i):
print(token[count])
continue
elif operator(i):
print(token[count])
continue
elif error(i):
print(token[count])
continue
elif floati(i):
print(token[count])
continue
elif integ(i):
print(token[count])
continue
elif ident(i):
print(token[count])
continue
else:
print("Zaaa anan xd")
count 1
lex()
I am trying to write a lexical analyzer in Python. I want to check an input string from a file for a float or integer, but when I use float()
my code changes the string type of integer to float and returns as float. I do not want to check string using float()
or int()
. I want to append the string to an array without changing it.
CodePudding user response:
A simple way to check if a string is int or float:
def is_int(s):
try:
int(s)
return True
except ValueError:
return False
Then:
>>> is_int('-73')
True
>>> is_int('2.3')
False
But note, the above is_int()
only checks for int
. If not, it is not necessarily a float
:
>>> is_int('foo')
False
But you could easily duplicate that pattern for float
.
CodePudding user response:
The str module offers the isdigit
function, returning True
if a string represents a digit.
str.isdigit("5")
# True
str.isdigit("five")
# False
For float
type, you could write a short function using try-except
:
def check_float(string):
try:
float(string)
return True
except ValueError:
return False
CodePudding user response:
I think this does what you want, without using regexes. Notice that this handles negative numbers, which yours did not. I've removed the called to error(i)
, since it was pointless.
def read():
return open('lex.txt','r').read().split()
op=[' ','-','/','*','==','!=','<','>','>=','<=']
def operator(i):
if i in op:
buf.append(i)
token.append('RELOP')
return True
return False
# I don't know what this is doing. `i` is a string.
def error(i):
digit=[0,1,2,3,4,5,6,7,8,9,0]
if i[0] in digit:
buf.append(i)
token.append('ERROR')
return True
return False
keywords=['if','while','for']
def keyword(i):
if i in keywords:
buf.append(i)
x=i.upper()
token.append(x '_TOKEN')
return True
return False
alph='abcdefghijklmnopqrstuvwxyz'
def ident(i):
if i[0] in alph:
buf.append(i)
token.append('ID')
return True
return False
def floati(i):
tmp = i
if tmp[0] in " -":
tmp = tmp[1:]
if tmp.replace('.', '', 1).isdigit():
buf.append(i)
token.append('FLOAT')
return True
return False
def integ(i):
if i.isdigit() or i[0] in " -" and i[1:].isdigit():
buf.append(i)
token.append('INTEGER')
return True
return False
def parse(lex):
for i in lex:
if keyword(i) or \
operator(i) or \
integ(i) or \
floati(i) or \
ident(i):
print(i, token[-1])
else:
print(i, "Syntax error")
buf=[]
token=[]
parse(read())
CodePudding user response:
strs = ["x", "45", "5.4", "-33", "size33", "34RR", "if"]
from re import match
strs = ["18","18.5","s","-35"]
for s in strs:
if match("^-{0,1}[0-9^]*(\.[0-9] ){0,1}$",s):
if s[0] == "-":
s = s[1:]
if s.isdigit():
print("int")
else:
print("float")
else:
print("other")