Beispiel #1
0
 def find(self, name):
     """
     沿着作用于链查找name的value
     """
     try:
         return self[name] if (name in self._dict) else self.outer.find(name)
     except AttributeError as e:
         print(colorful('{0} 在作用域链上不存在!'.format(name), 'Red'))
         return 'not-define-yet'
Beispiel #2
0
 def find(self, name):
     """
     沿着作用于链查找name的value
     """
     try:
         return self[name] if (name
                               in self._dict) else self.outer.find(name)
     except AttributeError as e:
         print(colorful('{0} 在作用域链上不存在!'.format(name), 'Red'))
         return 'not-define-yet'
Beispiel #3
0
 def calc_value(self, env=Env.std_env()):
     """
     在指定环境中求值, 或者对环境造成改变
     :param env: 表达式所在环境
     :return:表达式的值
     """
     if self.static and self.value:
         print(colorful('静态表达式, 直接返回值', 'Bold'))
         return self.value
     res = None
     stype, child = self.stype, self.child
     if stype == 'number':
         res = child[0].calc_value(env)
     elif stype == 'integer':
         res = int(self._value)
     elif stype == 'decimal':
         res = float(self._value)
     elif stype == 'string':
         res = self._value
     elif stype == 'bool':
         res = True if self._value == '$T' else False
     elif stype == 'symbol':
         self._value = child[0].raw_value
         res = child[0].calc_value(env)
     elif stype == 'identifier':
         res = env.find(self._value)
     elif stype == 'op':
         res = env.find(self._value)
     elif stype == 'atom' or self.stype == 'func':
         res = child[0].calc_value(env)
     elif stype == 'lexp':
         res = child[0].calc_value(env)
         if child[0].stype == 'list':
             res = [res, ]
             res = args_restore(res)
     elif stype == 'lexp-seq':
         if len(child) > 1:
             res = (child[0].calc_value(env), ) + child[1].calc_value(env)
         else:
             res = (child[0].calc_value(env), )
         # print 'this lexp-seq:', res
     elif stype == 'list':
         if len(child) == 3:
             res = child[1].calc_value(env)
         else:
             res = tuple()
     elif stype == 's-exp':
         func = child[1].calc_value(env)
         args = child[2].calc_value(env)
         if len(child) == 3:
             res = func()
         else:
             res = func(*[args_restore(arg) for arg in args])
     elif stype == 'define-exp':
         # <define-exp> ::= <(> <define> <symbol> <lexp> <)>
         symbol = child[2].child[0].raw_value
         define(env, symbol, child[3])
         res = symbol
     elif stype == 'args':
         if child[0].stype == 'symbol':
             res = (child[0].child[0].raw_value, )
         else:
             res = child[0].calc_value(env) + (child[1].child[0].raw_value, )
     elif stype == 'proc-body':
         if len(child) <= 1:
             res = child[0].calc_value(env)
         else:
             # 用语句块的最后一个语句作为语句块的值
             _ = child[0].calc_value(env)
             res = child[1].calc_value(env)
     elif stype == 'lambda-exp':
         # <lambda-exp> ::= <(> <lambda> <(> <args> <)> <proc-body> <)>
         args = child[3].calc_value(env)
         body = child[5]
         # print 'args: ', args
         # print 'body:', body
         res = Procedure(args, body, env)
     elif stype == 'var-exps':
         if len(child) == 4:
             define(env, child[1].child[0].raw_value, child[2])
         else:
             child[0].calc_value(env)
             define(env, child[2].child[0].raw_value, child[3])
     elif stype == 'let-exp':
         # <let-exp> ::= <(> <let> <(> <var-exps> <)> <proc-body> <)
         let_env = Env.std_env(outer=env)
         child[3].calc_value(let_env)
         res = child[5].calc_value(let_env)
     elif stype == 'proc-define-exp':
         # <proc-define-exp> ::= <(> <define> <(> <symbol> <args> <)> <proc-body> <)>
         # <proc-define-exp> ::= <(> <define> <(> <symbol> <)> <proc-body> <)>
         if len(child) > 7:
             # 有参函数
             symbol = child[3].child[0].raw_value
             args = child[4].calc_value(env)
             body = child[6]
             proc = Procedure(args, body, env)
             env[symbol] = proc
         else:
             symbol = child[3].child[0].raw_value
             args = tuple()
             body = child[5]
             proc = Procedure(args, body, env)
             env[symbol] = proc
         if symbol in env.dynamic_bind:
             # 如果之前是动态绑定key, 移除
             del env.dynamic_bind[symbol]
         res = symbol
     elif stype == 'predicate':
         if child[0].calc_value(env):
             res = True
         else:
             res = False
     elif stype in ['consequent', 'alternate']:
         res = child[0].calc_value(env)
     elif stype == 'if-exp':
         # <if-exp> ::= <(> <if> <predicate> <consequent> <alternate> <)>
         if child[2].calc_value(env):
             res = child[3].calc_value(env)
         else:
             res = child[4].calc_value(env)
     elif stype == 'or-exp':
         # <or-exp> ::= <(> <or> <lexp-seq> <)>
         cnode = child[2]
         res = False
         while len(cnode.child) > 1:
             val = cnode.child[0].calc_value(env)
             if type(val) == list:
                 val = args_restore(val)
             if val:
                 res = val
                 break
             else:
                 cnode = cnode.child[1]
         else:
             val = cnode.calc_value(env)[0]
             if type(val) == list:
                 val = args_restore(val)
             if val:
                 res = val
     elif stype == 'and-exp':
         # <and-exp> ::= <(> <and> <lexp-seq> <)>
         cnode = child[2]
         res = True
         while len(cnode.child) > 1:
             val = cnode.child[0].calc_value(env)
             if type(val) == list:
                 val = args_restore(val)
             if not val:
                 res = val
                 break
             else:
                 cnode = cnode.child[1]
         else:
             val = cnode.calc_value(env)[0]
             if type(val) == list:
                 val = args_restore(val)
             if not val:
                 res = val
     if not self.static:
         self.value = res
     return res
Beispiel #4
0
 def reduce(self, grammar):
     """
     规约动作, grammar为规约用的产身世
     """
     print('利用规则' + colorful('%s -> %s' % (grammar[0], ' '.join(grammar[1])), "Green"))
Beispiel #5
0
 def shift(self, token):
     print(colorful('移近 {0} {1}'.format(token[0], token[1]), "Cyan"))
Beispiel #6
0
 def compile(self):
     """
     利用 self.grammar 编译出dfa, 并构造分析表
     :return:
     """
     self.calc_first()
     alloc = 0
     grammar = self.grammar
     dfa = DFA()
     que = Queue()
     dfa.start = DFANode(id=alloc,
                         lr_items=self.closure(("start", tuple(),
                                                tuple(grammar["start"][0]),
                                                {'$'})))
     self.idx_items = [dfa.start]
     que.put(dfa.start.lr_items)
     vis = dict()
     vis[frozen_items(dfa.start.lr_items)] = dfa.start
     while not que.empty():
         lr_items = que.get()
         # if frozen_items(lr_items) in vis:
         #     continue
         dfa_node = vis[frozen_items(lr_items)]
         # print 'u_items:'
         # print lr_items
         tmp = defaultdict(list)
         for item in lr_items:
             if item[2]:
                 u_item = (item[0], item[1] + item[2][:1],
                           item[2][1:], item[3])
                 tmp[item[2][0]].append(u_item)
                 # 可能该状态有两个以上项目可以通过 item[2][0] 转换到新项目, 而新的项目集应该是他们的合集
         for l_hand, items in tmp.iteritems():
             vitem = defaultdict(set)
             for item in items:
                 u_items = self.closure(item)
                 for u_item in u_items:
                     vitem[u_item[:-1]].update(u_item[3])
             next_items = [core + (head, )
                           for core, head in vitem.iteritems()]
             if frozen_items(next_items) not in vis:
                 que.put(next_items)
                 alloc += 1
                 dfa_node.next[l_hand] = DFANode(id=alloc,
                                                 lr_items=next_items)
                 self.idx_items.append(dfa_node.next[l_hand])        # 插入新节点
                 vis[frozen_items(next_items)] = dfa_node.next[l_hand]
             else:
                 dfa_node.next[l_hand] = vis[frozen_items(next_items)]
     # dfa.draw("LR", show_meta=["lr_items"], generate_id=False)
     self.lr_dfa = dfa
     # DFA 构造完成
     # 构造分析表
     lr_table = defaultdict(dict)
     que = Queue()
     que.put(dfa.start)
     vis = dict()
     while not que.empty():
         tmp = que.get()
         if tmp in vis:
             continue
         vis[tmp] = 1
         for item in tmp.lr_items:
             if item[2]:
                 # 移进状态
                 if item[2][0] in lr_table[tmp.id]:
                     if lr_table[tmp.id][item[2][0]]['action'] != 'shift':
                         print(colorful('移近规约冲突', 'Red'))
                         raise LRConflict()
                     elif lr_table[tmp.id][item[2][0]]['next'] != \
                             tmp.next[item[2][0]].id:
                         print(colorful('移近移近冲突', 'Red'))
                         raise LRConflict()
                 lr_table[tmp.id][item[2][0]] = \
                     dict(action="shift", next=tmp.next[item[2][0]].id)
             else:
                 # 规约状态
                 for a in item[3]:
                     if a in lr_table[tmp.id]:
                         if lr_table[tmp.id][a]['action'] != 'reduce':
                             print(colorful('移近规约冲突', 'Red'))
                             raise LRConflict()
                         elif lr_table[tmp.id][a]['grammar'] != item:
                             print(colorful('规约规约冲突', 'Red'))
                             raise LRConflict()
                     lr_table[tmp.id][a] = dict(action="reduce",
                                                grammar=item)
         for next_node in tmp.next.values():
             que.put(next_node)
     self.lr_table = lr_table
     return dfa
