KiCad PCB EDA Suite
DRC_RULES_PARSER Class Reference

#include <drc_rule_parser.h>

Inheritance diagram for DRC_RULES_PARSER:

Public Member Functions

 DRC_RULES_PARSER (const wxString &aSource, const wxString &aSourceDescr)
 
 DRC_RULES_PARSER (FILE *aFile, const wxString &aFilename)
 
void Parse (std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
 

Private Member Functions

std::shared_ptr< DRC_RULEparseDRC_RULE ()
 
void parseConstraint (DRC_RULE *aRule)
 
void parseValueWithUnits (const wxString &aExpr, int &aResult, bool aUnitless=false)
 
LSET parseLayer ()
 
SEVERITY parseSeverity ()
 
void parseUnknown ()
 
void reportError (const wxString &aMessage)
 
void reportDeprecation (const wxString &oldToken, const wxString newToken)
 

Private Attributes

int m_requiredVersion
 
bool m_tooRecent
 
REPORTERm_reporter
 

Detailed Description

Definition at line 40 of file drc_rule_parser.h.

Constructor & Destructor Documentation

◆ DRC_RULES_PARSER() [1/2]

DRC_RULES_PARSER::DRC_RULES_PARSER ( const wxString &  aSource,
const wxString &  aSourceDescr 
)

Definition at line 36 of file drc_rule_parser.cpp.

36 :
37 DRC_RULES_LEXER( aSource.ToStdString(), aSourceDescr ),
39 m_tooRecent( false ),
40 m_reporter( nullptr )
41{
42}
REPORTER * m_reporter

◆ DRC_RULES_PARSER() [2/2]

DRC_RULES_PARSER::DRC_RULES_PARSER ( FILE *  aFile,
const wxString &  aFilename 
)

Definition at line 45 of file drc_rule_parser.cpp.

45 :
46 DRC_RULES_LEXER( aFile, aFilename ),
48 m_tooRecent( false ),
49 m_reporter( nullptr )
50{
51}

Member Function Documentation

◆ Parse()

void DRC_RULES_PARSER::Parse ( std::vector< std::shared_ptr< DRC_RULE > > &  aRules,
REPORTER aReporter 
)

Definition at line 107 of file drc_rule_parser.cpp.

108{
109 bool haveVersion = false;
110 wxString msg;
111
112 m_reporter = aReporter;
113
114 for( T token = NextTok(); token != T_EOF; token = NextTok() )
115 {
116 if( token != T_LEFT )
117 reportError( _( "Missing '('." ) );
118
119 token = NextTok();
120
121 if( !haveVersion && token != T_version )
122 {
123 reportError( _( "Missing version statement." ) );
124 haveVersion = true; // don't keep on reporting it
125 }
126
127 switch( token )
128 {
129 case T_version:
130 haveVersion = true;
131 token = NextTok();
132
133 if( (int) token == DSN_RIGHT )
134 {
135 reportError( _( "Missing version number." ) );
136 break;
137 }
138
139 if( (int) token == DSN_NUMBER )
140 {
141 m_requiredVersion = (int)strtol( CurText(), nullptr, 10 );
143 token = NextTok();
144 }
145 else
146 {
147 msg.Printf( _( "Unrecognized item '%s'.| Expected version number." ),
148 FromUTF8() );
149 reportError( msg );
150 }
151
152 if( (int) token != DSN_RIGHT )
153 {
154 msg.Printf( _( "Unrecognized item '%s'." ),
155 FromUTF8() );
156 reportError( msg );
157 parseUnknown();
158 }
159
160 break;
161
162 case T_rule:
163 aRules.emplace_back( parseDRC_RULE() );
164 break;
165
166 case T_EOF:
167 reportError( _( "Incomplete statement." ) );
168 break;
169
170 default:
171 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
172 wxT( "rule or version" ) );
173 reportError( msg );
174 parseUnknown();
175 }
176 }
177
178 if( m_reporter && !m_reporter->HasMessage() )
179 m_reporter->Report( _( "No errors found." ), RPT_SEVERITY_INFO );
180
181 m_reporter = nullptr;
182}
std::shared_ptr< DRC_RULE > parseDRC_RULE()
void reportError(const wxString &aMessage)
virtual bool HasMessage() const =0
Returns true if the reporter client is non-empty.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
#define DRC_RULE_FILE_VERSION
@ DSN_RIGHT
Definition: dsnlexer.h:66
@ DSN_NUMBER
Definition: dsnlexer.h:65
#define _(s)
@ RPT_SEVERITY_INFO

References _, DRC_RULE_FILE_VERSION, DSN_NUMBER, DSN_RIGHT, REPORTER::HasMessage(), m_reporter, m_requiredVersion, m_tooRecent, parseDRC_RULE(), parseUnknown(), REPORTER::Report(), reportError(), and RPT_SEVERITY_INFO.

Referenced by DRC_ENGINE::loadRules(), and PANEL_SETUP_RULES::OnCompile().

◆ parseConstraint()

void DRC_RULES_PARSER::parseConstraint ( DRC_RULE aRule)
private

Definition at line 267 of file drc_rule_parser.cpp.

268{
270 int value;
271 wxString msg;
272
273 T token = NextTok();
274
275 if( token == T_mechanical_clearance )
276 {
277 reportDeprecation( wxT( "mechanical_clearance" ), wxT( "physical_clearance" ) );
278 token = T_physical_clearance;
279 }
280 else if( token == T_mechanical_hole_clearance )
281 {
282 reportDeprecation( wxT( "mechanical_hole_clearance" ), wxT( "physical_hole_clearance" ) );
283 token = T_physical_hole_clearance;
284 }
285 else if( token == T_hole )
286 {
287 reportDeprecation( wxT( "hole" ), wxT( "hole_size" ) );
288 token = T_hole_size;
289 }
290 else if( (int) token == DSN_RIGHT || token == T_EOF )
291 {
292 msg.Printf( _( "Missing constraint type.| Expected %s." ),
293 wxT( "assertion, clearance, hole_clearance, edge_clearance, "
294 "physical_clearance, physical_hole_clearance, courtyard_clearance, "
295 "silk_clearance, hole_size, hole_to_hole, track_width, annular_width, "
296 "via_diameter, disallow, zone_connection, thermal_relief_gap, "
297 "thermal_spoke_width, min_resolved_spokes, length, skew, via_count, "
298 "diff_pair_gap or diff_pair_uncoupled" ) );
299 reportError( msg );
300 return;
301 }
302
303 switch( token )
304 {
305 case T_assertion: c.m_Type = ASSERTION_CONSTRAINT; break;
306 case T_clearance: c.m_Type = CLEARANCE_CONSTRAINT; break;
307 case T_hole_clearance: c.m_Type = HOLE_CLEARANCE_CONSTRAINT; break;
308 case T_edge_clearance: c.m_Type = EDGE_CLEARANCE_CONSTRAINT; break;
309 case T_hole_size: c.m_Type = HOLE_SIZE_CONSTRAINT; break;
310 case T_hole_to_hole: c.m_Type = HOLE_TO_HOLE_CONSTRAINT; break;
311 case T_courtyard_clearance: c.m_Type = COURTYARD_CLEARANCE_CONSTRAINT; break;
312 case T_silk_clearance: c.m_Type = SILK_CLEARANCE_CONSTRAINT; break;
313 case T_text_height: c.m_Type = TEXT_HEIGHT_CONSTRAINT; break;
314 case T_text_thickness: c.m_Type = TEXT_THICKNESS_CONSTRAINT; break;
315 case T_track_width: c.m_Type = TRACK_WIDTH_CONSTRAINT; break;
316 case T_connection_width: c.m_Type = CONNECTION_WIDTH_CONSTRAINT; break;
317 case T_annular_width: c.m_Type = ANNULAR_WIDTH_CONSTRAINT; break;
318 case T_via_diameter: c.m_Type = VIA_DIAMETER_CONSTRAINT; break;
319 case T_zone_connection: c.m_Type = ZONE_CONNECTION_CONSTRAINT; break;
320 case T_thermal_relief_gap: c.m_Type = THERMAL_RELIEF_GAP_CONSTRAINT; break;
321 case T_thermal_spoke_width: c.m_Type = THERMAL_SPOKE_WIDTH_CONSTRAINT; break;
322 case T_min_resolved_spokes: c.m_Type = MIN_RESOLVED_SPOKES_CONSTRAINT; break;
323 case T_disallow: c.m_Type = DISALLOW_CONSTRAINT; break;
324 case T_length: c.m_Type = LENGTH_CONSTRAINT; break;
325 case T_skew: c.m_Type = SKEW_CONSTRAINT; break;
326 case T_via_count: c.m_Type = VIA_COUNT_CONSTRAINT; break;
327 case T_diff_pair_gap: c.m_Type = DIFF_PAIR_GAP_CONSTRAINT; break;
328 case T_diff_pair_uncoupled: c.m_Type = DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT; break;
329 case T_physical_clearance: c.m_Type = PHYSICAL_CLEARANCE_CONSTRAINT; break;
330 case T_physical_hole_clearance: c.m_Type = PHYSICAL_HOLE_CLEARANCE_CONSTRAINT; break;
331 default:
332 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
333 wxT( "assertion, clearance, hole_clearance, edge_clearance, "
334 "physical_clearance, physical_hole_clearance, courtyard_clearance, "
335 "silk_clearance, hole_size, hole_to_hole, track_width, annular_width, "
336 "disallow, zone_connection, thermal_relief_gap, thermal_spoke_width, "
337 "min_resolved_spokes, length, skew, via_count, via_diameter, "
338 "diff_pair_gap or diff_pair_uncoupled" ) );
339 reportError( msg );
340 }
341
342 if( aRule->FindConstraint( c.m_Type ) )
343 {
344 msg.Printf( _( "Rule already has a '%s' constraint." ), FromUTF8() );
345 reportError( msg );
346 }
347
348 bool unitless = c.m_Type == VIA_COUNT_CONSTRAINT
350
351 if( c.m_Type == DISALLOW_CONSTRAINT )
352 {
353 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
354 {
355 if( (int) token == DSN_STRING )
356 token = GetCurStrAsToken();
357
358 switch( token )
359 {
360 case T_track: c.m_DisallowFlags |= DRC_DISALLOW_TRACKS; break;
361 case T_via: c.m_DisallowFlags |= DRC_DISALLOW_VIAS; break;
362 case T_micro_via: c.m_DisallowFlags |= DRC_DISALLOW_MICRO_VIAS; break;
363 case T_buried_via: c.m_DisallowFlags |= DRC_DISALLOW_BB_VIAS; break;
364 case T_pad: c.m_DisallowFlags |= DRC_DISALLOW_PADS; break;
365 case T_zone: c.m_DisallowFlags |= DRC_DISALLOW_ZONES; break;
366 case T_text: c.m_DisallowFlags |= DRC_DISALLOW_TEXTS; break;
367 case T_graphic: c.m_DisallowFlags |= DRC_DISALLOW_GRAPHICS; break;
368 case T_hole: c.m_DisallowFlags |= DRC_DISALLOW_HOLES; break;
369 case T_footprint: c.m_DisallowFlags |= DRC_DISALLOW_FOOTPRINTS; break;
370
371 case T_EOF:
372 reportError( _( "Missing ')'." ) );
373 return;
374
375 default:
376 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
377 wxT( "track, via, micro_via, buried_via, pad, zone, text, graphic, "
378 "hole, or footprint." ) );
379 reportError( msg );
380 break;
381 }
382 }
383
384 if( (int) CurTok() != DSN_RIGHT )
385 reportError( _( "Missing ')'." ) );
386
387 aRule->AddConstraint( c );
388 return;
389 }
390 else if( c.m_Type == ZONE_CONNECTION_CONSTRAINT )
391 {
392 token = NextTok();
393
394 if( (int) token == DSN_STRING )
395 token = GetCurStrAsToken();
396
397 switch( token )
398 {
399 case T_solid: c.m_ZoneConnection = ZONE_CONNECTION::FULL; break;
400 case T_thermal_reliefs: c.m_ZoneConnection = ZONE_CONNECTION::THERMAL; break;
401 case T_none: c.m_ZoneConnection = ZONE_CONNECTION::NONE; break;
402
403 case T_EOF:
404 reportError( _( "Missing ')'." ) );
405 return;
406
407 default:
408 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
409 "solid, thermal_reliefs or none." );
410 reportError( msg );
411 break;
412 }
413
414 if( (int) NextTok() != DSN_RIGHT )
415 reportError( _( "Missing ')'." ) );
416
417 aRule->AddConstraint( c );
418 return;
419 }
421 {
422 // We don't use a min/max/opt structure here because it would give a strong implication
423 // that you could specify the optimal number of spokes. We don't want to open that door
424 // because the spoke generator is highly optimized around being able to "cheat" off of a
425 // cartesian coordinate system.
426
427 token = NextTok();
428
429 if( (int) token == DSN_NUMBER )
430 {
431 value = (int) strtol( CurText(), nullptr, 10 );
432 c.m_Value.SetMin( value );
433 }
434 else
435 {
436 reportError( _( "Expecting number." ) );
437 parseUnknown();
438 }
439
440 if( (int) NextTok() != DSN_RIGHT )
441 reportError( _( "Missing ')'." ) );
442
443 aRule->AddConstraint( c );
444 return;
445 }
446 else if( c.m_Type == ASSERTION_CONSTRAINT )
447 {
448 token = NextTok();
449
450 if( (int) token == DSN_RIGHT )
451 reportError( _( "Missing assertion expression." ) );
452
453 if( IsSymbol( token ) )
454 {
455 c.m_Test = new DRC_RULE_CONDITION( FromUTF8() );
456 c.m_Test->Compile( m_reporter, CurLineNumber(), CurOffset() );
457 }
458 else
459 {
460 msg.Printf( _( "Unrecognized item '%s'.| Expected quoted expression." ), FromUTF8() );
461 reportError( msg );
462 }
463
464 if( (int) NextTok() != DSN_RIGHT )
465 {
466 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
467 parseUnknown();
468 }
469
470 aRule->AddConstraint( c );
471 return;
472 }
473
474 for( token = NextTok(); token != T_RIGHT && token != T_EOF; token = NextTok() )
475 {
476 if( token != T_LEFT )
477 reportError( _( "Missing '('." ) );
478
479 token = NextTok();
480
481 switch( token )
482 {
483 case T_min:
484 token = NextTok();
485
486 if( (int) token == DSN_RIGHT )
487 {
488 reportError( _( "Missing min value." ) );
489 break;
490 }
491
492 parseValueWithUnits( FromUTF8(), value, unitless );
493 c.m_Value.SetMin( value );
494
495 if( (int) NextTok() != DSN_RIGHT )
496 {
497 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
498 parseUnknown();
499 }
500
501 break;
502
503 case T_max:
504 token = NextTok();
505
506 if( (int) token == DSN_RIGHT )
507 {
508 reportError( _( "Missing max value." ) );
509 break;
510 }
511
512 parseValueWithUnits( FromUTF8(), value, unitless );
513
514 c.m_Value.SetMax( value );
515
516 if( (int) NextTok() != DSN_RIGHT )
517 {
518 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
519 parseUnknown();
520 }
521
522 break;
523
524 case T_opt:
525 token = NextTok();
526
527 if( (int) token == DSN_RIGHT )
528 {
529 reportError( _( "Missing opt value." ) );
530 break;
531 }
532
533 parseValueWithUnits( FromUTF8(), value, unitless );
534 c.m_Value.SetOpt( value );
535
536 if( (int) NextTok() != DSN_RIGHT )
537 {
538 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
539 parseUnknown();
540 }
541
542 break;
543
544 case T_EOF:
545 reportError( _( "Incomplete statement." ) );
546 return;
547
548 default:
549 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
550 FromUTF8(),
551 wxT( "min, max, or opt" ) );
552 reportError( msg );
553 parseUnknown();
554 }
555 }
556
557 if( (int) CurTok() != DSN_RIGHT )
558 reportError( _( "Missing ')'." ) );
559
560 aRule->AddConstraint( c );
561}
DRC_RULE_CONDITION * m_Test
Definition: drc_rule.h:175
int m_DisallowFlags
Definition: drc_rule.h:173
ZONE_CONNECTION m_ZoneConnection
Definition: drc_rule.h:174
MINOPTMAX< int > m_Value
Definition: drc_rule.h:172
DRC_CONSTRAINT_T m_Type
Definition: drc_rule.h:171
void parseValueWithUnits(const wxString &aExpr, int &aResult, bool aUnitless=false)
void reportDeprecation(const wxString &oldToken, const wxString newToken)
bool Compile(REPORTER *aReporter, int aSourceLine=0, int aSourceOffset=0)
void AddConstraint(DRC_CONSTRAINT &aConstraint)
Definition: drc_rule.cpp:60
std::optional< DRC_CONSTRAINT > FindConstraint(DRC_CONSTRAINT_T aType)
Definition: drc_rule.cpp:67
void SetMin(T v)
Definition: minoptmax.h:41
void SetOpt(T v)
Definition: minoptmax.h:43
void SetMax(T v)
Definition: minoptmax.h:42
@ DRC_DISALLOW_PADS
Definition: drc_rule.h:83
@ DRC_DISALLOW_VIAS
Definition: drc_rule.h:79
@ DRC_DISALLOW_TEXTS
Definition: drc_rule.h:85
@ DRC_DISALLOW_ZONES
Definition: drc_rule.h:84
@ DRC_DISALLOW_HOLES
Definition: drc_rule.h:87
@ DRC_DISALLOW_GRAPHICS
Definition: drc_rule.h:86
@ DRC_DISALLOW_FOOTPRINTS
Definition: drc_rule.h:88
@ DRC_DISALLOW_TRACKS
Definition: drc_rule.h:82
@ DRC_DISALLOW_MICRO_VIAS
Definition: drc_rule.h:80
@ DRC_DISALLOW_BB_VIAS
Definition: drc_rule.h:81
@ ANNULAR_WIDTH_CONSTRAINT
Definition: drc_rule.h:57
@ COURTYARD_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:52
@ VIA_DIAMETER_CONSTRAINT
Definition: drc_rule.h:63
@ ZONE_CONNECTION_CONSTRAINT
Definition: drc_rule.h:58
@ DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT
Definition: drc_rule.h:67
@ DIFF_PAIR_GAP_CONSTRAINT
Definition: drc_rule.h:66
@ DISALLOW_CONSTRAINT
Definition: drc_rule.h:62
@ TRACK_WIDTH_CONSTRAINT
Definition: drc_rule.h:56
@ SILK_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:53
@ EDGE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:50
@ MIN_RESOLVED_SPOKES_CONSTRAINT
Definition: drc_rule.h:61
@ TEXT_THICKNESS_CONSTRAINT
Definition: drc_rule.h:55
@ LENGTH_CONSTRAINT
Definition: drc_rule.h:64
@ VIA_COUNT_CONSTRAINT
Definition: drc_rule.h:69
@ PHYSICAL_HOLE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:71
@ CLEARANCE_CONSTRAINT
Definition: drc_rule.h:47
@ THERMAL_SPOKE_WIDTH_CONSTRAINT
Definition: drc_rule.h:60
@ CONNECTION_WIDTH_CONSTRAINT
Definition: drc_rule.h:73
@ THERMAL_RELIEF_GAP_CONSTRAINT
Definition: drc_rule.h:59
@ ASSERTION_CONSTRAINT
Definition: drc_rule.h:72
@ SKEW_CONSTRAINT
Definition: drc_rule.h:65
@ HOLE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:48
@ HOLE_SIZE_CONSTRAINT
Definition: drc_rule.h:51
@ TEXT_HEIGHT_CONSTRAINT
Definition: drc_rule.h:54
@ PHYSICAL_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:70
@ HOLE_TO_HOLE_CONSTRAINT
Definition: drc_rule.h:49
@ DSN_STRING
Definition: dsnlexer.h:68
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
@ THERMAL
Use thermal relief for pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper

References _, DRC_RULE::AddConstraint(), ANNULAR_WIDTH_CONSTRAINT, ASSERTION_CONSTRAINT, CLEARANCE_CONSTRAINT, DRC_RULE_CONDITION::Compile(), CONNECTION_WIDTH_CONSTRAINT, COURTYARD_CLEARANCE_CONSTRAINT, DIFF_PAIR_GAP_CONSTRAINT, DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT, DISALLOW_CONSTRAINT, DRC_DISALLOW_BB_VIAS, DRC_DISALLOW_FOOTPRINTS, DRC_DISALLOW_GRAPHICS, DRC_DISALLOW_HOLES, DRC_DISALLOW_MICRO_VIAS, DRC_DISALLOW_PADS, DRC_DISALLOW_TEXTS, DRC_DISALLOW_TRACKS, DRC_DISALLOW_VIAS, DRC_DISALLOW_ZONES, DSN_NUMBER, DSN_RIGHT, DSN_STRING, EDGE_CLEARANCE_CONSTRAINT, DRC_RULE::FindConstraint(), Format(), FULL, HOLE_CLEARANCE_CONSTRAINT, HOLE_SIZE_CONSTRAINT, HOLE_TO_HOLE_CONSTRAINT, LENGTH_CONSTRAINT, DRC_CONSTRAINT::m_DisallowFlags, m_reporter, DRC_CONSTRAINT::m_Test, DRC_CONSTRAINT::m_Type, DRC_CONSTRAINT::m_Value, DRC_CONSTRAINT::m_ZoneConnection, MIN_RESOLVED_SPOKES_CONSTRAINT, NONE, parseUnknown(), parseValueWithUnits(), PHYSICAL_CLEARANCE_CONSTRAINT, PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, reportDeprecation(), reportError(), MINOPTMAX< T >::SetMax(), MINOPTMAX< T >::SetMin(), MINOPTMAX< T >::SetOpt(), SILK_CLEARANCE_CONSTRAINT, SKEW_CONSTRAINT, TEXT_HEIGHT_CONSTRAINT, TEXT_THICKNESS_CONSTRAINT, THERMAL, THERMAL_RELIEF_GAP_CONSTRAINT, THERMAL_SPOKE_WIDTH_CONSTRAINT, TRACK_WIDTH_CONSTRAINT, VIA_COUNT_CONSTRAINT, VIA_DIAMETER_CONSTRAINT, and ZONE_CONNECTION_CONSTRAINT.

Referenced by parseDRC_RULE().

◆ parseDRC_RULE()

std::shared_ptr< DRC_RULE > DRC_RULES_PARSER::parseDRC_RULE ( )
private

Definition at line 185 of file drc_rule_parser.cpp.

186{
187 std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
188
189 T token = NextTok();
190 wxString msg;
191
192 if( !IsSymbol( token ) )
193 reportError( _( "Missing rule name." ) );
194
195 rule->m_Name = FromUTF8();
196
197 for( token = NextTok(); token != T_RIGHT && token != T_EOF; token = NextTok() )
198 {
199 if( token != T_LEFT )
200 reportError( _( "Missing '('." ) );
201
202 token = NextTok();
203
204 switch( token )
205 {
206 case T_constraint:
207 parseConstraint( rule.get() );
208 break;
209
210 case T_condition:
211 token = NextTok();
212
213 if( (int) token == DSN_RIGHT )
214 {
215 reportError( _( "Missing condition expression." ) );
216 break;
217 }
218
219 if( IsSymbol( token ) )
220 {
221 rule->m_Condition = new DRC_RULE_CONDITION( FromUTF8() );
222 rule->m_Condition->Compile( m_reporter, CurLineNumber(), CurOffset() );
223 }
224 else
225 {
226 msg.Printf( _( "Unrecognized item '%s'.| Expected quoted expression." ),
227 FromUTF8() );
228 reportError( msg );
229 }
230
231 if( (int) NextTok() != DSN_RIGHT )
232 {
233 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
234 parseUnknown();
235 }
236
237 break;
238
239 case T_layer:
240 rule->m_LayerSource = FromUTF8();
241 rule->m_LayerCondition = parseLayer();
242 break;
243
244 case T_severity:
245 rule->m_Severity = parseSeverity();
246 break;
247
248 case T_EOF:
249 reportError( _( "Incomplete statement." ) );
250 return rule;
251
252 default:
253 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
254 wxT( "constraint, condition, or disallow" ) );
255 reportError( msg );
256 parseUnknown();
257 }
258 }
259
260 if( (int) CurTok() != DSN_RIGHT )
261 reportError( _( "Missing ')'." ) );
262
263 return rule;
264}
SEVERITY parseSeverity()
void parseConstraint(DRC_RULE *aRule)

References _, DSN_RIGHT, Format(), m_reporter, parseConstraint(), parseLayer(), parseSeverity(), parseUnknown(), and reportError().

Referenced by Parse().

◆ parseLayer()

LSET DRC_RULES_PARSER::parseLayer ( )
private

Definition at line 596 of file drc_rule_parser.cpp.

597{
598 LSET retVal;
599 int token = NextTok();
600
601 if( (int) token == DSN_RIGHT )
602 {
603 reportError( _( "Missing layer name or type." ) );
604 return LSET::AllCuMask();
605 }
606 else if( token == T_outer )
607 {
608 retVal = LSET::ExternalCuMask();
609 }
610 else if( token == T_inner )
611 {
612 retVal = LSET::InternalCuMask();
613 }
614 else
615 {
616 wxString layerName = FromUTF8();
617 wxPGChoices& layerMap = ENUM_MAP<PCB_LAYER_ID>::Instance().Choices();
618
619 for( unsigned ii = 0; ii < layerMap.GetCount(); ++ii )
620 {
621 wxPGChoiceEntry& entry = layerMap[ii];
622
623 if( entry.GetText().Matches( layerName ) )
624 retVal.set( ToLAYER_ID( entry.GetValue() ) );
625 }
626
627 if( !retVal.any() )
628 {
629 reportError( wxString::Format( _( "Unrecognized layer '%s'." ), layerName ) );
630 retVal.set( Rescue );
631 }
632 }
633
634 if( (int) NextTok() != DSN_RIGHT )
635 {
636 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
637 parseUnknown();
638 }
639
640 return retVal;
641}
static ENUM_MAP< T > & Instance()
Definition: property.h:573
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
static LSET ExternalCuMask()
Return a mask holding the Front and Bottom layers.
Definition: lset.cpp:801
static LSET InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
Definition: lset.cpp:733
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
@ Rescue
Definition: layer_ids.h:133
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932

References _, LSET::AllCuMask(), DSN_RIGHT, LSET::ExternalCuMask(), Format(), ENUM_MAP< T >::Instance(), LSET::InternalCuMask(), parseUnknown(), reportError(), Rescue, and ToLAYER_ID().

Referenced by parseDRC_RULE().

◆ parseSeverity()

SEVERITY DRC_RULES_PARSER::parseSeverity ( )
private

Definition at line 644 of file drc_rule_parser.cpp.

645{
647 wxString msg;
648
649 T token = NextTok();
650
651 if( (int) token == DSN_RIGHT || token == T_EOF )
652 {
653 reportError( _( "Missing severity name." ) );
655 }
656
657 switch( token )
658 {
659 case T_ignore: retVal = RPT_SEVERITY_IGNORE; break;
660 case T_warning: retVal = RPT_SEVERITY_WARNING; break;
661 case T_error: retVal = RPT_SEVERITY_ERROR; break;
662 case T_exclusion: retVal = RPT_SEVERITY_EXCLUSION; break;
663
664 default:
665 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
666 FromUTF8(),
667 wxT( "ignore, warning, error, or exclusion" ) );
668 reportError( msg );
669 parseUnknown();
670 }
671
672 if( (int) NextTok() != DSN_RIGHT )
673 reportError( _( "Missing ')'." ) );
674
675 return retVal;
676}
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_UNDEFINED
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE

References _, DSN_RIGHT, parseUnknown(), reportError(), RPT_SEVERITY_ERROR, RPT_SEVERITY_EXCLUSION, RPT_SEVERITY_IGNORE, RPT_SEVERITY_UNDEFINED, and RPT_SEVERITY_WARNING.

Referenced by parseDRC_RULE().

◆ parseUnknown()

void DRC_RULES_PARSER::parseUnknown ( )
private

Definition at line 89 of file drc_rule_parser.cpp.

90{
91 int depth = 1;
92
93 for( T token = NextTok(); token != T_EOF; token = NextTok() )
94 {
95 if( token == T_LEFT )
96 depth++;
97
98 if( token == T_RIGHT )
99 {
100 if( --depth == 0 )
101 break;
102 }
103 }
104}

Referenced by Parse(), parseConstraint(), parseDRC_RULE(), parseLayer(), and parseSeverity().

◆ parseValueWithUnits()

void DRC_RULES_PARSER::parseValueWithUnits ( const wxString &  aExpr,
int &  aResult,
bool  aUnitless = false 
)
private

Definition at line 564 of file drc_rule_parser.cpp.

565{
566 auto errorHandler = [&]( const wxString& aMessage, int aOffset )
567 {
568 wxString rest;
569 wxString first = aMessage.BeforeFirst( '|', &rest );
570
571 if( m_reporter )
572 {
573 wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ),
574 CurLineNumber(), CurOffset() + aOffset, first, rest );
575
577 }
578 else
579 {
580 wxString msg = wxString::Format( _( "ERROR: %s%s" ), first, rest );
581
582 THROW_PARSE_ERROR( msg, CurSource(), CurLine(), CurLineNumber(),
583 CurOffset() + aOffset );
584 }
585 };
586
589 evaluator.SetErrorCallback( errorHandler );
590
591 evaluator.Evaluate( aExpr );
592 aResult = evaluator.Result();
593}
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:164

