3434# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3535# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3636
37+ import sys
3738import ply .lex as lex
3839import ply .yacc as yacc
3940
@@ -68,7 +69,7 @@ def register_entities(self, entities):
6869 # Comment (ignored)
6970 def t_COMMENT (self , t ):
7071 r'/\*(.|\n)*?\*/'
71- pass
72+ t . lexer . lineno += t . value . count ( ' \n ' )
7273
7374 def t_PART21_START (self , t ):
7475 r'ISO-10303-21;'
@@ -98,6 +99,10 @@ def t_STANDARD_KEYWORD(self, t):
9899 t .type = t .value
99100 return t
100101
102+ def t_newline (self , t ):
103+ r'\n+'
104+ t .lexer .lineno += len (t .value )
105+
101106 # Simple Data Types
102107 t_REAL = r'[+-]*[0-9][0-9]*\.[0-9]*(?:E[+-]*[0-9][0-9]*)?'
103108 t_INTEGER = r'[+-]*[0-9][0-9]*'
@@ -108,18 +113,9 @@ def t_STANDARD_KEYWORD(self, t):
108113
109114 # Punctuation
110115 literals = '()=;,*$'
111- #t_LBRACE = r'\('
112- #t_RBRACE = r'\)'
113- #t_EQ = r'='
114- #t_END_STMT = r';'
115- #t_COMMA = r','
116-
117- # Placeholders
118- #t_OMITTED_PARAMETER = r'\*'
119- #t_EMPTYDEF = r'\$'
120116
121117 # TODO: is it okay to ignore \n?
122- t_ignore = ' \t \n '
118+ t_ignore = ' \t '
123119
124120####################################################################################################
125121# Simple Model
@@ -171,9 +167,10 @@ def __init__(self, lexer=None):
171167 self .lexer = lexer
172168 self .parser = yacc .yacc (module = self )
173169
174- def parse (self , p21_data , debug = None ):
170+ def parse (self , p21_data , ** kwargs ):
175171 self .lexer .input (p21_data )
176- result = self .parser .parse (lexer = self .lexer , debug = debug )
172+ self .refs = {}
173+ result = self .parser .parse (lexer = self .lexer , ** kwargs )
177174 return result
178175
179176 def p_exchange_file (self , p ):
@@ -194,12 +191,21 @@ def p_header_entity(self, p):
194191 """header_entity : keyword '(' parameter_list ')' ';'"""
195192 p [0 ] = HeaderEntity (p [1 ], p [3 ])
196193
194+ def p_check_entity_instance_name (self , p ):
195+ """check_entity_instance_name : ENTITY_INSTANCE_NAME"""
196+ if p [1 ] in self .refs :
197+ print ('ERROR: Line {0}, duplicate entity instance name: {1}' .format (p .lineno (1 ), p [1 ]), file = sys .stderr )
198+ raise SyntaxError
199+ else :
200+ self .refs [p [1 ]] = None
201+ p [0 ] = p [1 ]
202+
197203 def p_simple_entity_instance (self , p ):
198- """simple_entity_instance : ENTITY_INSTANCE_NAME '=' simple_record ';'"""
204+ """simple_entity_instance : check_entity_instance_name '=' simple_record ';'"""
199205 p [0 ] = SimpleEntity (p [1 ], * p [3 ])
200206
201207 def p_complex_entity_instance (self , p ):
202- """complex_entity_instance : ENTITY_INSTANCE_NAME '=' subsuper_record ';'"""
208+ """complex_entity_instance : check_entity_instance_name '=' subsuper_record ';'"""
203209 p [0 ] = ComplexEntity (p [1 ], p [3 ])
204210
205211 def p_subsuper_record (self , p ):
@@ -279,6 +285,7 @@ def p_entity_instance(self, p):
279285 | complex_entity_instance"""
280286 p [0 ] = p [1 ]
281287
288+
282289 def p_simple_record_empty (self , p ):
283290 """simple_record : keyword '(' ')'"""
284291 p [0 ] = (p [1 ], [])
@@ -292,16 +299,24 @@ def p_simple_record_list(self, p):
292299 | simple_record"""
293300 try : p [0 ] = p [1 ] + [p [2 ],]
294301 except IndexError : p [0 ] = [p [1 ],]
295-
302+
296303 def p_empty (self , p ):
297304 """empty :"""
298305 pass
299306
307+ def p_error (self , p ):
308+ raise SyntaxError
309+
300310
301311def test ():
312+ import logging
313+ logger = logging .getLogger ()
314+ logger .setLevel (logging .DEBUG )
315+
302316 s = open ('io1-tu-203.stp' , 'r' ).read ()
303317 parser = Parser ()
304318
319+ #r = parser.parse(s, debug=logger)
305320 r = parser .parse (s )
306321 return r
307322
0 commit comments