Beispiel #7
0
    class ParseHandler(object):

        def __init__(self):
            self.ast = None
            self.exps = []

        def shift(self, token):
            print(colorful('移近 {0} {1}'.format(token[0], token[1]), "Cyan"))

        def reduce(self, grammar):
            """
            规约动作, grammar为规约用的产身世
            """
            print('利用规则' + colorful('%s -> %s' % (grammar[0], ' '.join(grammar[1])), "Green"))

    # from util import colorful
    lex = Lex()
    lex.keyword = ['lambda', '[', ']', 'let', 'define', 'if', 'cond', 'or', 'and', '(', ')']
    lex.read_lex('regular_lex.txt')
    lex.compile(grammar_type="regular")
    print(colorful('词法编译完成...', 'Yellow'))

    parser = LRParser()
    parser.read_grammar('schepy_grammar.txt')
    parser.compile()
    print(colorful('语法编译完成...', 'Yellow'))
    parser.show_dfa()

    while True:
        parser.parse(lex.lex(raw_input(), ignore=["limit"]), ParseHandler())
Beispiel #8
0
crash_on_ipy.init()

from lex import Lex
from parser import LRParser
from util import colorful
from runtime import ParseHandler, Env

LEX = Lex()
LEX.keyword = ['lambda', '[', ']', 'let', 'define', 'if',
               'cond', 'or', 'and', '(', ')', '$T', '$F']
LEX.read_lex('regular_lex.txt')
LEX.compile(grammar_type="regular")
# lex.read_lex('regex_lex.txt')
# lex.compile()
print(colorful('词法编译完成...', 'Yellow'))
PARSER = LRParser()
PARSER.read_grammar('schepy_grammar.txt')
PARSER.compile()
print(colorful('语法编译完成...', 'Yellow'))
GLOBAL_ENV = Env.std_env()
while True:
    try:
        HANDLER = ParseHandler()
        EXP = raw_input(colorful('schepy => ', 'Cyan'))
        PARSER.parse(LEX.lex(EXP, ignore=["limit"]), HANDLER)
        print(';VALUE: ' +
              colorful(repr(HANDLER.ast.calc_value(env=GLOBAL_ENV)), "Magenta"))
    except (EOFError, KeyboardInterrupt) as e:
        CHOICE = raw_input(colorful('Do you really want to exit ([y]/n)?',
                                    "Red"))
