Sapan Bhatia | 3cfdf63 | 2017-06-08 05:14:03 +0200 | [diff] [blame] | 1 | import plyxproto.model as m |
Sapan Bhatia | db183c2 | 2017-06-23 02:47:42 -0700 | [diff] [blame] | 2 | from plyxproto.helpers import Visitor |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 3 | import pdb |
| 4 | import argparse |
Sapan Bhatia | 3cfdf63 | 2017-06-08 05:14:03 +0200 | [diff] [blame] | 5 | import plyxproto.parser as plyxproto |
Sapan Bhatia | ea6ff75 | 2017-07-14 01:52:18 -0400 | [diff] [blame] | 6 | from plyxproto.logicparser import FOLParser, FOLLexer |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 7 | import traceback |
| 8 | import sys |
| 9 | import jinja2 |
| 10 | import os |
Sapan Bhatia | ea6ff75 | 2017-07-14 01:52:18 -0400 | [diff] [blame] | 11 | import ply.lex as lex |
| 12 | import ply.yacc as yacc |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 13 | |
| 14 | class Stack(list): |
| 15 | def push(self,x): |
| 16 | self.append(x) |
| 17 | |
Sapan Bhatia | 3cfdf63 | 2017-06-08 05:14:03 +0200 | [diff] [blame] | 18 | def str_to_dict(s): |
| 19 | lst = s.rsplit('.',1) |
| 20 | name = lst[-1] |
| 21 | |
| 22 | if len(lst)==2: |
| 23 | package = lst[0] |
| 24 | else: |
| 25 | package = '' |
| 26 | |
| 27 | return {'name': name, 'package': package, 'fqn': s} |
| 28 | |
Sapan Bhatia | ea6ff75 | 2017-07-14 01:52:18 -0400 | [diff] [blame] | 29 | |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 30 | def replace_link(obj): |
| 31 | try: |
| 32 | link = obj.link |
| 33 | try: |
| 34 | through = link['through'] |
| 35 | except KeyError: |
| 36 | through = None |
| 37 | |
| 38 | try: |
| 39 | through_str = through[1:-1] |
| 40 | except TypeError: |
| 41 | through_str = None |
| 42 | |
Sapan Bhatia | 3cfdf63 | 2017-06-08 05:14:03 +0200 | [diff] [blame] | 43 | if through_str: |
| 44 | through_dict = str_to_dict(through_str) |
| 45 | else: |
| 46 | through_dict = {} |
| 47 | |
| 48 | model_dict = str_to_dict(link['model'][1:-1]) |
| 49 | |
| 50 | ls = m.LinkSpec(obj, m.LinkDefinition(link['link'][1:-1],obj.name,model_dict,link['port'][1:-1],through_dict)) |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 51 | return ls |
| 52 | except: |
| 53 | return obj |
| 54 | |
Sapan Bhatia | db183c2 | 2017-06-23 02:47:42 -0700 | [diff] [blame] | 55 | class Proto2XProto(Visitor): |
Sapan Bhatia | ea6ff75 | 2017-07-14 01:52:18 -0400 | [diff] [blame] | 56 | fol_lexer = lex.lex(module=FOLLexer()) |
| 57 | fol_parser = yacc.yacc(module=FOLParser(), start='goal') |
| 58 | |
Matteo Scandolo | 67654fa | 2017-06-09 09:33:17 -0700 | [diff] [blame] | 59 | def __init__(self): |
| 60 | super(Proto2XProto, self).__init__() |
| 61 | |
| 62 | self.stack = Stack() |
| 63 | self.count_stack = Stack() |
| 64 | self.content="" |
| 65 | self.offset=0 |
| 66 | self.statementsChanged=0 |
| 67 | self.message_options = {} |
| 68 | self.options = {} |
| 69 | self.current_message_name = None |
| 70 | |
| 71 | self.xproto_message_options = ['bases'] |
| 72 | self.xproto_field_options = ['model'] |
| 73 | self.verbose = 0 |
| 74 | self.first_field = True |
| 75 | self.first_method = True |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 76 | |
Sapan Bhatia | ea6ff75 | 2017-07-14 01:52:18 -0400 | [diff] [blame] | 77 | def replace_policy(self, obj): |
| 78 | if isinstance(obj, m.OptionStatement): |
| 79 | rhs = obj.value.value.pval |
| 80 | if rhs.startswith('"') and rhs.endswith('"'): |
| 81 | rhs = rhs[1:-1] |
| 82 | |
| 83 | if rhs.startswith('policy:'): |
| 84 | str = rhs.split(':')[1] |
| 85 | val = self.fol_parser.parse(str, lexer = self.fol_lexer) |
| 86 | |
| 87 | return m.PolicyDefinition(obj.name, val) |
| 88 | |
| 89 | return obj |
| 90 | |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 91 | def proto_to_xproto_field(self, obj): |
| 92 | try: |
| 93 | opts = {} |
| 94 | for fd in obj.fieldDirective: |
| 95 | k = fd.pval.name.value.pval |
| 96 | v = fd.pval.value.value.pval |
| 97 | opts[k]=v |
| 98 | |
| 99 | if ('model' in opts and 'link' in opts and 'port' in opts): |
| 100 | obj.link = opts |
| 101 | pass |
| 102 | except KeyError: |
| 103 | raise |
| 104 | |
| 105 | def proto_to_xproto_message(self, obj): |
| 106 | try: |
Sapan Bhatia | ea6ff75 | 2017-07-14 01:52:18 -0400 | [diff] [blame] | 107 | try: |
| 108 | bases = self.message_options['bases'].split(',') |
| 109 | except KeyError: |
| 110 | bases = [] |
| 111 | |
Sapan Bhatia | 3cfdf63 | 2017-06-08 05:14:03 +0200 | [diff] [blame] | 112 | bases = map(lambda x:str_to_dict(x[1:-1]), bases) |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 113 | obj.bases = bases |
| 114 | except KeyError: |
| 115 | raise |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 116 | |
| 117 | def map_field(self, obj, s): |
| 118 | if 'model' in s: |
| 119 | link = m.LinkDefinition('onetoone','src','name','dst', obj.linespan, obj.lexspan, obj.p) |
| 120 | lspec = m.LinkSpec(link, obj) |
| 121 | else: |
| 122 | lspec = obj |
| 123 | return lspec |
| 124 | |
| 125 | |
| 126 | def get_stack(self): |
Matteo Scandolo | 67654fa | 2017-06-09 09:33:17 -0700 | [diff] [blame] | 127 | return self.stack |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 128 | |
| 129 | def visit_PackageStatement(self, obj): |
| 130 | '''Ignore''' |
| 131 | return True |
| 132 | |
| 133 | def visit_ImportStatement(self, obj): |
| 134 | '''Ignore''' |
| 135 | return True |
| 136 | |
| 137 | def visit_OptionStatement(self, obj): |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 138 | if (self.current_message_name): |
| 139 | k = obj.name.value.pval |
| 140 | self.message_options[k] = obj.value.value.pval |
| 141 | if (k in self.xproto_message_options): |
| 142 | obj.mark_for_deletion = True |
| 143 | else: |
| 144 | self.options[obj.name.value.pval] = obj.value.value.pval |
| 145 | |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 146 | return True |
| 147 | |
| 148 | def visit_LU(self, obj): |
| 149 | return True |
| 150 | |
| 151 | def visit_default(self, obj): |
| 152 | return True |
| 153 | |
| 154 | def visit_FieldDirective(self, obj): |
| 155 | return True |
| 156 | |
| 157 | def visit_FieldDirective_post(self, obj): |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 158 | return True |
| 159 | |
| 160 | def visit_FieldType(self, obj): |
| 161 | return True |
| 162 | |
| 163 | def visit_LinkDefinition(self, obj): |
| 164 | return True |
| 165 | |
| 166 | def visit_FieldDefinition(self, obj): |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 167 | return True |
| 168 | |
| 169 | def visit_FieldDefinition_post(self, obj): |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 170 | self.proto_to_xproto_field(obj) |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 171 | return True |
| 172 | |
| 173 | def visit_EnumFieldDefinition(self, obj): |
| 174 | return True |
| 175 | |
| 176 | def visit_EnumDefinition(self, obj): |
| 177 | return True |
| 178 | |
| 179 | def visit_MessageDefinition(self, obj): |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 180 | self.current_message_name = obj.name.value.pval |
| 181 | self.message_options = {} |
| 182 | |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 183 | return True |
| 184 | |
| 185 | def visit_MessageDefinition_post(self, obj): |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 186 | self.proto_to_xproto_message(obj) |
| 187 | obj.body = filter(lambda x:not hasattr(x, 'mark_for_deletion'), obj.body) |
| 188 | obj.body = map(replace_link, obj.body) |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 189 | |
Sapan Bhatia | ae9645c | 2017-05-05 15:35:54 +0200 | [diff] [blame] | 190 | self.current_message_name = None |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 191 | return True |
| 192 | |
| 193 | def visit_MessageExtension(self, obj): |
| 194 | return True |
| 195 | |
| 196 | def visit_MethodDefinition(self, obj): |
| 197 | return True |
| 198 | |
| 199 | def visit_ServiceDefinition(self, obj): |
| 200 | return True |
| 201 | |
| 202 | def visit_ExtensionsDirective(self, obj): |
| 203 | return True |
| 204 | |
| 205 | def visit_Literal(self, obj): |
| 206 | return True |
| 207 | |
| 208 | def visit_Name(self, obj): |
| 209 | return True |
| 210 | |
| 211 | def visit_DotName(self, obj): |
| 212 | return True |
| 213 | |
| 214 | def visit_Proto(self, obj): |
| 215 | self.count_stack.push(len(obj.body)) |
| 216 | return True |
| 217 | |
| 218 | def visit_Proto_post(self, obj): |
Sapan Bhatia | ea6ff75 | 2017-07-14 01:52:18 -0400 | [diff] [blame] | 219 | |
| 220 | obj.body = [self.replace_policy(o) for o in obj.body] |
Sapan Bhatia | ff1b8fa | 2017-04-10 19:44:38 -0700 | [diff] [blame] | 221 | return True |
| 222 | |
| 223 | def visit_LinkSpec(self, obj): |
| 224 | return False |