class Token:
def __init__(self, type_, value=None):
self.type = type_
self.value = value
def __repr__(self):
return f'{self.type}:{self.value}' if self.value else f'{self.type}'
class Lexer:
def __init__(self, text):
self.text = text
self.pos = 0
self.current_char = self.text[self.pos] if text else None
def advance(self):
self.pos += 1
self.current_char = self.text[self.pos] if self.pos < len(self.text) else None
def skip_whitespace(self):
while self.current_char and self.current_char.isspace():
self.advance()
def get_word(self):
word = ''
while self.current_char and (self.current_char.isalnum() or self.current_char == '_'):
word += self.current_char
self.advance()
return word
def get_string(self):
string = ''
self.advance() # Skip first quote
while self.current_char and self.current_char != '"':
string += self.current_char
self.advance()
self.advance() # Skip closing quote
return string
def tokenize(self):
tokens = []
while self.current_char:
if self.current_char.isspace():
self.skip_whitespace()
continue
if self.current_char.isalpha():
word = self.get_word()
if word.lower() == 'dim':
tokens.append(Token('DIM'))
elif word.lower() == 'as':
tokens.append(Token('AS'))
elif word.lower() == 'print':
tokens.append(Token('PRINT'))
else:
tokens.append(Token('IDENTIFIER', word))
continue
if self.current_char == '=':
tokens.append(Token('EQUALS'))
self.advance()
continue
if self.current_char == '"':
string = self.get_string()
tokens.append(Token('STRING', string))
continue
self.advance()
return tokens
class Parser:
def __init__(self, tokens):
self.tokens = tokens
self.pos = 0
self.current_token = tokens[0] if tokens else None
def advance(self):
self.pos += 1
self.current_token = self.tokens[self.pos] if self.pos < len(self.tokens) else None
def parse(self):
if not self.current_token:
return None
if self.current_token.type == 'DIM':
return self.parse_variable_declaration()
elif self.current_token.type == 'IDENTIFIER':
return self.parse_assignment()
elif self.current_token.type == 'PRINT':
return self.parse_print()
return None
def parse_variable_declaration(self):
self.advance() # Skip 'DIM'
if self.current_token and self.current_token.type == 'IDENTIFIER':
var_name = self.current_token.value
self.advance()
if self.current_token and self.current_token.type == 'AS':
self.advance()
if self.current_token and self.current_token.type == 'IDENTIFIER':
var_type = self.current_token.value
return {'type': 'variable_declaration', 'name': var_name, 'var_type': var_type}
def parse_assignment(self):
var_name = self.current_token.value
self.advance()
if self.current_token and self.current_token.type == 'EQUALS':
self.advance()
if self.current_token and self.current_token.type == 'STRING':
value = self.current_token.value
return {'type': 'assignment', 'name': var_name, 'value': value}
def parse_print(self):
self.advance() # Skip 'PRINT'
if self.current_token and self.current_token.type == 'IDENTIFIER':
var_name = self.current_token.value
return {'type': 'print', 'name': var_name}
class Interpreter:
def __init__(self):
self.variables = {}
def run(self, text):
lexer = Lexer(text)
tokens = lexer.tokenize()
parser = Parser(tokens)
result = parser.parse()
if result:
if result['type'] == 'variable_declaration':
self.variables[result['name']] = {'type': result['var_type'], 'value': None}
print(f"声明变量: {result['name']} (类型: {result['var_type']})")
elif result['type'] == 'assignment':
if result['name'] in self.variables:
self.variables[result['name']]['value'] = result['value']
print(f"赋值: {result['name']} = {result['value']}")
else:
print(f"错误: 变量 {result['name']} 未声明")
elif result['type'] == 'print':
if result['name'] in self.variables:
print(f"输出: {self.variables[result['name']]['value']}")
else:
print(f"错误: 变量 {result['name']} 未声明")
else:
print("语法错误")
def run_file(filename):
try:
with open(filename, 'r') as file:
interpreter = Interpreter()
for line in file:
line = line.strip()
if line:
interpreter.run(line)
except FileNotFoundError:
print(f"错误: 文件 {filename} 不存在")
def run_shell():
interpreter = Interpreter()
while True:
try:
text = input('SimpleScript > ')
if text.lower() == 'exit':
break
if text.startswith('run '):
filename = text[4:].strip()
if filename.endswith('.ss'):
run_file(filename)
else:
print("错误: 只能运行 .ss 文件")
elif text.strip():
interpreter.run(text)
except KeyboardInterrupt:
break
except Exception as e:
print(f"错误: {str(e)}")
if __name__ == "__main__":
run_shell()