Beispiel #9
0
 def calc_value(self, env=Env.std_env()):
     """
     在指定环境中求值, 或者对环境造成改变
     :param env: 表达式所在环境
     :return:表达式的值
     """
     if self.static and self.value:
         print(colorful('静态表达式, 直接返回值', 'Bold'))
         return self.value
     res = None
     stype, child = self.stype, self.child
     if stype == 'number':
         res = child[0].calc_value(env)
     elif stype == 'integer':
         res = int(self._value)
     elif stype == 'decimal':
         res = float(self._value)
     elif stype == 'string':
         res = self._value
     elif stype == 'bool':
         res = True if self._value == '$T' else False
     elif stype == 'symbol':
         self._value = child[0].raw_value
         res = child[0].calc_value(env)
     elif stype == 'identifier':
         res = env.find(self._value)
     elif stype == 'op':
         res = env.find(self._value)
     elif stype == 'atom' or self.stype == 'func':
         res = child[0].calc_value(env)
     elif stype == 'lexp':
         res = child[0].calc_value(env)
         if child[0].stype == 'list':
             res = [
                 res,
             ]
             res = args_restore(res)
     elif stype == 'lexp-seq':
         if len(child) > 1:
             res = (child[0].calc_value(env), ) + child[1].calc_value(env)
         else:
             res = (child[0].calc_value(env), )
         # print 'this lexp-seq:', res
     elif stype == 'list':
         if len(child) == 3:
             res = child[1].calc_value(env)
         else:
             res = tuple()
     elif stype == 's-exp':
         func = child[1].calc_value(env)
         args = child[2].calc_value(env)
         if len(child) == 3:
             res = func()
         else:
             res = func(*[args_restore(arg) for arg in args])
     elif stype == 'define-exp':
         # <define-exp> ::= <(> <define> <symbol> <lexp> <)>
         symbol = child[2].child[0].raw_value
         define(env, symbol, child[3])
         res = symbol
     elif stype == 'args':
         if child[0].stype == 'symbol':
             res = (child[0].child[0].raw_value, )
         else:
             res = child[0].calc_value(env) + (
                 child[1].child[0].raw_value, )
     elif stype == 'proc-body':
         if len(child) <= 1:
             res = child[0].calc_value(env)
         else:
             # 用语句块的最后一个语句作为语句块的值
             _ = child[0].calc_value(env)
             res = child[1].calc_value(env)
     elif stype == 'lambda-exp':
         # <lambda-exp> ::= <(> <lambda> <(> <args> <)> <proc-body> <)>
         args = child[3].calc_value(env)
         body = child[5]
         # print 'args: ', args
         # print 'body:', body
         res = Procedure(args, body, env)
     elif stype == 'var-exps':
         if len(child) == 4:
             define(env, child[1].child[0].raw_value, child[2])
         else:
             child[0].calc_value(env)
             define(env, child[2].child[0].raw_value, child[3])
     elif stype == 'let-exp':
         # <let-exp> ::= <(> <let> <(> <var-exps> <)> <proc-body> <)
         let_env = Env.std_env(outer=env)
         child[3].calc_value(let_env)
         res = child[5].calc_value(let_env)
     elif stype == 'proc-define-exp':
         # <proc-define-exp> ::= <(> <define> <(> <symbol> <args> <)> <proc-body> <)>
         # <proc-define-exp> ::= <(> <define> <(> <symbol> <)> <proc-body> <)>
         if len(child) > 7:
             # 有参函数
             symbol = child[3].child[0].raw_value
             args = child[4].calc_value(env)
             body = child[6]
             proc = Procedure(args, body, env)
             env[symbol] = proc
         else:
             symbol = child[3].child[0].raw_value
             args = tuple()
             body = child[5]
             proc = Procedure(args, body, env)
             env[symbol] = proc
         if symbol in env.dynamic_bind:
             # 如果之前是动态绑定key, 移除
             del env.dynamic_bind[symbol]
         res = symbol
     elif stype == 'predicate':
         if child[0].calc_value(env):
             res = True
         else:
             res = False
     elif stype in ['consequent', 'alternate']:
         res = child[0].calc_value(env)
     elif stype == 'if-exp':
         # <if-exp> ::= <(> <if> <predicate> <consequent> <alternate> <)>
         if child[2].calc_value(env):
             res = child[3].calc_value(env)
         else:
             res = child[4].calc_value(env)
     elif stype == 'or-exp':
         # <or-exp> ::= <(> <or> <lexp-seq> <)>
         cnode = child[2]
         res = False
         while len(cnode.child) > 1:
             val = cnode.child[0].calc_value(env)
             if type(val) == list:
                 val = args_restore(val)
             if val:
                 res = val
                 break
             else:
                 cnode = cnode.child[1]
         else:
             val = cnode.calc_value(env)[0]
             if type(val) == list:
                 val = args_restore(val)
             if val:
                 res = val
     elif stype == 'and-exp':
         # <and-exp> ::= <(> <and> <lexp-seq> <)>
         cnode = child[2]
         res = True
         while len(cnode.child) > 1:
             val = cnode.child[0].calc_value(env)
             if type(val) == list:
                 val = args_restore(val)
             if not val:
                 res = val
                 break
             else:
                 cnode = cnode.child[1]
         else:
             val = cnode.calc_value(env)[0]
             if type(val) == list:
                 val = args_restore(val)
             if not val:
                 res = val
     if not self.static:
         self.value = res
     return res