--- esG.py- 2016-09-05 00:00:00.000000000 +0900 +++ esG.py 2016-09-06 00:00:00.000000000 +0900 @@ -114,9 +114,98 @@ def name_bra(lst): return [ f( *lst[:pn] ) ] + name_bra(lst[pn:]) return [ lst[0] ] + name_bra(lst[1:]) +def ops_idx(ops, term, op): + i = next( ( i for (i, (term_, bind, lst)) in enumerate(ops) if term_ == term and op in lst ), None ) + if i is None: + err_exit("not found term={} op='{}' in ops".format(term, op)) + return i + +def tree_op(lst, ops): + if len(lst) == 0: + return lst + e = lst[0] + (k, v) = e[:2] + + if k == 'br_s': + e = [ k, v, tree_op( e[2], ops ) ] + elif k in [ 'fcall', 'arr' ]: + e = [ k, v, tree_op( [ e[2] ], ops )[0] ] + elif k == 'fdef': + e = [ k, v, e[2], e[3], tree_op( [ e[4] ], ops )[0] ] + + if k == 'op': + r = tree_op( lst[1:], ops ) + if len(r) == 0: + err_exit("not found rignt term op='{}'".format(v)) + (k2, v2) = r[0][:2] + if k2 == 'op': + i1 = ops_idx(ops, 1, v) + i2 = ops_idx( ops, len( r[0][2:] ), v2 ) + if i1 < i2 or (i1 == i2 and ops[i1][1] == '>'): + return [ [ k2, v2, [ k, v, r[0][2] ] ] + r[0][3:] ] + r[1:] + return [ [ k, v, r[0] ] ] + r[1:] + + if k in [ 'num', 'name', 'arr', 'fcall', 'br_s' ] and len( lst[1:] ) > 0: + e1 = lst[1] + (k1, v1) = e1[:2] + if k1 == 'op': + r = tree_op( lst[2:], ops ) + if len(r) == 0: + err_exit("not found right term op='{}'".format(v1)) + (k2, v2) = r[0][:2] + if k2 == 'op': + i1 = ops_idx(ops, 2, v1) + i2 = ops_idx( ops, len( r[0][2:] ), v2 ) + if i1 < i2 or (i1 == i2 and ops[i1][1] == '>'): + return [ [ k2, v2, [ k1, v1, e, r[0][2] ], r[0][3] ] ] + r[1:] + return [ [ k1, v1, e, r[0] ] ] + r[1:] + + return [ e ] + tree_op( lst[1:], ops ) + def es_split(s): s = s.replace('@', '@ ') + ''' + Operator Associativity + -------- ------------- + () [] -> . left to right + ! ~ ++ -- - (type) * & sizeof right to left + * / % left to right + + - left to right + << >> left to right + < <= > >= left to right + == != left to right + & left to right + ^ left to right + | left to right + && left to right + || left to right + ?: right to left + = += -= etc. right to left + , left to right + ''' + + ops = [ # term, bind, lst + [ 2, '>', [ '->', '.' ] ], + [ 1, '<', [ '!', '~', '++', '--', '-', '*', '&' ] ], # dup -,*,& + [ 2, '>', [ '*', '/', '%' ] ], # dup * + [ 2, '>', [ '+', '-' ] ], # dup - + [ 2, '>', [ '<<', '>>' ] ], + [ 2, '>', [ '<', '<=', '>', '>=' ] ], + [ 2, '>', [ '==', '!=' ] ], + [ 2, '>', [ '&' ] ], # dup & + [ 2, '>', [ '^' ] ], + [ 2, '>', [ '|' ] ], + [ 2, '>', [ '&&' ] ], + [ 2, '>', [ '||' ] ], + [ 3, '<', [ '?', ':' ] ], + [ 2, '<', [ '=', '+=', '-=', '*=', '/=', '%=', '&=', '|=', '^=', '~=', '>>=', '<<=' ] ], + # [ 2, '>', [ ',' ] ], # ... + ] + + f = lambda t, (term, bind, lst): t + [ v for v in lst if v not in t ] + ops_flat = reduce(f, ops, []) + kdic = { 'cmt_s' : [ '/*', '//' ], 'cmt_e' : [ '*/' ], @@ -124,7 +213,7 @@ def es_split(s): 'esc' : { '\\n':'\n', '\\t':'\t', '\\"':'"', "\\'":"'", '\\\\':'\\' }, 'br_s' : [ '(', '[', '{' ], 'br_e' : [ ')', ']', '}' ], - 'op' : [ '+', '-', '*', '=' ], + 'op' : ops_flat, 'type' : [ 'int', 'char', 'void' ], 'kwd' : [ 'return' ], 'spc' : [ ' ', '\t', '\n' ], @@ -165,8 +254,14 @@ def es_split(s): lst = name_bra(lst) + lst = tree_op(lst, ops) + return lst +def err_exit(msg, rcode=1): + print('Err {}'.format(msg)) + sys.exit(rcode) + if __name__ == "__main__": rcode = 0 if len(sys.argv) <= 1: