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-2020 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 = NULL );
131 
132  virtual ~DSNLEXER();
133 
143  bool SyncLineReaderWith( DSNLEXER& aLexer );
144 
158  void SetSpecctraMode( bool aMode );
159 
170  void PushReader( LINE_READER* aLineReader );
171 
188 
200  int NextTok();
201 
208  int NeedSYMBOL();
209 
217  int NeedSYMBOLorNUMBER();
218 
225  int NeedNUMBER( const char* aExpectation );
226 
230  int CurTok() const
231  {
232  return curTok;
233  }
234 
238  int PrevTok() const
239  {
240  return prevTok;
241  }
242 
246  int GetCurStrAsToken() const
247  {
248  return findToken( curText );
249  }
250 
258  char SetStringDelimiter( char aStringDelimiter )
259  {
260  int old = stringDelimiter;
261 
262  if( specctraMode )
263  stringDelimiter = aStringDelimiter;
264 
265  return old;
266  }
267 
273  bool SetSpaceInQuotedTokens( bool val )
274  {
275  bool old = space_in_quoted_tokens;
276 
277  if( specctraMode )
279 
280  return old;
281  }
282 
289  bool SetCommentsAreTokens( bool val )
290  {
291  bool old = commentsAreTokens;
292  commentsAreTokens = val;
293  return old;
294  }
295 
308  wxArrayString* ReadCommentLines();
309 
316  static bool IsSymbol( int aTok );
317 
324  void Expecting( int aTok ) const;
325 
333  void Expecting( const char* aTokenList ) const;
334 
342  void Unexpected( int aTok ) const;
343 
350  void Unexpected( const char* aToken ) const;
351 
360  void Duplicate( int aTok );
361 
367  void NeedLEFT();
368 
374  void NeedRIGHT();
375 
379  const char* GetTokenText( int aTok ) const;
380 
384  wxString GetTokenString( int aTok ) const;
385 
386  static const char* Syntax( int aTok );
387 
391  const char* CurText() const
392  {
393  return curText.c_str();
394  }
395 
399  const std::string& CurStr() const
400  {
401  return curText;
402  }
403 
408  wxString FromUTF8() const
409  {
410  return wxString::FromUTF8( curText.c_str() );
411  }
412 
416  int CurLineNumber() const
417  {
418  return reader->LineNumber();
419  }
420 
424  const char* CurLine() const
425  {
426  return (const char*)(*reader);
427  }
428 
434  const wxString& CurSource() const
435  {
436  return reader->GetSource();
437  }
438 
444  int CurOffset() const
445  {
446  return curOffset + 1;
447  }
448 
449 #ifndef SWIG
450 
451 protected:
452  void init();
453 
454  int readLine()
455  {
456  if( reader )
457  {
458  reader->ReadLine();
459 
460  unsigned len = reader->Length();
461 
462  // start may have changed in ReadLine(), which can resize and
463  // relocate reader's line buffer.
464  start = reader->Line();
465 
466  next = start;
467  limit = next + len;
468 
469  return len;
470  }
471  return 0;
472  }
473 
481  int findToken( const std::string& aToken ) const;
482 
483  bool isStringTerminator( char cc ) const
484  {
485  if( !space_in_quoted_tokens && cc == ' ' )
486  return true;
487 
488  if( cc == stringDelimiter )
489  return true;
490 
491  return false;
492  }
493 
494  bool iOwnReaders;
495  const char* start;
496  const char* next;
497  const char* limit;
498  char dummy[1];
499 
500  typedef std::vector<LINE_READER*> READER_STACK;
501 
503 
506 
508 
515 
517 
518  int prevTok;
519  int curOffset;
520 
521  int curTok;
522  std::string curText;
523 
524  const KEYWORD* keywords;
525  unsigned keywordCount;
527 #endif // SWIG
528 };
529 
530 #endif // DSNLEXER_H_
int curOffset
offset within current line of the current token
Definition: dsnlexer.h:519
int CurLineNumber() const
Return the current line number within my LINE_READER.
Definition: dsnlexer.h:416
std::vector< LINE_READER * > READER_STACK
Definition: dsnlexer.h:500
int NeedNUMBER(const char *aExpectation)
Call NextTok() and then verifies that the token read is type DSN_NUMBER.
Definition: dsnlexer.cpp:395
bool commentsAreTokens
true if should return comments as tokens
Definition: dsnlexer.h:516
bool SetCommentsAreTokens(bool val)
Change the handling of comments.
Definition: dsnlexer.h:289
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:187
bool isStringTerminator(char cc) const
Definition: dsnlexer.h:483
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:386
char SetStringDelimiter(char aStringDelimiter)
Change the string delimiter from the default " to some other character and return the old value.
Definition: dsnlexer.h:258
const KEYWORD * keywords
table sorted by CMake for bsearch()
Definition: dsnlexer.h:524
virtual ~DSNLEXER()
Definition: dsnlexer.cpp:138
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:779
bool SetSpaceInQuotedTokens(bool val)
Change the setting controlling whether a space in a quoted string isa terminator.
Definition: dsnlexer.h:273
KEYWORD_MAP keyword_hash
fast, specialized "C string" hashtable
Definition: dsnlexer.h:526
const char * CurText() const
Return a pointer to the current token's text.
Definition: dsnlexer.h:391
void SetSpecctraMode(bool aMode)
Change the behavior of this lexer into or out of "specctra mode".
Definition: dsnlexer.cpp:148
bool space_in_quoted_tokens
blank spaces within quoted strings
Definition: dsnlexer.h:514
int findToken(const std::string &aToken) const
Take aToken string and looks up the string in the keywords table.
Definition: dsnlexer.cpp:228
wxString GetTokenString(int aTok) const
Return a quote wrapped wxString representation of a token value.
Definition: dsnlexer.cpp:302
const char * next
Definition: dsnlexer.h:496
int NeedSYMBOL()
Call NextTok() and then verifies that the token read in satisfies IsSymbol().
Definition: dsnlexer.cpp:377
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:199
void NeedLEFT()
Call NextTok() and then verifies that the token read in is a DSN_LEFT.
Definition: dsnlexer.cpp:361
const char * limit
Definition: dsnlexer.h:497
#define NULL
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:312
int CurTok() const
Return whatever NextTok() returned the last time it was called.
Definition: dsnlexer.h:230
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:399
const char * GetTokenText(int aTok) const
Return the C string representation of a DSN_T value.
Definition: dsnlexer.cpp:283
bool iOwnReaders
on readerStack, should I delete them?
Definition: dsnlexer.h:494
READER_STACK readerStack
all the LINE_READERs by pointer.
Definition: dsnlexer.h:502
LINE_READER * reader
Definition: dsnlexer.h:505
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:507
int prevTok
curTok from previous NextTok() call.
Definition: dsnlexer.h:518
int readLine()
Definition: dsnlexer.h:454
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:138
int CurOffset() const
Return the byte offset within the current line, using a 1 based index.
Definition: dsnlexer.h:444
const char * start
Definition: dsnlexer.h:495
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:164
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:345
std::string curText
the text of the current token
Definition: dsnlexer.h:522
int NextTok()
Return the next token found in the input file or DSN_EOF when reaching the end of file.
Definition: dsnlexer.cpp:508
void Expecting(int aTok) const
Throw an IO_ERROR exception with an input file specific error message.
Definition: dsnlexer.cpp:321
const char * CurLine() const
Return the current line of text from which the CurText() would return its token.
Definition: dsnlexer.h:424
void NeedRIGHT()
Call NextTok() and then verifies that the token read in is a DSN_RIGHT.
Definition: dsnlexer.cpp:369
unsigned keywordCount
count of keywords table
Definition: dsnlexer.h:525
int PrevTok() const
Return whatever NextTok() returned the 2nd to last time it was called.
Definition: dsnlexer.h:238
const wxString & CurSource() const
Return the current LINE_READER source.
Definition: dsnlexer.h:434
char dummy[1]
when there is no reader.
Definition: dsnlexer.h:498
int curTok
the current token obtained on last NextTok()
Definition: dsnlexer.h:521
void Unexpected(int aTok) const
Throw an IO_ERROR exception with an input file specific error message.
Definition: dsnlexer.cpp:337
Hold a keyword string and its unique integer token.
Definition: dsnlexer.h:39
void init()
Definition: dsnlexer.cpp:39
Implement a lexical analyzer for the SPECCTRA DSN file format.
Definition: dsnlexer.h:78
char stringDelimiter
Definition: dsnlexer.h:513
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:71
wxString FromUTF8() const
Return the current token text as a wxString, assuming that the input byte stream is UTF8 encoded.
Definition: dsnlexer.h:408
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:246
static const char * Syntax(int aTok)
Definition: dsnlexer.cpp:239