我正尝试在python中创建一个简单的Lexer,以将一些sudo代码解析为有趣的项目。
我将文件读取为字符串,然后使用code = list(code)
将字符串转换为char数组
文件如下:
print "Hello World";
数组最终看起来像这样:
code = ['p', 'r', 'i', 'n', 't', ' ', '"', 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '"', ';']
这时,我遍历它,并使用以下代码将某些字符附加到数组中:
for c in code:
if c == '(':
TOKENS.append(Tokens.LPAREN)
if c == ')':
TOKENS.append(Tokens.RPAREN)
if c == '}':
TOKENS.append(Tokens.RBRACKET)
if c == '{':
TOKENS.append(Tokens.LBRACKET)
if c == '+':
TOKENS.append(Tokens.PLUS_OPERATOR)
if c == '-':
TOKENS.append(Tokens.MINUS_OPERATOR)
if c == ' ':
TOKENS.append(Tokens.WHITESPACE)
if c == ';':
TOKENS.append(Tokens.SEMICOLON)
if c == "\"":
TOKENS.append(Tokens.QUOTATION)
if c.isalpha() or c.isnumeric():
curr_string.append(c)
if not c.isalpha() and not c.isnumeric():
TOKENS.append("STRING: " + ''.join(curr_string))
curr_string = []
Tokens
是一个包含以下数据的枚举:
@unique
class Tokens(Enum):
LPAREN = -1
RPAREN = -2
RBRACKET = -3
LBRACKET = -4
STRING = -5
PLUS_OPERATOR = -6
MINUS_OPERATOR = -7
INVALID_TOKEN = -8
WHITESPACE = -9
SEMICOLON = -10
这在大多数情况下都可以正常工作,但是在遍历TOKENS
时,会显示以下内容:
Tokens.WHITESPACE
STRING: print
Tokens.QUOTATION
STRING:
Tokens.WHITESPACE
STRING: Hello
Tokens.QUOTATION
STRING: World
Tokens.SEMICOLON
STRING:
为什么控制台为什么在数组的开头打印出空格?为什么它会混淆附加到TOKENS
的项目的顺序?
谢谢您的帮助。
答案 0 :(得分:1)
最短答案:问题在于您错误地订购了if
条语句。另外,if not c.isalpha() and not c.isnumeric():
应该是if not c.isalpha() and not c.isnumeric() and curr_string:
让我们看一下print "Hello World";
字符串。 code
数组将为['p', 'r', 'i', 'n', 't', ' ', '"', 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '"', ';']
。循环的前5次迭代将结束于:
if c.isalpha() or c.isnumeric():
curr_string.append(c)
第六次迭代,满足两个if
,第一个是:
if c == ' ':
TOKENS.append(Tokens.WHITESPACE)
并且只有在此之后,它将"STRING: "
附加到TOKENS
。要解决此问题,您需要将if not c.isalpha() and not c.isnumeric()
放在循环代码的顶部。另外,始终会打印STRING
令牌,因为您无需检查curr_string != []
。