@@ -54,10 +54,14 @@ class Base:
5454# Lexer
5555####################################################################################################
5656class Lexer (Base ):
57- def __init__ (self , debug = 0 , optimize = 0 ):
57+ def __init__ (self , debug = 0 , optimize = 0 , compatibility_mode = False , header_limit = 1024 ):
5858 self .lexer = lex .lex (module = self , debug = debug , debuglog = logger , optimize = optimize ,
5959 errorlog = logger )
6060 self .entity_keywords = []
61+ self .compatibility_mode = compatibility_mode
62+ self .header_limit = header_limit
63+
64+ states = (('compatibility' , 'inclusive' ),)
6165
6266 def __getattr__ (self , name ):
6367 if name == 'lineno' :
@@ -68,8 +72,17 @@ def __getattr__(self, name):
6872 raise AttributeError
6973
7074 def input (self , s ):
71- self .lexer .input (s )
72-
75+ startidx = s .find ('ISO-10303-21;' , 0 , self .header_limit )
76+ if startidx == - 1 :
77+ sys .exit ('Aborting... ISO-10303-21; header not found' )
78+ self .lexer .input (s [startidx :])
79+ self .lexer .lineno += s [0 :startidx ].count ('\n ' )
80+
81+ if self .compatibility_mode :
82+ self .lexer .begin ('compatibility' )
83+ else :
84+ self .lexer .begin ('INITIAL' )
85+
7386 def token (self ):
7487 try :
7588 return next (self .lexer )
@@ -80,29 +93,39 @@ def register_entities(self, entities):
8093 self .entity_keywords .extend (entities )
8194
8295 # Comment (ignored)
83- def t_COMMENT (self , t ):
96+ def t_ANY_COMMENT (self , t ):
8497 r'/\*(.|\n)*?\*/'
8598 t .lexer .lineno += t .value .count ('\n ' )
8699
87- def t_PART21_START (self , t ):
100+ def t_ANY_PART21_START (self , t ):
88101 r'ISO-10303-21;'
89102 return t
90103
91- def t_PART21_END (self , t ):
104+ def t_ANY_PART21_END (self , t ):
92105 r'END-ISO-10303-21;'
93106 return t
94107
95- def t_HEADER_SEC (self , t ):
108+ def t_ANY_HEADER_SEC (self , t ):
96109 r'HEADER;'
97110 return t
98111
99- def t_ENDSEC (self , t ):
112+ def t_ANY_ENDSEC (self , t ):
100113 r'ENDSEC;'
101114 return t
102115
103116 # Keywords
104- # TODO: provide a hook for entity validation i.e. t.value in list_of_entities_for_AP###
105- def t_STANDARD_KEYWORD (self , t ):
117+ def t_compatibility_STANDARD_KEYWORD (self , t ):
118+ r'(?:!|)[A-Z_][0-9A-Za-z_]*'
119+ t .value = t .value .upper ()
120+ if t .value == 'DATA' :
121+ t .type = 'DATA_SEC'
122+ elif t .value .startswith ('!' ):
123+ t .type = 'USER_DEFINED_KEYWORD'
124+ elif t .value in self .entity_keywords :
125+ t .type = t .value
126+ return t
127+
128+ def t_ANY_STANDARD_KEYWORD (self , t ):
106129 r'(?:!|)[A-Z_][0-9A-Z_]*'
107130 if t .value == 'DATA' :
108131 t .type = 'DATA_SEC'
@@ -112,24 +135,22 @@ def t_STANDARD_KEYWORD(self, t):
112135 t .type = t .value
113136 return t
114137
115- def t_newline (self , t ):
138+ def t_ANY_newline (self , t ):
116139 r'\n+'
117140 t .lexer .lineno += len (t .value )
118141
119142 # Simple Data Types
120- t_REAL = r'[+-]*[0-9][0-9]*\.[0-9]*(?:E[+-]*[0-9][0-9]*)?'
121- t_INTEGER = r'[+-]*[0-9][0-9]*'
122- t_STRING = r"'(?:[][!\"*$%&.#+,\-()?/:;<=>@{}|^`~0-9a-zA-Z_\\ ]|'')*'"
123- t_BINARY = r'"[0-3][0-9A-F]*"'
124- t_ENTITY_INSTANCE_NAME = r'\#[0-9]+'
125- t_ENUMERATION = r'\.[A-Z_][A-Z0-9_]*\.'
143+ t_ANY_REAL = r'[+-]*[0-9][0-9]*\.[0-9]*(?:E[+-]*[0-9][0-9]*)?'
144+ t_ANY_INTEGER = r'[+-]*[0-9][0-9]*'
145+ t_ANY_STRING = r"'(?:[][!\"*$%&.#+,\-()?/:;<=>@{}|^`~0-9a-zA-Z_\\ ]|'')*'"
146+ t_ANY_BINARY = r'"[0-3][0-9A-F]*"'
147+ t_ANY_ENTITY_INSTANCE_NAME = r'\#[0-9]+'
148+ t_ANY_ENUMERATION = r'\.[A-Z_][A-Z0-9_]*\.'
126149
127150 # Punctuation
128151 literals = '()=;,*$'
129152
130- # TODO: is it okay to ignore \n?
131- t_ignore = ' \t '
132-
153+ t_ANY_ignore = ' \t '
133154
134155
135156####################################################################################################
@@ -324,17 +345,34 @@ def p_empty(self, p):
324345 """empty :"""
325346 pass
326347
348+ def test_debug ():
349+ logging .basicConfig ()
350+ logger .setLevel (logging .DEBUG )
351+
352+ s = open ('io1-tu-203.stp' , 'r' ).read ()
353+ parser = Parser ()
354+
355+ try :
356+ r = parser .parse (s , debug = 1 )
357+ except SystemExit :
358+ pass
359+
360+ return (parser , r )
327361
328362def test ():
329363 logging .basicConfig ()
330364 logger .setLevel (logging .ERROR )
331365
332366 s = open ('io1-tu-203.stp' , 'r' ).read ()
333- parser = Parser (debug = 1 )
367+ parser = Parser ()
368+
369+ try :
370+ r = parser .parse (s )
371+ except SystemExit :
372+ pass
373+
374+ return (parser , r )
334375
335- r = parser .parse (s , debug = 1 )
336- #r = parser.parse(s)
337- return r
338376
339377if __name__ == '__main__' :
340378 test ()
0 commit comments