Skip to content

Instantly share code, notes, and snippets.

@qnnnnez
Created April 3, 2019 13:35
Show Gist options
  • Save qnnnnez/0bb45797b169193be9f9b51521344843 to your computer and use it in GitHub Desktop.
Save qnnnnez/0bb45797b169193be9f9b51521344843 to your computer and use it in GitHub Desktop.
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