Created
April 3, 2019 13:35
-
-
Save qnnnnez/0bb45797b169193be9f9b51521344843 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
flowscript = ''' | |
查询结果 = 录取信息库.单条查询({ | |
“姓名” : 姓名输入框.内容, | |
“准考证号” : 准考证输入框.内容, | |
“身份证号” : 身份证输入框.内容, | |
}); | |
如果(查询结果){ | |
结果页.姓名文本.内容 = 查询结果.分数; | |
结果页.高考分数文本.内容 = 查询结果.分数; | |
结果页.录取结果文本.内容 = 查询结果.录取状态; | |
进入(成功页); | |
}否则{ | |
提示(“未查询到相关考生信息,请重试”); //没有成功不跳转 | |
} | |
''' | |
from collections import namedtuple | |
import regex | |
import pprint | |
def escaped(symbols): | |
return '|'.join(regex.escape(symbol) for symbol in symbols) | |
symbols = ' =(){},;' | |
pattern = regex.compile('(?<={0})|(?={0})'.format(escaped(symbols))) | |
def tokenize(src): | |
src = src.replace('“', '"').replace('”', '"') | |
src = src.replace('(', '(').replace(')', ')') | |
src = src.replace('。', '.') | |
lines = src.splitlines() | |
for line in lines: | |
for token in pattern.split(line.split('//')[0]): | |
token = token.strip() | |
if token: | |
yield token | |
AssignStmt = namedtuple('AssignStmt', ['var_name', 'init_val']) | |
ExprStmt = namedtuple('ExprStmt', ['expr']) | |
FunctionCall = namedtuple('FunctionCall', ['func', 'args']) | |
IfStmt = namedtuple('IfStmt', ['condition', 'then', 'orelse']) | |
MemberExpr = namedtuple('MemberExpr', ['instance', 'member']) | |
class Parser: | |
def __init__(self, src): | |
self.src = src | |
self.tokens = list(tokenize(src)) | |
self.offset = 0 | |
self.symbols =symbols | |
self.keywords = ['如果', '否则'] | |
@property | |
def eof(self): | |
return self.offset >= len(self.tokens) | |
@property | |
def current_token(self): | |
if not self.eof: | |
return self.tokens[self.offset] | |
def move(self, offset): | |
self.offset += offset | |
def expect(self, token): | |
assert self.tokens[self.offset] == token | |
self.offset += 1 | |
def stmts(self): | |
result = [] | |
while not self.eof: | |
stmt = self.stmt() | |
if stmt is None: | |
break | |
result.append(stmt) | |
return result | |
def stmt(self): | |
if self.current_token == '{': | |
self.move(1) | |
result = self.stmts() | |
self.expect('}') | |
return result | |
result = self.if_stmt() | |
if result: | |
return result | |
result = self.assign_stmt() | |
if result: | |
return result | |
result = self.expr() | |
if result and self.current_token == ';': | |
self.move(1) | |
return ExprStmt(expr=result) | |
def assign_stmt(self): | |
before = self.offset | |
id = self.current_token | |
self.move(1) | |
if self.current_token != '=': | |
self.offset = before | |
return | |
self.move(1) | |
expr = self.expr() | |
self.expect(';') | |
return AssignStmt('$' + id, expr) | |
def expr(self): | |
result = self.constant() | |
if result: | |
return self.maybe_function_call(result) | |
result = self.create_dict() | |
if result: | |
return result | |
if self.current_token in self.symbols or self.current_token in self.keywords: | |
return | |
result = '$' + self.current_token | |
self.move(1) | |
return self.maybe_function_call(result) | |
def constant(self): | |
if self.current_token.startswith('"') and self.current_token.endswith('"'): | |
result = self.current_token[1:-1] | |
self.move(1) | |
return result | |
def maybe_function_call(self, func): | |
before = self.offset | |
if self.current_token != '(': | |
return func | |
self.move(1) | |
args = self.args() | |
if args is None: | |
self.offset = before | |
return func | |
if self.current_token != ')': | |
self.offset = before | |
return func | |
self.move(1) | |
return FunctionCall(func=func, args=args) | |
def maybe_member(self, obj): | |
if self.current_token == '.': | |
self.move(1) | |
member = self.current_token | |
self.move(1) | |
return MemberExpr(obj, member) | |
else: | |
return obj | |
def args(self): | |
before = self.offset | |
result = [] | |
if self.current_token == ')': | |
return result | |
first = self.expr() | |
if first is None: | |
self.offset = before | |
return | |
else: | |
result.append(first) | |
while self.current_token == ',': | |
self.move(1) | |
result.append(self.expr()) | |
if self.current_token != ')': | |
self.offset = before | |
return | |
return result | |
def create_dict(self): | |
before = self.offset | |
if self.current_token != '{': | |
return | |
self.move(1) | |
result = {} | |
if self.current_token == '}': | |
self.move(1) | |
return result | |
first_key = self.expr() | |
if first_key is None or self.current_token != ':': | |
self.offset = before | |
return | |
self.move(1) | |
first_value = self.expr() | |
result[first_key] = first_value | |
while self.current_token == ',': | |
self.move(1) | |
if self.current_token == '}': | |
break | |
key = self.expr() | |
if key is None or self.current_token != ':': | |
self.offset = before | |
return | |
self.move(1) | |
value = self.expr() | |
result[key] = value | |
if self.current_token == '}': | |
self.move(1) | |
return result | |
else: | |
self.offset = before | |
def if_stmt(self): | |
before = self.offset | |
if self.current_token != '如果': | |
return | |
self.move(1) | |
self.expect('(') | |
condition = self.expr() | |
self.expect(')') | |
then = self.stmt() | |
self.expect('否则') | |
orelse = self.stmt() | |
return IfStmt(condition, then, orelse) | |
parser = Parser(flowscript) | |
result = parser.stmts() | |
pp.pprint(result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment