Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
f8263c0e
Commit
f8263c0e
authored
Feb 14, 2011
by
Dick Hollenbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sweet parser work
parent
fe504483
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
549 additions
and
326 deletions
+549
-326
dsnlexer.cpp
common/dsnlexer.cpp
+14
-0
dsnlexer.h
include/dsnlexer.h
+9
-0
CMakeLists.txt
new/CMakeLists.txt
+1
-0
eeschema_part_sexpr_format_EN.odt
new/eeschema_part_sexpr_format_EN.odt
+0
-0
sch_lib.cpp
new/sch_lib.cpp
+3
-3
sch_part.cpp
new/sch_part.cpp
+22
-264
sch_part.h
new/sch_part.h
+69
-59
sch_sweet_parser.cpp
new/sch_sweet_parser.cpp
+336
-0
sch_sweet_parser.h
new/sch_sweet_parser.h
+95
-0
No files found.
common/dsnlexer.cpp
View file @
f8263c0e
...
@@ -351,6 +351,20 @@ int DSNLEXER::NeedSYMBOLorNUMBER() throw( IO_ERROR )
...
@@ -351,6 +351,20 @@ int DSNLEXER::NeedSYMBOLorNUMBER() throw( IO_ERROR )
}
}
int
DSNLEXER
::
NeedNUMBER
(
const
char
*
aExpectation
)
throw
(
IO_ERROR
)
{
int
tok
=
NextTok
();
if
(
tok
!=
DSN_NUMBER
)
{
wxString
errText
;
errText
.
Printf
(
_
(
"need a NUMBER for '%s'"
),
wxString
::
FromUTF8
(
aExpectation
).
GetData
()
);
THROW_PARSE_ERROR
(
errText
,
CurSource
(),
CurLine
(),
CurLineNumber
(),
CurOffset
()
);
}
return
tok
;
}
/**
/**
* Function isspace
* Function isspace
* strips the upper bits of the int to ensure the value passed to ::isspace() is
* strips the upper bits of the int to ensure the value passed to ::isspace() is
...
...
include/dsnlexer.h
View file @
f8263c0e
...
@@ -292,6 +292,15 @@ public:
...
@@ -292,6 +292,15 @@ public:
*/
*/
int
NeedSYMBOLorNUMBER
()
throw
(
IO_ERROR
);
int
NeedSYMBOLorNUMBER
()
throw
(
IO_ERROR
);
/**
* Function NeedNUMBER
* calls NextTok() and then verifies that the token read is type DSN_NUMBER.
* If not, and IO_ERROR is thrown using text from aExpectation.
* @return int - the actual token read in.
* @throw IO_ERROR, if the next token does not satisfy the above test
*/
int
NeedNUMBER
(
const
char
*
aExpectation
)
throw
(
IO_ERROR
);
/**
/**
* Function CurTok
* Function CurTok
* returns whatever NextTok() returned the last time it was called.
* returns whatever NextTok() returned the last time it was called.
...
...
new/CMakeLists.txt
View file @
f8263c0e
...
@@ -108,6 +108,7 @@ add_library( sweet SHARED
...
@@ -108,6 +108,7 @@ add_library( sweet SHARED
sch_lpid.cpp
sch_lpid.cpp
sch_dir_lib_source.cpp
sch_dir_lib_source.cpp
sch_part.cpp
sch_part.cpp
sch_sweet_parser.cpp
sweet_keywords.cpp
sweet_keywords.cpp
${
PROJECT_SOURCE_DIR
}
/common/richio.cpp
${
PROJECT_SOURCE_DIR
}
/common/richio.cpp
${
PROJECT_SOURCE_DIR
}
/common/dsnlexer.cpp
${
PROJECT_SOURCE_DIR
}
/common/dsnlexer.cpp
...
...
new/eeschema_part_sexpr_format_EN.odt
0 → 100644
View file @
f8263c0e
File added
new/sch_lib.cpp
View file @
f8263c0e
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
#include <sch_lib.h>
#include <sch_lib.h>
#include <sch_lpid.h>
#include <sch_lpid.h>
#include <sch_part.h>
#include <sch_part.h>
#include <s
weet_lex
er.h>
#include <s
ch_sweet_pars
er.h>
#include <sch_lib_table.h>
#include <sch_lib_table.h>
...
@@ -253,9 +253,9 @@ PART* LIB::LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) throw( IO_ERROR
...
@@ -253,9 +253,9 @@ PART* LIB::LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) throw( IO_ERROR
#endif
#endif
// @todo consider changing ReadPart to return a "source"
// @todo consider changing ReadPart to return a "source"
SWEET_
LEXER
sw
(
part
->
body
,
wxString
::
FromUTF8
(
aLPID
.
Format
().
c_str
()
)
);
SWEET_
PARSER
sp
(
part
->
body
,
wxString
::
FromUTF8
(
aLPID
.
Format
().
c_str
()
)
);
part
->
Parse
(
&
s
w
,
aLibTable
);
part
->
Parse
(
&
s
p
,
aLibTable
);
}
}
return
part
;
return
part
;
...
...
new/sch_part.cpp
View file @
f8263c0e
...
@@ -24,269 +24,12 @@
...
@@ -24,269 +24,12 @@
#include <wx/wx.h> // _()
#include <wx/wx.h> // _()
#include <sch_part.h>
#include <sch_part.h>
#include <s
weet_lex
er.h>
#include <s
ch_sweet_pars
er.h>
#include <sch_lpid.h>
#include <sch_lpid.h>
#include <sch_lib_table.h>
#include <sch_lib_table.h>
using
namespace
SCH
;
using
namespace
PR
;
// tokens, enum T for SWEET_LEXER
#define MAX_INHERITANCE_NESTING 6 // no problem going larger
//-----<temporary home for PART sub objects, move after stable>------------------
struct
XY
{};
struct
AT
{};
class
POLY_LINE
{
};
//-----</temporary home for PART sub objects, move after stable>-----------------
/**
* Class PART_PARSER
* is a localized/hidden PART Parser. You get here through the public interface
* PART::Parse(). Advantages of private class declaration in this situation:
* 1) keeps all the recursive parsing helper functions out of the main public PART
* header file and so should speed up compilation.
* 2) Allows use of cost-less Java like inline functions, since nobody knows about
* them but this source file. Most are only used once and called from one place.
* <p>
* All the functions in this class throw PARSE_ERROR. If SWEET_LEXER throws, it
* may be an IO_ERROR, propogated from here also. The throws() statements are left off
* to keep the noise level down.
*/
class
PART_PARSER
{
SWEET_LEXER
*
in
;
LIB_TABLE
*
libs
;
int
contains
;
// separate from PART::contains until done
// so we can see what we inherited from base PART
public
:
PART_PARSER
(
PART
*
aPart
,
SWEET_LEXER
*
aLexer
,
LIB_TABLE
*
aTable
)
:
in
(
aLexer
),
libs
(
aTable
),
contains
(
0
)
{
parsePart
(
aPart
);
}
void
parseXY
(
XY
*
me
)
{
}
void
parseAt
(
AT
*
me
)
{
}
void
parseExtends
(
PART
*
me
)
{
PART
*
base
;
int
offset
;
if
(
contains
&
PB
(
EXTENDS
)
)
in
->
Duplicate
(
T_extends
);
in
->
NeedSYMBOLorNUMBER
();
me
->
setExtends
(
new
LPID
()
);
offset
=
me
->
extends
->
Parse
(
in
->
CurText
()
);
if
(
offset
>
-
1
)
// -1 is success
THROW_PARSE_ERROR
(
_
(
"invalid extends LPID"
),
in
->
CurSource
(),
in
->
CurLine
(),
in
->
CurLineNumber
(),
in
->
CurOffset
()
+
offset
);
base
=
libs
->
LookupPart
(
*
me
->
extends
,
me
->
Owner
()
);
// we could be going in circles here, recursively, or too deep, set limits
// and disallow extending from self (even indirectly)
int
extendsDepth
=
0
;
for
(
PART
*
ancestor
=
base
;
ancestor
&&
extendsDepth
<
MAX_INHERITANCE_NESTING
;
++
extendsDepth
,
ancestor
=
ancestor
->
base
)
{
if
(
ancestor
==
me
)
{
THROW_PARSE_ERROR
(
_
(
"'extends' may not have self as any ancestor"
),
in
->
CurSource
(),
in
->
CurLine
(),
in
->
CurLineNumber
(),
in
->
CurOffset
()
);
}
}
if
(
extendsDepth
==
MAX_INHERITANCE_NESTING
)
{
THROW_PARSE_ERROR
(
_
(
"max allowed extends depth exceeded"
),
in
->
CurSource
(),
in
->
CurLine
(),
in
->
CurLineNumber
(),
in
->
CurOffset
()
);
}
me
->
inherit
(
*
base
);
using
namespace
SCH
;
me
->
base
=
base
;
contains
|=
PB
(
EXTENDS
);
}
/// @param me = ja mir, the object getting stuffed, from its perspective
void
parsePart
(
PART
*
me
)
{
T
tok
;
#if 0
// Be flexible regarding the starting point of the stream.
// Caller may not have read the first two tokens out of the
// stream: T_LEFT and T_part, so ignore them if seen here.
// The 1st two tokens T_LEFT and T_part are then optional in the grammar.
if( (tok = in->NextTok() ) == T_LEFT )
{
if( ( tok = in->NextTok() ) != T_part )
in->Expecting( T_part );
}
#else
// "( part" are not optional
in
->
NeedLEFT
();
if
(
(
tok
=
in
->
NextTok
()
)
!=
T_part
)
in
->
Expecting
(
T_part
);
#endif
in
->
NeedSYMBOLorNUMBER
();
// read in part NAME_HINT, and toss
tok
=
in
->
NextTok
();
// extends must be _first_ thing, if it is present at all, after NAME_HINT
if
(
tok
==
T_extends
)
{
parseExtends
(
me
);
tok
=
in
->
NextTok
();
}
for
(
;
tok
!=
T_RIGHT
;
tok
=
in
->
NextTok
()
)
{
if
(
tok
==
T_EOF
)
in
->
Unexpected
(
T_EOF
);
if
(
tok
==
T_LEFT
)
tok
=
in
->
NextTok
();
switch
(
tok
)
{
default
:
// describe what we expect at this level
in
->
Expecting
(
"anchor|value|footprint|model|keywords|alternates
\n
"
"|property
\n
"
" |property_del
\n
"
"|pin
\n
"
" |pin_merge|pin_swap|pin_renum|pin_rename|route_pin_swap
\n
"
"|polyline|line|rectangle|circle|arc|bezier|text"
);
break
;
case
T_anchor
:
if
(
contains
&
PB
(
ANCHOR
)
)
in
->
Duplicate
(
tok
);
contains
|=
PB
(
ANCHOR
);
break
;
case
T_line
:
break
;
/*
case T_value:
if( contains & PB(VALUE) )
in->Duplicate( tok );
contains |= PB(VALUE);
in->NeedSYMBOLorNUMBER();
// me->value = in->CurText();
in->NeedRIGHT();
break;
case T_footprint:
break;
case T_model:
break;
case T_keywords:
break;
case T_alternates:
break;
case T_property:
break;
case T_property_del:
break;
case T_pin:
break;
case T_pin_merge:
break;
case T_pin_swap:
break;
case T_pin_renum:
break;
case T_pin_rename:
break;
case T_route_pin_swap:
break;
case T_polyline:
break;
case T_rectangle:
break;
case T_circle:
break;
case T_arc:
break;
case T_bezier:
break;
case T_text:
break;
*/
// Not sure about reference in a PART, comes in at COMPONENT object.
// It is maybe just a hint here or a prefix.
case
T_reference
:
if
(
contains
&
PB
(
REFERENCE
)
)
in
->
Duplicate
(
tok
);
contains
|=
PB
(
REFERENCE
);
break
;
}
}
contains
|=
PB
(
PARSED
);
me
->
contains
|=
contains
;
}
};
PART
::
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartNameAndRev
)
:
PART
::
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartNameAndRev
)
:
...
@@ -302,9 +45,26 @@ PART::PART( LIB* aOwner, const STRING& aPartNameAndRev ) :
...
@@ -302,9 +45,26 @@ PART::PART( LIB* aOwner, const STRING& aPartNameAndRev ) :
}
}
PART
::~
PART
()
void
PART
::
clear
()
{
{
if
(
extends
)
{
delete
extends
;
delete
extends
;
extends
=
0
;
}
for
(
GRAPHICS
::
iterator
it
=
graphics
.
begin
();
it
!=
graphics
.
end
();
++
it
)
delete
*
it
;
graphics
.
clear
();
// @todo delete all properties, pins, and graphics
}
PART
::~
PART
()
{
clear
();
}
}
...
@@ -339,14 +99,12 @@ PART& PART::operator=( const PART& other )
...
@@ -339,14 +99,12 @@ PART& PART::operator=( const PART& other )
}
}
void
PART
::
Parse
(
SWEET_
LEXER
*
aLexer
,
LIB_TABLE
*
aTable
)
throw
(
IO
_ERROR
)
void
PART
::
Parse
(
SWEET_
PARSER
*
aParser
,
LIB_TABLE
*
aTable
)
throw
(
IO_ERROR
,
PARSE
_ERROR
)
{
{
PART_PARSER
(
this
,
aLexer
,
aTable
);
aParser
->
Parse
(
this
,
aTable
);
}
}
#if 0 && defined(DEBUG)
#if 0 && defined(DEBUG)
int main( int argc, char** argv )
int main( int argc, char** argv )
...
...
new/sch_part.h
View file @
f8263c0e
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef SCH_PART_H_
#ifndef SCH_PART_H_
#define SCH_PART_H_
#define SCH_PART_H_
#include <sch_lib.h>
#include <sch_lib.h>
class
SWEET_LEXER
;
class
PART_PARSER
;
//-----<temporary home for PART sub objects, move after stable>------------------
typedef
wxPoint
POINT
;
#include <wx/gdicmn.h>
#include <vector>
namespace
SCH
{
namespace
SCH
{
class
LPID
;
class
PART
;
class
SWEET_PARSER
;
/**
* Enum PartBit
class
BASE_GRAPHIC
* is a set of bit positions that can be used to create flag bits within
* PART::contains to indicate what state the PART is in and what it contains, i.e.
* whether the PART has been parsed, and what the PART contains, categorically.
*/
enum
PartBit
{
{
PARSED
,
///< have parsed this part already, otherwise 'body' text must be parsed
friend
class
PART
;
EXTENDS
,
///< saw "extends" keyword, inheriting from another PART
friend
class
SWEET_PARSER
;
VALUE
,
ANCHOR
,
protected
:
REFERENCE
,
PART
*
owner
;
FOOTPRINT
,
DATASHEET
,
public
:
MODEL
,
BASE_GRAPHIC
(
PART
*
aOwner
)
:
KEYWORDS
,
owner
(
aOwner
)
{}
virtual
~
BASE_GRAPHIC
()
{}
};
};
/// Function PB
class
POLY_LINE
:
BASE_GRAPHIC
/// is a PartBit shifter for PART::contains field.
static
inline
const
int
PB
(
PartBit
oneBitOnly
)
{
{
return
(
1
<<
oneBitOnly
);
friend
class
PART
;
}
friend
class
SWEET_PARSER
;
protected
:
double
width
;
std
::
vector
<
POINT
>
pts
;
public
:
POLY_LINE
(
PART
*
aOwner
)
:
BASE_GRAPHIC
(
aOwner
)
{}
};
};
//-----</temporary home for PART sub objects, move after stable>-----------------
namespace
SCH
{
typedef
std
::
vector
<
BASE_GRAPHIC
*
>
GRAPHICS
;
class
LPID
;
class
SWEET_PARSER
;
/**
/**
...
@@ -75,13 +77,20 @@ static inline const int PB( PartBit oneBitOnly )
...
@@ -75,13 +77,20 @@ static inline const int PB( PartBit oneBitOnly )
class
PART
class
PART
{
{
friend
class
LIB
;
// is the owner of all PARTS, afterall
friend
class
LIB
;
// is the owner of all PARTS, afterall
friend
class
::
PAR
T_PARSER
;
friend
class
SWEE
T_PARSER
;
protected
:
// not likely to have C++ descendants, but protected none-the-less.
protected
:
// not likely to have C++ descendants, but protected none-the-less.
/// a protected constructor, only a LIB can instantiate a PART.
/// a protected constructor, only a LIB can instantiate a PART.
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartNameAndRev
);
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartNameAndRev
);
/**
* Function destroy
* clears out this object, deleting all graphics, all fields, all properties,
* etc.
*/
void
clear
();
/**
/**
* Function inherit
* Function inherit
* is a specialized assignment function that copies a specific subset, enough
* is a specialized assignment function that copies a specific subset, enough
...
@@ -89,6 +98,7 @@ protected: // not likely to have C++ descendants, but protected none-the-le
...
@@ -89,6 +98,7 @@ protected: // not likely to have C++ descendants, but protected none-the-le
*/
*/
void
inherit
(
const
PART
&
aBasePart
);
void
inherit
(
const
PART
&
aBasePart
);
POINT
anchor
;
//PART( LIB* aOwner );
//PART( LIB* aOwner );
...
@@ -115,7 +125,7 @@ protected: // not likely to have C++ descendants, but protected none-the-le
...
@@ -115,7 +125,7 @@ protected: // not likely to have C++ descendants, but protected none-the-le
//PROPERTIES properties;
//PROPERTIES properties;
/// A drawing list for graphics
/// A drawing list for graphics
//DRAWINGS drawing
s;
GRAPHICS
graphic
s
;
/// A pin list
/// A pin list
//PINS pins;
//PINS pins;
...
@@ -127,7 +137,7 @@ protected: // not likely to have C++ descendants, but protected none-the-le
...
@@ -127,7 +137,7 @@ protected: // not likely to have C++ descendants, but protected none-the-le
public
:
public
:
~
PART
();
virtual
~
PART
();
PART
&
operator
=
(
const
PART
&
other
);
PART
&
operator
=
(
const
PART
&
other
);
...
@@ -143,12 +153,12 @@ public:
...
@@ -143,12 +153,12 @@ public:
* by the normal fields of this class. Parse is expected to call Inherit()
* by the normal fields of this class. Parse is expected to call Inherit()
* if this part extends any other.
* if this part extends any other.
*
*
* @param a
Lexer is an instance of SWEET_LEX
ER, rewound at the first line.
* @param a
Parser is an instance of SWEET_PARS
ER, rewound at the first line.
*
*
* @param aLibTable is the LIB_TABLE "view" that is in effect for inheritance,
* @param aLibTable is the LIB_TABLE "view" that is in effect for inheritance,
* and comes from the big containing SCHEMATIC object.
* and comes from the big containing SCHEMATIC object.
*/
*/
void
Parse
(
SWEET_
LEXER
*
aLexer
,
LIB_TABLE
*
aLibTable
)
throw
(
IO
_ERROR
);
void
Parse
(
SWEET_
PARSER
*
aParser
,
LIB_TABLE
*
aLibTable
)
throw
(
IO_ERROR
,
PARSE
_ERROR
);
/*
/*
void SetBody( const STR_UTF& aSExpression )
void SetBody( const STR_UTF& aSExpression )
...
...
new/sch_sweet_parser.cpp
0 → 100644
View file @
f8263c0e
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <sch_sweet_parser.h>
#include <sch_part.h>
#include <sch_lib_table.h>
#include <sch_lpid.h>
using
namespace
SCH
;
using
namespace
PR
;
#define MAX_INHERITANCE_NESTING 6 // no problem going larger
/**
* Function log2int
* converts a logical coordinate to an internal coordinate. Logical coordinates
* are defined as the standard distance between pins being equal to one.
* Internal coordinates are 1000 times that.
*/
static
inline
int
log2int
(
double
aCoord
)
{
return
int
(
aCoord
*
1000
);
}
static
inline
int
internal
(
const
STRING
&
aCoord
)
{
return
log2int
(
strtod
(
aCoord
.
c_str
(),
NULL
)
);
}
/**
* Enum PartBit
* is a set of bit positions that can be used to create flag bits within
* PART::contains to indicate what state the PART is in and what it contains, i.e.
* whether the PART has been parsed, and what the PART contains, categorically.
*/
enum
PartBit
{
PARSED
,
///< have parsed this part already, otherwise 'body' text must be parsed
EXTENDS
,
///< saw "extends" keyword, inheriting from another PART
VALUE
,
ANCHOR
,
REFERENCE
,
FOOTPRINT
,
DATASHEET
,
MODEL
,
KEYWORDS
,
};
/// Function PB
/// is a PartBit shifter for PART::contains field.
static
inline
const
int
PB
(
PartBit
oneBitOnly
)
{
return
(
1
<<
oneBitOnly
);
}
void
SWEET_PARSER
::
parseExtends
(
PART
*
me
)
{
PART
*
base
;
int
offset
;
if
(
contains
&
PB
(
EXTENDS
)
)
Duplicate
(
T_extends
);
NeedSYMBOLorNUMBER
();
me
->
setExtends
(
new
LPID
()
);
offset
=
me
->
extends
->
Parse
(
CurText
()
);
if
(
offset
>
-
1
)
// -1 is success
THROW_PARSE_ERROR
(
_
(
"invalid extends LPID"
),
CurSource
(),
CurLine
(),
CurLineNumber
(),
CurOffset
()
+
offset
);
base
=
libs
->
LookupPart
(
*
me
->
extends
,
me
->
Owner
()
);
// we could be going in circles here, recursively, or too deep, set limits
// and disallow extending from self (even indirectly)
int
extendsDepth
=
0
;
for
(
PART
*
ancestor
=
base
;
ancestor
&&
extendsDepth
<
MAX_INHERITANCE_NESTING
;
++
extendsDepth
,
ancestor
=
ancestor
->
base
)
{
if
(
ancestor
==
me
)
{
THROW_PARSE_ERROR
(
_
(
"'extends' may not have self as any ancestor"
),
CurSource
(),
CurLine
(),
CurLineNumber
(),
CurOffset
()
);
}
}
if
(
extendsDepth
==
MAX_INHERITANCE_NESTING
)
{
THROW_PARSE_ERROR
(
_
(
"max allowed extends depth exceeded"
),
CurSource
(),
CurLine
(),
CurLineNumber
(),
CurOffset
()
);
}
me
->
inherit
(
*
base
);
me
->
base
=
base
;
contains
|=
PB
(
EXTENDS
);
}
void
SWEET_PARSER
::
Parse
(
PART
*
me
,
LIB_TABLE
*
aTable
)
throw
(
IO_ERROR
,
PARSE_ERROR
)
{
T
tok
;
libs
=
aTable
;
// empty everything out, could be re-parsing this object and it may not be empty.
me
->
clear
();
#if 0
// Be flexible regarding the starting point of the stream.
// Caller may not have read the first two tokens out of the
// stream: T_LEFT and T_part, so ignore them if seen here.
// The 1st two tokens T_LEFT and T_part are then optional in the grammar.
if( (tok = NextTok() ) == T_LEFT )
{
if( ( tok = NextTok() ) != T_part )
Expecting( T_part );
}
#else
// "( part" are not optional
NeedLEFT
();
if
(
(
tok
=
NextTok
()
)
!=
T_part
)
Expecting
(
T_part
);
#endif
NeedSYMBOLorNUMBER
();
// read in part NAME_HINT, and toss
tok
=
NextTok
();
// extends must be _first_ thing, if it is present at all, after NAME_HINT
if
(
tok
==
T_extends
)
{
parseExtends
(
me
);
tok
=
NextTok
();
}
for
(
;
tok
!=
T_RIGHT
;
tok
=
NextTok
()
)
{
if
(
tok
==
T_EOF
)
Unexpected
(
T_EOF
);
if
(
tok
==
T_LEFT
)
tok
=
NextTok
();
switch
(
tok
)
{
default
:
// describe what we expect at this level
Expecting
(
"anchor|value|footprint|model|keywords|alternates
\n
"
"|property
\n
"
" |property_del
\n
"
"|pin
\n
"
" |pin_merge|pin_swap|pin_renum|pin_rename|route_pin_swap
\n
"
"|polyline|line|rectangle|circle|arc|bezier|text"
);
break
;
case
T_anchor
:
if
(
contains
&
PB
(
ANCHOR
)
)
Duplicate
(
tok
);
NeedNUMBER
(
"anchor x"
);
me
->
anchor
.
x
=
internal
(
CurText
()
);
NeedNUMBER
(
"anchor y"
);
me
->
anchor
.
y
=
internal
(
CurText
()
);
contains
|=
PB
(
ANCHOR
);
break
;
case
T_line
:
POLY_LINE
*
pl
;
pl
=
new
POLY_LINE
(
me
);
me
->
graphics
.
push_back
(
pl
);
parsePolyLine
(
pl
);
break
;
/*
case T_value:
if( contains & PB(VALUE) )
Duplicate( tok );
contains |= PB(VALUE);
NeedSYMBOLorNUMBER();
// me->value = CurText();
NeedRIGHT();
break;
case T_footprint:
break;
case T_model:
break;
case T_keywords:
break;
case T_alternates:
break;
case T_property:
break;
case T_property_del:
break;
case T_pin:
break;
case T_pin_merge:
break;
case T_pin_swap:
break;
case T_pin_renum:
break;
case T_pin_rename:
break;
case T_route_pin_swap:
break;
case T_polyline:
break;
case T_rectangle:
break;
case T_circle:
break;
case T_arc:
break;
case T_bezier:
break;
case T_text:
break;
*/
// Not sure about reference in a PART, comes in at COMPONENT object.
// It is maybe just a hint here or a prefix.
case
T_reference
:
if
(
contains
&
PB
(
REFERENCE
)
)
Duplicate
(
tok
);
contains
|=
PB
(
REFERENCE
);
break
;
}
}
contains
|=
PB
(
PARSED
);
me
->
contains
|=
contains
;
}
void
SWEET_PARSER
::
parsePolyLine
(
POLY_LINE
*
me
)
{
T
tok
;
int
count
;
NeedLEFT
();
while
(
(
tok
=
NextTok
()
)
!=
T_RIGHT
)
{
NeedLEFT
();
tok
=
NextTok
();
switch
(
tok
)
{
case
T_line_width
:
NeedNUMBER
(
"line_width"
);
me
->
width
=
strtod
(
CurText
(),
NULL
);
break
;
case
T_pts
:
for
(
count
=
0
;
(
tok
=
NextTok
()
)
!=
T_RIGHT
;
++
count
)
{
if
(
tok
!=
T_LEFT
)
Expecting
(
T_LEFT
);
tok
=
NeedSYMBOL
();
if
(
tok
!=
T_xy
)
Expecting
(
T_xy
);
/* @todo resume here, its late
NeedNUMBER();
*/
}
break
;
case
T_fill
:
break
;
default
:
Expecting
(
"pts|line_width|fill"
);
}
}
}
new/sch_sweet_parser.h
0 → 100644
View file @
f8263c0e
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef SCH_SWEET_PARSER_H_
#define SCH_SWEET_PARSER_H_
#include <utf8.h>
#include <sweet_lexer.h>
namespace
SCH
{
class
LIB_TABLE
;
class
PART
;
class
POLY_LINE
;
/**
* Class SWEET_PARSER
* scans a Sweet string as input and stuffs a PART.
* <p>
* Most functions in this class throw IO_ERROR and PARSE_ERROR. The IO_ERROR can
* happen if there is difficulty reading the input stream.
*/
class
SWEET_PARSER
:
public
SWEET_LEXER
{
LIB_TABLE
*
libs
;
int
contains
;
// separate from PART::contains until done
// so we can see what we inherited from base PART
// all these private functions rely on libs having been set via the public API, Parse( PART*)
void
parseExtends
(
PART
*
me
);
void
parsePolyLine
(
POLY_LINE
*
me
);
public
:
/**
* Constructor SWEET_PARSER
* takes aSweet string and gets ready to parse it.
* @param aSweet is the full description of a PART.
* @param aSource is used in error reporting and describes where the Sweet
* string came from in any appropriate way.
*/
SWEET_PARSER
(
const
STRING
&
aSweet
,
const
wxString
&
aSource
=
wxEmptyString
)
:
SWEET_LEXER
(
aSweet
,
aSource
),
libs
(
0
),
contains
(
0
)
{
}
SWEET_PARSER
(
LINE_READER
*
aLineReader
)
:
SWEET_LEXER
(
aLineReader
),
libs
(
0
),
contains
(
0
)
{
}
/**
* Function Parse
* stuffs @a aPart with data from this SWEET_LEXER, which has its own
* sweet string source.
* @param aPart is what is to be stuffed.
* @param aTable is the view of the LIBs in play.
*/
void
Parse
(
PART
*
aPart
,
LIB_TABLE
*
aTable
)
throw
(
IO_ERROR
,
PARSE_ERROR
);
};
}
// namespace SCH
#endif // SCH_SWEET_PARSER_H_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment