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 <dick@softplc.com>
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
36 
39 struct 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,
60  DSN_COMMENT = -10,
63  DSN_DASH = -7,
64  DSN_SYMBOL = -6,
65  DSN_NUMBER = -5,
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 
78 class DSNLEXER
79 {
80 public:
81 
92  DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
93  FILE* aFile, const wxString& aFileName );
94 
104  DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
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,
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 
253  int GetCurStrAsToken() const
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 
458 protected:
459  void init();
460 
461  int readLine()
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 
501  bool iOwnReaders;
502  const char* start;
503  const char* next;
504  const char* limit;
505  char dummy[1];
506 
507  typedef std::vector<LINE_READER*> READER_STACK;
508 
510 
513 
515 
522 
524 
525  int prevTok;
526  int curOffset;
527 
528  int curTok;
529  std::string curText;
530 
531  const KEYWORD* keywords;
532  unsigned keywordCount;
534 #endif // SWIG
535 };
536 
537 #endif // DSNLEXER_H_
int curOffset
offset within current line of the current token
Definition: dsnlexer.h:526
int CurLineNumber() const
Return the current line number within my LINE_READER.
Definition: dsnlexer.h:423
std::vector< LINE_READER * > READER_STACK
Definition: dsnlexer.h:507
int NeedNUMBER(const char *aExpectation)
Call NextTok() and then verifies that the token read is type DSN_NUMBER.
Definition: dsnlexer.cpp:412
bool commentsAreTokens
true if should return comments as tokens
Definition: dsnlexer.h:523
bool SetCommentsAreTokens(bool val)
Change the handling of comments.
Definition: dsnlexer.h:296
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition: richio.h:80
void PushReader(LINE_READER *aLineReader)
Manage a stack of LINE_READERs in order to handle nested file inclusion.
Definition: dsnlexer.cpp:199
bool isStringTerminator(char cc) const
Definition: dsnlexer.h:490
char * Line() const
Return a pointer to the last line that was read in.
Definition: richio.h:117
virtual const wxString & GetSource() const
Returns the name of the source of the lines in an abstract sense.
Definition: richio.h:109
int NeedSYMBOLorNUMBER()
Call NextTok() and then verifies that the token read in satisfies bool IsSymbol() or the next token i...
Definition: dsnlexer.cpp:401
char SetStringDelimiter(char aStringDelimiter)
Change the string delimiter from the default " to some other character and return the old value.
Definition: dsnlexer.h:265
const KEYWORD * keywords
table sorted by CMake for bsearch()
Definition: dsnlexer.h:531
virtual ~DSNLEXER()
Definition: dsnlexer.cpp:139
void InitParserState()
Reinit variables used during parsing, to ensure od states are not used in a new parsing must be calle...
Definition: dsnlexer.cpp:166
const char * name
unique keyword.
Definition: dsnlexer.h:41
wxArrayString * ReadCommentLines()
Check the next sequence of tokens and reads them into a wxArrayString if they are comments.
Definition: dsnlexer.cpp:809
bool SetSpaceInQuotedTokens(bool val)
Change the setting controlling whether a space in a quoted string isa terminator.
Definition: dsnlexer.h:280
KEYWORD_MAP keyword_hash
fast, specialized "C string" hashtable
Definition: dsnlexer.h:533
const char * CurText() const
Return a pointer to the current token's text.
Definition: dsnlexer.h:398
void SetSpecctraMode(bool aMode)
Change the behavior of this lexer into or out of "specctra mode".
Definition: dsnlexer.cpp:150
bool space_in_quoted_tokens
blank spaces within quoted strings
Definition: dsnlexer.h:521
int findToken(const std::string &aToken) const
Take aToken string and looks up the string in the keywords table.
Definition: dsnlexer.cpp:240
wxString GetTokenString(int aTok) const
Return a quote wrapped wxString representation of a token value.
Definition: dsnlexer.cpp:314
const char * next
Definition: dsnlexer.h:503
int NeedSYMBOL()
Call NextTok() and then verifies that the token read in satisfies IsSymbol().
Definition: dsnlexer.cpp:390
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:211
void NeedLEFT()
Call NextTok() and then verifies that the token read in is a DSN_LEFT.
Definition: dsnlexer.cpp:373
const char * limit
Definition: dsnlexer.h:504
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
Definition: richio.h:135
static bool IsSymbol(int aTok)
Test a token to see if it is a symbol.
Definition: dsnlexer.cpp:324
int CurTok() const
Return whatever NextTok() returned the last time it was called.
Definition: dsnlexer.h:237
DSN_SYNTAX_T
List all the DSN lexer's tokens that are supported in lexing.
Definition: dsnlexer.h:57
const std::string & CurStr() const
Return a reference to current token in std::string form.
Definition: dsnlexer.h:406
const char * GetTokenText(int aTok) const
Return the C string representation of a DSN_T value.
Definition: dsnlexer.cpp:295
bool iOwnReaders
on readerStack, should I delete them?
Definition: dsnlexer.h:501
READER_STACK readerStack
all the LINE_READERs by pointer.
Definition: dsnlexer.h:509
LINE_READER * reader
Definition: dsnlexer.h:512
unsigned Length() const
Return the number of bytes in the last line read from this LINE_READER.
Definition: richio.h:143
bool specctraMode
if true, then: 1) stringDelimiter can be changed 2) Kicad quoting protocol is not in effect 3) space_...
Definition: dsnlexer.h:514
int prevTok
curTok from previous NextTok() call.
Definition: dsnlexer.h:525
int readLine()
Definition: dsnlexer.h:461
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:129
int CurOffset() const
Return the byte offset within the current line, using a 1 based index.
Definition: dsnlexer.h:451
const char * start
Definition: dsnlexer.h:502
virtual char * ReadLine()=0
Read a line of text into the buffer and increments the line number counter.
bool SyncLineReaderWith(DSNLEXER &aLexer)
Usable only for DSN lexers which share the same LINE_READER.
Definition: dsnlexer.cpp:176
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:357
std::string curText
the text of the current token
Definition: dsnlexer.h:529
int NextTok()
Return the next token found in the input file or DSN_EOF when reaching the end of file.
Definition: dsnlexer.cpp:526
void Expecting(int aTok) const
Throw an IO_ERROR exception with an input file specific error message.
Definition: dsnlexer.cpp:333
const char * CurLine() const
Return the current line of text from which the CurText() would return its token.
Definition: dsnlexer.h:431
void NeedRIGHT()
Call NextTok() and then verifies that the token read in is a DSN_RIGHT.
Definition: dsnlexer.cpp:381
unsigned keywordCount
count of keywords table
Definition: dsnlexer.h:532
int PrevTok() const
Return whatever NextTok() returned the 2nd to last time it was called.
Definition: dsnlexer.h:245
const wxString & CurSource() const
Return the current LINE_READER source.
Definition: dsnlexer.h:441
char dummy[1]
when there is no reader.
Definition: dsnlexer.h:505
int curTok
the current token obtained on last NextTok()
Definition: dsnlexer.h:528
void Unexpected(int aTok) const
Throw an IO_ERROR exception with an input file specific error message.
Definition: dsnlexer.cpp:349
Hold a keyword string and its unique integer token.
Definition: dsnlexer.h:39
void init()
Definition: dsnlexer.cpp:40
Implement a lexical analyzer for the SPECCTRA DSN file format.
Definition: dsnlexer.h:78
char stringDelimiter
Definition: dsnlexer.h:520
DSNLEXER(const KEYWORD *aKeywordTable, unsigned aKeywordCount, 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:72
wxString FromUTF8() const
Return the current token text as a wxString, assuming that the input byte stream is UTF8 encoded.
Definition: dsnlexer.h:415
int token
a zero based index into an array of KEYWORDs
Definition: dsnlexer.h:42
int GetCurStrAsToken() const
Used to support "loose" matches (quoted tokens).
Definition: dsnlexer.h:253
static const char * Syntax(int aTok)
Definition: dsnlexer.cpp:251