References _, PCB_EXPR_EVALUATOR::Evaluate(), Format(), m_reporter, REPORTER::Report(), PCB_EXPR_EVALUATOR::Result(), RPT_SEVERITY_ERROR, PCB_EXPR_EVALUATOR::SetErrorCallback(), and THROW_PARSE_ERROR.

Referenced by parseConstraint().

◆ reportDeprecation()

void DRC_RULES_PARSER::reportDeprecation ( const wxString &  oldToken,
const wxString  newToken 
)
private

Definition at line 75 of file drc_rule_parser.cpp.

76{
77 if( m_reporter )
78 {
79 wxString msg = wxString::Format( _( "The '%s' keyword has been deprecated. "
80 "Please use '%s' instead." ),
81 oldToken,
82 newToken);
83
85 }
86}

References _, Format(), m_reporter, REPORTER::Report(), and RPT_SEVERITY_WARNING.

Referenced by parseConstraint().

◆ reportError()

void DRC_RULES_PARSER::reportError ( const wxString &  aMessage)
private

Definition at line 54 of file drc_rule_parser.cpp.

55{
56 wxString rest;
57 wxString first = aMessage.BeforeFirst( '|', &rest );
58
59 if( m_reporter )
60 {
61 wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ), CurLineNumber(),
62 CurOffset(), first, rest );
63
65 }
66 else
67 {
68 wxString msg = wxString::Format( _( "ERROR: %s%s" ), first, rest );
69
70 THROW_PARSE_ERROR( msg, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
71 }
72}

References _, Format(), m_reporter, REPORTER::Report(), RPT_SEVERITY_ERROR, and THROW_PARSE_ERROR.

Referenced by Parse(), parseConstraint(), parseDRC_RULE(), parseLayer(), and parseSeverity().

Member Data Documentation

◆ m_reporter

REPORTER* DRC_RULES_PARSER::m_reporter
private

◆ m_requiredVersion

int DRC_RULES_PARSER::m_requiredVersion
private

Definition at line 61 of file drc_rule_parser.h.

Referenced by Parse().

◆ m_tooRecent

bool DRC_RULES_PARSER::m_tooRecent
private

Definition at line 62 of file drc_rule_parser.h.

Referenced by Parse().


The documentation for this class was generated from the following files: