2021-03-21 15:37:02 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2021 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
|
|
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.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 "altium_rule_transformer.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
2021-03-21 16:35:20 +00:00
|
|
|
#include <wx/wxcrt.h> // for wxIsspace
|
2021-03-21 15:37:02 +00:00
|
|
|
|
|
|
|
const ALTIUM_RULE_TOKEN& ALTIUM_RULE_TOKENIZER::Next()
|
|
|
|
{
|
|
|
|
m_currentToken = m_nextToken;
|
|
|
|
|
|
|
|
// skip whitespaces
|
|
|
|
for( ; m_it != m_expr.end() && wxIsspace( curChar() ); nextChar() )
|
|
|
|
;
|
|
|
|
|
|
|
|
// check for end of string
|
|
|
|
if( m_it == m_expr.end() )
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, m_pos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
|
|
|
|
const size_t startPos = m_pos;
|
|
|
|
const wxUniChar curCh = curChar();
|
|
|
|
wxUniChar nextCh = nextChar();
|
|
|
|
|
|
|
|
if( curCh == '(' )
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::LPAR, startPos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == ')' )
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::RPAR, startPos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '*' )
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::MUL, startPos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '/' )
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::DIV, startPos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '=' )
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::EQUAL, startPos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '<' )
|
|
|
|
{
|
|
|
|
if( nextCh == '=' )
|
|
|
|
{
|
|
|
|
nextChar();
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::LESS_EQUAL, startPos };
|
|
|
|
}
|
|
|
|
else if( nextCh == '>' )
|
|
|
|
{
|
|
|
|
nextChar();
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::NOT_EQUAL, startPos };
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::LESS, startPos };
|
|
|
|
}
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '>' )
|
|
|
|
{
|
|
|
|
if( nextCh == '=' )
|
|
|
|
{
|
|
|
|
nextChar();
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::GREATER_EQUAL, startPos };
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::GREATER, startPos };
|
|
|
|
}
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '&' && nextCh == '&' )
|
|
|
|
{
|
|
|
|
nextChar();
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::LOW_AND, startPos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '|' && nextCh == '|' )
|
|
|
|
{
|
|
|
|
nextChar();
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::LOW_OR, startPos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '\'' )
|
|
|
|
{
|
|
|
|
wxString constString;
|
|
|
|
while( m_it != m_expr.end() && nextCh != '\'' )
|
|
|
|
{
|
|
|
|
constString += nextCh; // TODO: escaping?
|
|
|
|
nextCh = nextChar();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_it != m_expr.end() )
|
|
|
|
{
|
|
|
|
nextChar(); // TODO: exception if EOF reached?
|
|
|
|
}
|
|
|
|
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::CONST_STRING, startPos, constString };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '+' && !wxIsdigit( nextCh ) )
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::ADD, startPos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '-' && !wxIsdigit( nextCh ) )
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::SUB, startPos };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else if( curCh == '+' || curCh == '-' || wxIsdigit( curCh ) )
|
|
|
|
{
|
|
|
|
wxString digitString = curCh;
|
|
|
|
while( wxIsdigit( nextCh ) )
|
|
|
|
{
|
|
|
|
digitString += nextCh;
|
|
|
|
nextCh = nextChar();
|
|
|
|
}
|
|
|
|
|
|
|
|
long value;
|
|
|
|
digitString.ToLong( &value ); // TODO: check return value
|
|
|
|
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::CONST_INT, startPos, value };
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wxString identString = curCh;
|
|
|
|
while( wxIsalnum( nextCh ) )
|
|
|
|
{
|
|
|
|
identString += nextCh;
|
|
|
|
nextCh = nextChar();
|
|
|
|
}
|
|
|
|
|
2022-02-05 02:06:25 +00:00
|
|
|
if( identString.IsSameAs( wxT( "True" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::CONST_TRUE, startPos };
|
|
|
|
}
|
2022-02-05 02:06:25 +00:00
|
|
|
else if( identString.IsSameAs( wxT( "False" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::CONST_FALSE, startPos };
|
|
|
|
}
|
2022-02-05 02:06:25 +00:00
|
|
|
else if( identString.IsSameAs( wxT( "Div" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::INTEGRAL_DIV, startPos };
|
|
|
|
}
|
2022-02-05 02:06:25 +00:00
|
|
|
else if( identString.IsSameAs( wxT( "Mod" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::MOD, startPos };
|
|
|
|
}
|
2022-02-05 02:06:25 +00:00
|
|
|
else if( identString.IsSameAs( wxT( "And" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::AND, startPos };
|
|
|
|
}
|
2022-02-05 02:06:25 +00:00
|
|
|
else if( identString.IsSameAs( wxT( "Or" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::OR, startPos };
|
|
|
|
}
|
2022-02-05 02:06:25 +00:00
|
|
|
else if( identString.IsSameAs( wxT( "Xor" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::XOR, startPos };
|
|
|
|
}
|
2022-02-05 02:06:25 +00:00
|
|
|
else if( identString.IsSameAs( wxT( "Not" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::NOT, startPos };
|
|
|
|
}
|
2022-02-05 02:06:25 +00:00
|
|
|
else if( identString.IsSameAs( wxT( "Between" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::BETWEEN, startPos };
|
|
|
|
}
|
2022-02-05 02:06:25 +00:00
|
|
|
else if( identString.IsSameAs( wxT( "Like" ), false ) )
|
2021-03-21 15:37:02 +00:00
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::LIKE, startPos };
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::IDENT, startPos, identString };
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_currentToken;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const ALTIUM_RULE_TOKEN& ALTIUM_RULE_TOKENIZER::Peek() const
|
|
|
|
{
|
|
|
|
return m_nextToken;
|
|
|
|
}
|