KiCad PCB EDA Suite
dsnlexer.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright (C) 2007-2021 Kicad Developers, see change_log.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#ifndef DSNLEXER_H_
26#define DSNLEXER_H_
27
28#include <cstdio>
29#include <hashtables.h>
30#include <string>
31#include <vector>
32
33#include <richio.h>
34
35#ifndef SWIG
39struct KEYWORD
40{
41 const char* name;
42 int token;
43};
44#endif // SWIG
45
46// something like this macro can be used to help initialize a KEYWORD table.
47// see SPECCTRA_DB::keywords[] as an example.
48
49//#define TOKDEF(x) { #x, T_##x }
50
51
58{
59 DSN_NONE = -11,
66 DSN_RIGHT = -4, // right bracket, ')'
67 DSN_LEFT = -3, // left bracket, '('
68 DSN_STRING = -2, // a quoted string, stripped of the quotes
69 DSN_EOF = -1 // special case for end of file
70};
71
72
79{
80public:
81
92 DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount, const KEYWORD_MAP* aKeywordMap,
93 FILE* aFile, const wxString& aFileName );
94
104 DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount, const KEYWORD_MAP* aKeywordMap,
105 const std::string& aSExpression, const wxString& aSource = wxEmptyString );
106
115 DSNLEXER( const std::string& aSExpression, const wxString& aSource = wxEmptyString );
116
129 DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount, const KEYWORD_MAP* aKeywordMap,
130 LINE_READER* aLineReader = nullptr );
131
132 virtual ~DSNLEXER();
133
139 void InitParserState();
140
150 bool SyncLineReaderWith( DSNLEXER& aLexer );
151
165 void SetSpecctraMode( bool aMode );
166
177 void PushReader( LINE_READER* aLineReader );
178
195
207 int NextTok();
208
215 int NeedSYMBOL();
216
224 int NeedSYMBOLorNUMBER();
225
232 int NeedNUMBER( const char* aExpectation );
233
237 int CurTok() const
238 {
239 return curTok;
240 }
241
245 int PrevTok() const
246 {
247 return prevTok;
248 }
249
254 {
255 return findToken( curText );
256 }
257
265 char SetStringDelimiter( char aStringDelimiter )
266 {
267 int old = stringDelimiter;
268
269 if( specctraMode )
270 stringDelimiter = aStringDelimiter;
271
272 return old;
273 }
274
280 bool SetSpaceInQuotedTokens( bool val )
281 {
282 bool old = space_in_quoted_tokens;
283
284 if( specctraMode )
286
287 return old;
288 }
289
296 bool SetCommentsAreTokens( bool val )
297 {
298 bool old = commentsAreTokens;
299 commentsAreTokens = val;
300 return old;
301 }
302
315 wxArrayString* ReadCommentLines();
316
323 static bool IsSymbol( int aTok );
324
331 void Expecting( int aTok ) const;
332
340 void Expecting( const char* aTokenList ) const;
341
349 void Unexpected( int aTok ) const;
350
357 void Unexpected( const char* aToken ) const;
358
367 void Duplicate( int aTok );
368
374 void NeedLEFT();
375
381 void NeedRIGHT();
382
386 const char* GetTokenText( int aTok ) const;
387
391 wxString GetTokenString( int aTok ) const;
392
393 static const char* Syntax( int aTok );
394
398 const char* CurText() const
399 {
400 return curText.c_str();
401 }
402
406 const std::string& CurStr() const
407 {
408 return curText;
409 }
410
415 wxString FromUTF8() const
416 {
417 return wxString::FromUTF8( curText.c_str() );
418 }
419
423 int CurLineNumber() const
424 {
425 return reader->LineNumber();
426 }
427
431 const char* CurLine() const
432 {
433 return (const char*)(*reader);
434 }
435
441 const wxString& CurSource() const
442 {
443 return reader->GetSource();
444 }
445
451 int CurOffset() const
452 {
453 return curOffset + 1;
454 }
455
456#ifndef SWIG
457
458protected:
459 void init();
460
462 {
463 if( reader )
464 {
465 reader->ReadLine();
466
467 unsigned len = reader->Length();
468
469 // start may have changed in ReadLine(), which can resize and
470 // relocate reader's line buffer.
471 start = reader->Line();
472
473 next = start;
474 limit = next + len;
475
476 return len;
477 }
478 return 0;
479 }
480
488 int findToken( const std::string& aToken ) const;
489
490 bool isStringTerminator( char cc ) const
491 {
492 if( !space_in_quoted_tokens && cc == ' ' )
493 return true;
494
495 if( cc == stringDelimiter )
496 return true;
497
498 return false;
499 }
500
508 double parseDouble();
509
510 double parseDouble( const char* aExpected )
511 {
512 NeedNUMBER( aExpected );
513 return parseDouble();
514 }
515
516 template <typename T>
517 inline double parseDouble( T aToken )
518 {
519 return parseDouble( GetTokenText( aToken ) );
520 }
521
523 const char* start;
524 const char* next;
525 const char* limit;
526 char dummy[1];
527
528 typedef std::vector<LINE_READER*> READER_STACK;
529
531
534
540
543
545
548
549 int curTok;
550 std::string curText;
551
553 unsigned keywordCount;
555#endif // SWIG
556};
557
558#endif // DSNLEXER_H_
Implement a lexical analyzer for the SPECCTRA DSN file format.
Definition: dsnlexer.h:79
int NeedSYMBOLorNUMBER()
Call NextTok() and then verifies that the token read in satisfies bool IsSymbol() or the next token i...
Definition: dsnlexer.cpp:394
virtual ~DSNLEXER()
Definition: dsnlexer.cpp:129
void NeedLEFT()
Call NextTok() and then verifies that the token read in is a DSN_LEFT.
Definition: dsnlexer.cpp:366
const char * next
Definition: dsnlexer.h:524
std::string curText
the text of the current token
Definition: dsnlexer.h:550
unsigned keywordCount
count of keywords table
Definition: dsnlexer.h:553
int NeedNUMBER(const char *aExpectation)
Call NextTok() and then verifies that the token read is type DSN_NUMBER.
Definition: dsnlexer.cpp:405
std::vector< LINE_READER * > READER_STACK
Definition: dsnlexer.h:528
bool SetSpaceInQuotedTokens(bool val)
Change the setting controlling whether a space in a quoted string isa terminator.
Definition: dsnlexer.h:280
bool commentsAreTokens
true if should return comments as tokens
Definition: dsnlexer.h:544
int findToken(const std::string &aToken) const
Take aToken string and looks up the string in the keywords table.
Definition: dsnlexer.cpp:230
const char * CurText() const
Return a pointer to the current token's text.
Definition: dsnlexer.h:398
static bool IsSymbol(int aTok)
Test a token to see if it is a symbol.
Definition: dsnlexer.cpp:317
void init()
Definition: dsnlexer.cpp:40
const char * start
Definition: dsnlexer.h:523
const char * GetTokenText(int aTok) const
Return the C string representation of a DSN_T value.
Definition: dsnlexer.cpp:288
wxArrayString * ReadCommentLines()
Check the next sequence of tokens and reads them into a wxArrayString if they are comments.
Definition: dsnlexer.cpp:802
int curTok
the current token obtained on last NextTok()
Definition: dsnlexer.h:549
bool space_in_quoted_tokens
blank spaces within quoted strings
Definition: dsnlexer.h:542
int PrevTok() const
Return whatever NextTok() returned the 2nd to last time it was called.
Definition: dsnlexer.h:245
bool specctraMode
if true, then: 1) stringDelimiter can be changed 2) Kicad quoting protocol is not in effect 3) space_...
Definition: dsnlexer.h:535
int NextTok()
Return the next token found in the input file or DSN_EOF when reaching the end of file.
Definition: dsnlexer.cpp:519
int NeedSYMBOL()
Call NextTok() and then verifies that the token read in satisfies IsSymbol().
Definition: dsnlexer.cpp:383
int curOffset
offset within current line of the current token
Definition: dsnlexer.h:547
char stringDelimiter
Definition: dsnlexer.h:541
LINE_READER * reader
Definition: dsnlexer.h:533
const char * limit
Definition: dsnlexer.h:525
bool isStringTerminator(char cc) const
Definition: dsnlexer.h:490
const KEYWORD * keywords
table sorted by CMake for bsearch()
Definition: dsnlexer.h:552
void NeedRIGHT()
Call NextTok() and then verifies that the token read in is a DSN_RIGHT.
Definition: dsnlexer.cpp:374
int readLine()
Definition: dsnlexer.h:461
READER_STACK readerStack
all the LINE_READERs by pointer.
Definition: dsnlexer.h:530
char dummy[1]
when there is no reader.
Definition: dsnlexer.h:526
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
Definition: dsnlexer.cpp:825
void SetSpecctraMode(bool aMode)
Change the behavior of this lexer into or out of "specctra mode".
Definition: dsnlexer.cpp:140
wxString FromUTF8() const
Return the current token text as a wxString, assuming that the input byte stream is UTF8 encoded.
Definition: dsnlexer.h:415
void Expecting(int aTok) const
Throw an IO_ERROR exception with an input file specific error message.
Definition: dsnlexer.cpp:326
const wxString & CurSource() const
Return the current LINE_READER source.
Definition: dsnlexer.h:441
LINE_READER * PopReader()
Delete the top most LINE_READER from an internal stack of LINE_READERs and in the case of FILE_LINE_R...
Definition: dsnlexer.cpp:201
void Duplicate(int aTok)
Throw an IO_ERROR exception with a message saying specifically that aTok is a duplicate of one alread...
Definition: dsnlexer.cpp:350
const std::string & CurStr() const
Return a reference to current token in std::string form.
Definition: dsnlexer.h:406
const char * CurLine() const
Return the current line of text from which the CurText() would return its token.
Definition: dsnlexer.h:431
bool SetCommentsAreTokens(bool val)
Change the handling of comments.
Definition: dsnlexer.h:296
wxString GetTokenString(int aTok) const
Return a quote wrapped wxString representation of a token value.
Definition: dsnlexer.cpp:307
double parseDouble(T aToken)
Definition: dsnlexer.h:517
int GetCurStrAsToken() const
Used to support "loose" matches (quoted tokens).
Definition: dsnlexer.h:253
int CurTok() const
Return whatever NextTok() returned the last time it was called.
Definition: dsnlexer.h:237
double parseDouble(const char *aExpected)
Definition: dsnlexer.h:510
int CurOffset() const
Return the byte offset within the current line, using a 1 based index.
Definition: dsnlexer.h:451
void InitParserState()
Reinit variables used during parsing, to ensure od states are not used in a new parsing must be calle...
Definition: dsnlexer.cpp:156
char SetStringDelimiter(char aStringDelimiter)
Change the string delimiter from the default " to some other character and return the old value.
Definition: dsnlexer.h:265
int prevTok
curTok from previous NextTok() call.
Definition: dsnlexer.h:546
const KEYWORD_MAP * keywordsLookup
fast, specialized "C string" hashtable
Definition: dsnlexer.h:554
static const char * Syntax(int aTok)
Definition: dsnlexer.cpp:244
DSNLEXER(const KEYWORD *aKeywordTable, unsigned aKeywordCount, const KEYWORD_MAP *aKeywordMap, FILE *aFile, const wxString &aFileName)
Initialize a DSN lexer and prepares to read from aFile which is already open and has aFilename.
Definition: dsnlexer.cpp:55
bool SyncLineReaderWith(DSNLEXER &aLexer)
Usable only for DSN lexers which share the same LINE_READER.
Definition: dsnlexer.cpp:166
void Unexpected(int aTok) const
Throw an IO_ERROR exception with an input file specific error message.
Definition: dsnlexer.cpp:342
int CurLineNumber() const
Return the current line number within my LINE_READER.
Definition: dsnlexer.h:423
bool iOwnReaders
on readerStack, should I delete them?
Definition: dsnlexer.h:522
void PushReader(LINE_READER *aLineReader)
Manage a stack of LINE_READERs in order to handle nested file inclusion.
Definition: dsnlexer.cpp:189
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition: richio.h:81
virtual char * ReadLine()=0
Read a line of text into the buffer and increments the line number counter.
virtual const wxString & GetSource() const
Returns the name of the source of the lines in an abstract sense.
Definition: richio.h:109
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
Definition: richio.h:135
unsigned Length() const
Return the number of bytes in the last line read from this LINE_READER.
Definition: richio.h:143
char * Line() const
Return a pointer to the last line that was read in.
Definition: richio.h:117
DSN_SYNTAX_T
List all the DSN lexer's tokens that are supported in lexing.
Definition: dsnlexer.h:58
@ DSN_QUOTE_DEF
Definition: dsnlexer.h:62
@ DSN_STRING_QUOTE
Definition: dsnlexer.h:61
@ DSN_LEFT
Definition: dsnlexer.h:67
@ DSN_RIGHT
Definition: dsnlexer.h:66
@ DSN_NUMBER
Definition: dsnlexer.h:65
@ DSN_NONE
Definition: dsnlexer.h:59
@ DSN_DASH
Definition: dsnlexer.h:63
@ DSN_SYMBOL
Definition: dsnlexer.h:64
@ DSN_COMMENT
Definition: dsnlexer.h:60
@ DSN_STRING
Definition: dsnlexer.h:68
@ DSN_EOF
Definition: dsnlexer.h:69
std::unordered_map< const char *, int, fnv_1a, iequal_to > KEYWORD_MAP
A hashtable made of a const char* and an int.
Definition: hashtables.h:95
Hold a keyword string and its unique integer token.
Definition: dsnlexer.h:40
int token
a zero based index into an array of KEYWORDs
Definition: dsnlexer.h:42
const char * name
unique keyword.
Definition: dsnlexer.h:41