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-2015 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 <stdio.h>
29 #include <string>
30 #include <vector>
31 #include <hashtables.h>
32 
33 #include <richio.h>
34 
35 #ifndef SWIG
36 
40 struct KEYWORD
41 {
42  const char* name;
43  int token;
44 };
45 #endif
46 
47 // something like this macro can be used to help initialize a KEYWORD table.
48 // see SPECCTRA_DB::keywords[] as an example.
49 
50 //#define TOKDEF(x) { #x, T_##x }
51 
52 
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 
79 class DSNLEXER
80 {
81 #ifndef SWIG
82 protected:
83  bool iOwnReaders;
84  const char* start;
85  const char* next;
86  const char* limit;
87  char dummy[1];
88 
89  typedef std::vector<LINE_READER*> READER_STACK;
90 
91  READER_STACK readerStack;
93 
94  bool specctraMode;
95 
102 
104 
105  int prevTok;
106  int curOffset;
107 
108  int curTok;
109  std::string curText;
110 
111  const KEYWORD* keywords;
112  unsigned keywordCount;
114 
115  void init();
116 
117  int readLine()
118  {
119  if( reader )
120  {
121  reader->ReadLine();
122 
123  unsigned len = reader->Length();
124 
125  // start may have changed in ReadLine(), which can resize and
126  // relocate reader's line buffer.
127  start = reader->Line();
128 
129  next = start;
130  limit = next + len;
131 
132  return len;
133  }
134  return 0;
135  }
136 
145  int findToken( const std::string& aToken );
146 
147  bool isStringTerminator( char cc )
148  {
149  if( !space_in_quoted_tokens && cc==' ' )
150  return true;
151 
152  if( cc == stringDelimiter )
153  return true;
154 
155  return false;
156  }
157 
158 #endif
159 
160 public:
161 
173  DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
174  FILE* aFile, const wxString& aFileName );
175 
186  DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
187  const std::string& aSExpression, const wxString& aSource = wxEmptyString );
188 
197  DSNLEXER( const std::string& aSExpression, const wxString& aSource = wxEmptyString );
198 
213  DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
214  LINE_READER* aLineReader = NULL );
215 
216  virtual ~DSNLEXER();
217 
226  bool SyncLineReaderWith( DSNLEXER& aLexer );
227 
240  void SetSpecctraMode( bool aMode );
241 
252  void PushReader( LINE_READER* aLineReader );
253 
270 
271  // Some functions whose return value is best overloaded to return an enum
272  // in a derived class.
273  //-----<overload return values to tokens>------------------------------
274 
285  int NextTok();
286 
295  int NeedSYMBOL();
296 
305  int NeedSYMBOLorNUMBER();
306 
314  int NeedNUMBER( const char* aExpectation );
315 
320  int CurTok()
321  {
322  return curTok;
323  }
324 
329  int PrevTok()
330  {
331  return prevTok;
332  }
333 
334  //-----</overload return values to tokens>-----------------------------
335 
336 
344  char SetStringDelimiter( char aStringDelimiter )
345  {
346  int old = stringDelimiter;
347  if( specctraMode )
348  stringDelimiter = aStringDelimiter;
349  return old;
350  }
351 
358  bool SetSpaceInQuotedTokens( bool val )
359  {
360  bool old = space_in_quoted_tokens;
361  if( specctraMode )
362  space_in_quoted_tokens = val;
363  return old;
364  }
365 
372  bool SetCommentsAreTokens( bool val )
373  {
374  bool old = commentsAreTokens;
375  commentsAreTokens = val;
376  return old;
377  }
378 
390  wxArrayString* ReadCommentLines();
391 
398  static bool IsSymbol( int aTok );
399 
406  void Expecting( int aTok );
407 
415  void Expecting( const char* aTokenList );
416 
424  void Unexpected( int aTok );
425 
433  void Unexpected( const char* aToken );
434 
443  void Duplicate( int aTok );
444 
451  void NeedLEFT();
452 
459  void NeedRIGHT();
460 
465  const char* GetTokenText( int aTok );
466 
471  wxString GetTokenString( int aTok );
472 
473  static const char* Syntax( int aTok );
474 
479  const char* CurText()
480  {
481  return curText.c_str();
482  }
483 
488  const std::string& CurStr()
489  {
490  return curText;
491  }
492 
498  wxString FromUTF8()
499  {
500  return wxString::FromUTF8( curText.c_str() );
501  }
502 
508  {
509  return reader->LineNumber();
510  }
511 
517  const char* CurLine()
518  {
519  return (const char*)(*reader);
520  }
521 
528  const wxString& CurSource()
529  {
530  return reader->GetSource();
531  }
532 
538  int CurOffset()
539  {
540  return curOffset + 1;
541  }
542 };
543 
544 #endif // DSNLEXER_H_
int curOffset
offset within current line of the current token
Definition: dsnlexer.h:106
std::vector< LINE_READER * > READER_STACK
Definition: dsnlexer.h:89
int NeedNUMBER(const char *aExpectation)
Function NeedNUMBER calls NextTok() and then verifies that the token read is type DSN_NUMBER...
Definition: dsnlexer.cpp:427
bool commentsAreTokens
true if should return comments as tokens
Definition: dsnlexer.h:103
bool SetCommentsAreTokens(bool val)
Function SetCommentsAreTokens changes the handling of comments.
Definition: dsnlexer.h:372
Class LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived...
Definition: richio.h:81
void PushReader(LINE_READER *aLineReader)
Function PushReader manages a stack of LINE_READERs in order to handle nested file inclusion...
Definition: dsnlexer.cpp:192
virtual unsigned LineNumber() const
Function Line Number returns the line number of the last line read from this LINE_READER.
Definition: richio.h:159
int NeedSYMBOLorNUMBER()
Function NeedSYMBOLorNUMBER calls NextTok() and then verifies that the token read in satisfies bool I...
Definition: dsnlexer.cpp:418
const char * GetTokenText(int aTok)
Function GetTokenText returns the C string representation of a DSN_T value.
Definition: dsnlexer.cpp:315
char SetStringDelimiter(char aStringDelimiter)
Function SetStringDelimiter changes the string delimiter from the default " to some other character a...
Definition: dsnlexer.h:344
const KEYWORD * keywords
table sorted by CMake for bsearch()
Definition: dsnlexer.h:111
virtual ~DSNLEXER()
Definition: dsnlexer.cpp:143
int findToken(const std::string &aToken)
Function findToken takes aToken string and looks up the string in the keywords table.
Definition: dsnlexer.cpp:260
int PrevTok()
Function PrevTok returns whatever NextTok() returned the 2nd to last time it was called.
Definition: dsnlexer.h:329
void Unexpected(int aTok)
Function Unexpected throws an IO_ERROR exception with an input file specific error message...
Definition: dsnlexer.cpp:369
const std::string & CurStr()
Function CurStr returns a reference to current token in std::string form.
Definition: dsnlexer.h:488
const char * name
unique keyword.
Definition: dsnlexer.h:42
wxArrayString * ReadCommentLines()
Function ReadCommentLines checks the next sequence of tokens and reads them into a wxArrayString if t...
Definition: dsnlexer.cpp:811
bool SetSpaceInQuotedTokens(bool val)
Function SetSpaceInQuotedTokens changes the setting controlling whether a space in a quoted string is...
Definition: dsnlexer.h:358
KEYWORD_MAP keyword_hash
fast, specialized "C string" hashtable
Definition: dsnlexer.h:113
wxString FromUTF8()
Function FromUTF8 returns the current token text as a wxString, assuming that the input byte stream i...
Definition: dsnlexer.h:498
void SetSpecctraMode(bool aMode)
Function SetSpecctraMode changes the behavior of this lexer into or out of "specctra mode"...
Definition: dsnlexer.cpp:153
bool space_in_quoted_tokens
blank spaces within quoted strings
Definition: dsnlexer.h:101
const wxString & CurSource()
Function CurFilename returns the current LINE_READER source.
Definition: dsnlexer.h:528
const char * next
Definition: dsnlexer.h:85
int NeedSYMBOL()
Function NeedSYMBOL calls NextTok() and then verifies that the token read in satisfies bool IsSymbol(...
Definition: dsnlexer.cpp:409
LINE_READER * PopReader()
Function PopReader deletes the top most LINE_READER from an internal stack of LINE_READERs and in the...
Definition: dsnlexer.cpp:204
void NeedLEFT()
Function NeedLEFT calls NextTok() and then verifies that the token read in is a DSN_LEFT.
Definition: dsnlexer.cpp:393
const char * limit
Definition: dsnlexer.h:86
int CurTok()
Function CurTok returns whatever NextTok() returned the last time it was called.
Definition: dsnlexer.h:320
static bool IsSymbol(int aTok)
Function IsSymbol tests a token to see if it is a symbol.
Definition: dsnlexer.cpp:344
char * Line() const
Function Line returns a pointer to the last line that was read in.
Definition: richio.h:139
DSN_SYNTAX_T
Enum DSN_SYNTAX_T lists all the DSN lexer's tokens that are supported in lexing.
Definition: dsnlexer.h:58
int CurOffset()
Function CurOffset returns the byte offset within the current line, using a 1 based index...
Definition: dsnlexer.h:538
bool iOwnReaders
on readerStack, should I delete them?
Definition: dsnlexer.h:83
void Expecting(int aTok)
Function Expecting throws an IO_ERROR exception with an input file specific error message...
Definition: dsnlexer.cpp:353
READER_STACK readerStack
all the LINE_READERs by pointer.
Definition: dsnlexer.h:91
unsigned Length() const
Function Length returns the number of bytes in the last line read from this LINE_READER.
Definition: richio.h:168
LINE_READER * reader
no ownership. ownership is via readerStack, maybe, if iOwnReaders
Definition: dsnlexer.h:92
bool specctraMode
if true, then: 1) stringDelimiter can be changed 2) Kicad quoting protocol is not in effect 3) space_...
Definition: dsnlexer.h:94
const char * CurLine()
Function CurLine returns the current line of text, from which the CurText() would return its token...
Definition: dsnlexer.h:517
int prevTok
curTok from previous NextTok() call.
Definition: dsnlexer.h:105
int readLine()
Definition: dsnlexer.h:117
std::unordered_map< const char *, int, fnv_1a, iequal_to > KEYWORD_MAP
Type KEYWORD_MAP is a hashtable made of a const char* and an int.
Definition: hashtables.h:132
const char * start
Definition: dsnlexer.h:84
virtual char * ReadLine()=0
Function ReadLine reads a line of text into the buffer and increments the line number counter...
bool SyncLineReaderWith(DSNLEXER &aLexer)
Useable only for DSN lexers which share the same LINE_READER Synchronizes the pointers handling the d...
Definition: dsnlexer.cpp:169
void Duplicate(int aTok)
Function Duplicate throws an IO_ERROR exception with a message saying specifically that aTok is a dup...
Definition: dsnlexer.cpp:377
virtual const wxString & GetSource() const
Function GetSource returns the name of the source of the lines in an abstract sense.
Definition: richio.h:130
std::string curText
the text of the current token
Definition: dsnlexer.h:109
int NextTok()
Function NextTok returns the next token found in the input file or DSN_EOF when reaching the end of f...
Definition: dsnlexer.cpp:540
int CurLineNumber()
Function CurLineNumber returns the current line number within my LINE_READER.
Definition: dsnlexer.h:507
wxString GetTokenString(int aTok)
Function GetTokenString returns a quote wrapped wxString representation of a token value...
Definition: dsnlexer.cpp:334
void NeedRIGHT()
Function NeedRIGHT calls NextTok() and then verifies that the token read in is a DSN_RIGHT.
Definition: dsnlexer.cpp:401
unsigned keywordCount
count of keywords table
Definition: dsnlexer.h:112
char dummy[1]
when there is no reader.
Definition: dsnlexer.h:87
int curTok
the current token obtained on last NextTok()
Definition: dsnlexer.h:108
Struct KEYWORD holds a keyword string and its unique integer token.
Definition: dsnlexer.h:40
bool isStringTerminator(char cc)
Definition: dsnlexer.h:147
void init()
Definition: dsnlexer.cpp:44
const char * CurText()
Function CurText returns a pointer to the current token's text.
Definition: dsnlexer.h:479
Class DSNLEXER implements a lexical analyzer for the SPECCTRA DSN file format.
Definition: dsnlexer.h:79
char stringDelimiter
Definition: dsnlexer.h:100
DSNLEXER(const KEYWORD *aKeywordTable, unsigned aKeywordCount, FILE *aFile, const wxString &aFileName)
Constructor ( FILE*, const wxString& ) intializes a DSN lexer and prepares to read from aFile which i...
Definition: dsnlexer.cpp:76
int token
a zero based index into an array of KEYWORDs
Definition: dsnlexer.h:43
static const char * Syntax(int aTok)
Definition: dsnlexer.cpp:271