altium: introduce tokenizer for query language
Based on this tokenizer, a LL1 parser will be built in the future.
This commit is contained in:
parent
b25103ccf1
commit
68f3d09ac1
|
@ -5,8 +5,9 @@ set( ALTIUM2PCBNEW_SRCS
|
|||
altium_circuit_maker_plugin.cpp
|
||||
altium_circuit_studio_plugin.cpp
|
||||
altium_designer_plugin.cpp
|
||||
altium_pcb.cpp
|
||||
altium_parser_pcb.cpp
|
||||
altium_pcb.cpp
|
||||
altium_rule_transformer.cpp
|
||||
)
|
||||
|
||||
add_library( altium2pcbnew STATIC ${ALTIUM2PCBNEW_SRCS} )
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
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 == '\'' )
|
||||
{
|
||||
std::cout << "start const string" << std::endl;
|
||||
wxString constString;
|
||||
while( m_it != m_expr.end() && nextCh != '\'' )
|
||||
{
|
||||
constString += nextCh; // TODO: escaping?
|
||||
nextCh = nextChar();
|
||||
}
|
||||
std::cout << "end const string: " << constString << std::endl;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
if( identString.IsSameAs( "True", false ) )
|
||||
{
|
||||
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::CONST_TRUE, startPos };
|
||||
}
|
||||
else if( identString.IsSameAs( "False", false ) )
|
||||
{
|
||||
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::CONST_FALSE, startPos };
|
||||
}
|
||||
else if( identString.IsSameAs( "Div", false ) )
|
||||
{
|
||||
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::INTEGRAL_DIV, startPos };
|
||||
}
|
||||
else if( identString.IsSameAs( "Mod", false ) )
|
||||
{
|
||||
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::MOD, startPos };
|
||||
}
|
||||
else if( identString.IsSameAs( "And", false ) )
|
||||
{
|
||||
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::AND, startPos };
|
||||
}
|
||||
else if( identString.IsSameAs( "Or", false ) )
|
||||
{
|
||||
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::OR, startPos };
|
||||
}
|
||||
else if( identString.IsSameAs( "Xor", false ) )
|
||||
{
|
||||
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::XOR, startPos };
|
||||
}
|
||||
else if( identString.IsSameAs( "Not", false ) )
|
||||
{
|
||||
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::NOT, startPos };
|
||||
}
|
||||
else if( identString.IsSameAs( "Between", false ) )
|
||||
{
|
||||
m_nextToken = { ALTIUM_RULE_TOKEN_KIND::BETWEEN, startPos };
|
||||
}
|
||||
else if( identString.IsSameAs( "Like", false ) )
|
||||
{
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef ALTIUM_RULE_TRANSFORMER_H
|
||||
#define ALTIUM_RULE_TRANSFORMER_H
|
||||
|
||||
#include "wx/string.h"
|
||||
|
||||
// See: https://www.altium.com/documentation/altium-designer/query-operators-ad
|
||||
enum class ALTIUM_RULE_TOKEN_KIND
|
||||
{
|
||||
UNKNOWN,
|
||||
|
||||
IDENT,
|
||||
CONST_INT,
|
||||
CONST_FLOAT,
|
||||
CONST_STRING,
|
||||
|
||||
CONST_TRUE,
|
||||
CONST_FALSE,
|
||||
|
||||
LPAR,
|
||||
RPAR,
|
||||
|
||||
ADD,
|
||||
SUB,
|
||||
MUL,
|
||||
DIV,
|
||||
INTEGRAL_DIV,
|
||||
MOD,
|
||||
|
||||
AND,
|
||||
LOW_AND,
|
||||
OR,
|
||||
LOW_OR,
|
||||
XOR,
|
||||
NOT,
|
||||
|
||||
LESS,
|
||||
LESS_EQUAL,
|
||||
GREATER_EQUAL,
|
||||
GREATER,
|
||||
NOT_EQUAL,
|
||||
EQUAL,
|
||||
|
||||
BETWEEN,
|
||||
LIKE,
|
||||
|
||||
END_OF_EXPR
|
||||
};
|
||||
|
||||
struct ALTIUM_RULE_TOKEN
|
||||
{
|
||||
ALTIUM_RULE_TOKEN_KIND kind;
|
||||
size_t pos;
|
||||
|
||||
long iValue;
|
||||
double fValue;
|
||||
wxString sValue;
|
||||
|
||||
ALTIUM_RULE_TOKEN() :
|
||||
kind( ALTIUM_RULE_TOKEN_KIND::UNKNOWN ), pos( 0 ), iValue( 0 ), fValue( 0. ),
|
||||
sValue( "" )
|
||||
{
|
||||
}
|
||||
|
||||
ALTIUM_RULE_TOKEN( ALTIUM_RULE_TOKEN_KIND aKind, size_t aPos ) :
|
||||
kind( aKind ), pos( aPos ), iValue( 0 ), fValue( 0. ), sValue( "" )
|
||||
{
|
||||
}
|
||||
|
||||
ALTIUM_RULE_TOKEN( ALTIUM_RULE_TOKEN_KIND aKind, size_t aPos, long aValue ) :
|
||||
kind( aKind ), pos( aPos ), iValue( aValue ), fValue( 0. ), sValue( "" )
|
||||
{
|
||||
}
|
||||
|
||||
ALTIUM_RULE_TOKEN( ALTIUM_RULE_TOKEN_KIND aKind, size_t aPos, float aValue ) :
|
||||
kind( aKind ), pos( aPos ), iValue( 0 ), fValue( aValue ), sValue( "" )
|
||||
{
|
||||
}
|
||||
|
||||
ALTIUM_RULE_TOKEN( ALTIUM_RULE_TOKEN_KIND aKind, size_t aPos, wxString aValue ) :
|
||||
kind( aKind ), pos( aPos ), iValue( 0 ), fValue( 0. ), sValue( aValue )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class ALTIUM_RULE_TOKENIZER
|
||||
{
|
||||
public:
|
||||
ALTIUM_RULE_TOKENIZER( const wxString& aExpr ) : m_pos( 0 ), m_expr( aExpr )
|
||||
{
|
||||
m_it = m_expr.begin();
|
||||
Next();
|
||||
}
|
||||
|
||||
const ALTIUM_RULE_TOKEN& Next();
|
||||
|
||||
const ALTIUM_RULE_TOKEN& Peek() const;
|
||||
|
||||
private:
|
||||
wxUniChar curChar() { return *m_it; }
|
||||
|
||||
wxUniChar nextChar()
|
||||
{
|
||||
if( m_it != m_expr.end() )
|
||||
{
|
||||
m_pos++;
|
||||
}
|
||||
return *( ++m_it );
|
||||
}
|
||||
|
||||
size_t m_pos;
|
||||
const wxString m_expr;
|
||||
wxString::const_iterator m_it;
|
||||
|
||||
ALTIUM_RULE_TOKEN m_currentToken;
|
||||
ALTIUM_RULE_TOKEN m_nextToken;
|
||||
};
|
||||
|
||||
|
||||
#endif //ALTIUM_RULE_TRANSFORMER_H
|
|
@ -41,6 +41,8 @@ set( QA_PCBNEW_SRCS
|
|||
drc/test_drc_courtyard_invalid.cpp
|
||||
drc/test_drc_courtyard_overlap.cpp
|
||||
|
||||
plugins/altium/test_altium_rule_transformer.cpp
|
||||
|
||||
group_saveload.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 KiCad Developers, see CHANGELOG.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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file test_altium_rule_transformer.cpp
|
||||
* Test suite for #ALTIUM_RULE_TOKENIZER
|
||||
*/
|
||||
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
|
||||
#include <pcbnew/plugins/altium/altium_rule_transformer.h>
|
||||
|
||||
struct ALTIUM_RULE_TRANSFORMER_FIXTURE
|
||||
{
|
||||
ALTIUM_RULE_TRANSFORMER_FIXTURE() {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Declares the struct as the Boost test fixture.
|
||||
*/
|
||||
BOOST_FIXTURE_TEST_SUITE( AltiumRuleTransformer, ALTIUM_RULE_TRANSFORMER_FIXTURE )
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AltiumRuleTokenizerEmptyInput )
|
||||
{
|
||||
ALTIUM_RULE_TOKENIZER tokenizer( "" );
|
||||
|
||||
const ALTIUM_RULE_TOKEN& peek = tokenizer.Peek();
|
||||
BOOST_CHECK( ( ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR == peek.kind ) );
|
||||
BOOST_CHECK_EQUAL( 0, peek.pos );
|
||||
|
||||
const ALTIUM_RULE_TOKEN& next = tokenizer.Next();
|
||||
BOOST_CHECK( ( ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR == next.kind ) );
|
||||
BOOST_CHECK_EQUAL( 0, next.pos );
|
||||
|
||||
const ALTIUM_RULE_TOKEN& peek2 = tokenizer.Peek();
|
||||
BOOST_CHECK( ( ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR == peek2.kind ) );
|
||||
BOOST_CHECK_EQUAL( 0, peek2.pos );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AltiumRuleTokenizerOnlySpaces )
|
||||
{
|
||||
ALTIUM_RULE_TOKENIZER tokenizer( " " );
|
||||
|
||||
const ALTIUM_RULE_TOKEN& peek = tokenizer.Peek();
|
||||
BOOST_CHECK( ( ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR == peek.kind ) );
|
||||
BOOST_CHECK_EQUAL( 3, peek.pos );
|
||||
|
||||
const ALTIUM_RULE_TOKEN& next = tokenizer.Next();
|
||||
BOOST_CHECK( ( ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR == next.kind ) );
|
||||
BOOST_CHECK_EQUAL( 3, next.pos );
|
||||
|
||||
const ALTIUM_RULE_TOKEN& peek2 = tokenizer.Peek();
|
||||
BOOST_CHECK( ( ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR == peek2.kind ) );
|
||||
BOOST_CHECK_EQUAL( 3, peek2.pos );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( AltiumRuleTokenizerSingleCharIdentifier )
|
||||
{
|
||||
ALTIUM_RULE_TOKENIZER tokenizer( "a" );
|
||||
|
||||
const ALTIUM_RULE_TOKEN& next = tokenizer.Next();
|
||||
BOOST_CHECK( ( ALTIUM_RULE_TOKEN_KIND::IDENT == next.kind ) );
|
||||
BOOST_CHECK_EQUAL( 0, next.pos );
|
||||
BOOST_CHECK_EQUAL( "a", next.sValue );
|
||||
|
||||
const ALTIUM_RULE_TOKEN& peek = tokenizer.Peek();
|
||||
BOOST_CHECK( ( ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR == peek.kind ) );
|
||||
BOOST_CHECK_EQUAL( 1, peek.pos );
|
||||
|
||||
const ALTIUM_RULE_TOKEN& next2 = tokenizer.Next();
|
||||
BOOST_CHECK( ( ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR == next2.kind ) );
|
||||
BOOST_CHECK_EQUAL( 1, next2.pos );
|
||||
}
|
||||
|
||||
|
||||
struct ALTIUM_RULE_TOKENIZER_INPUT_OUTPUT
|
||||
{
|
||||
wxString input;
|
||||
std::vector<ALTIUM_RULE_TOKEN> exp_token;
|
||||
};
|
||||
|
||||
/**
|
||||
* A list of valid test strings and the expected results
|
||||
*/
|
||||
static const std::vector<ALTIUM_RULE_TOKENIZER_INPUT_OUTPUT> altium_rule_tokens_property = {
|
||||
// Empty string
|
||||
{ "",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 0 }
|
||||
}
|
||||
},
|
||||
// Single Token
|
||||
{ "All",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::IDENT, 0, "All" },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "1234",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_INT, 0, 1234L },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 4 }
|
||||
}
|
||||
},
|
||||
{ "+1234",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_INT, 0, 1234L },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 5 }
|
||||
}
|
||||
},
|
||||
{ "-1234",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_INT, 0, -1234L },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 5 }
|
||||
}
|
||||
},
|
||||
{ "'1234'",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_STRING, 0, "1234" },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 6 }
|
||||
}
|
||||
},
|
||||
{ "True",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_TRUE, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 4 }
|
||||
}
|
||||
},
|
||||
{ "true",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_TRUE, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 4 }
|
||||
}
|
||||
},
|
||||
{ "False",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_FALSE, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 5 }
|
||||
}
|
||||
},
|
||||
{ "false",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_FALSE, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 5 }
|
||||
}
|
||||
},
|
||||
{ "+",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::ADD, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 1 }
|
||||
}
|
||||
},
|
||||
{ "-",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::SUB, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 1 }
|
||||
}
|
||||
},
|
||||
{ "*",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::MUL, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 1 }
|
||||
}
|
||||
},
|
||||
{ "/",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::DIV, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 1 }
|
||||
}
|
||||
},
|
||||
{ "Div",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::INTEGRAL_DIV, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "div",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::INTEGRAL_DIV, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "Mod",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::MOD, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "mod",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::MOD, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "And",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::AND, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "and",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::AND, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "&&",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::LOW_AND, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 2 }
|
||||
}
|
||||
},
|
||||
{ "Or",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::OR, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 2 }
|
||||
}
|
||||
},
|
||||
{ "or",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::OR, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 2 }
|
||||
}
|
||||
},
|
||||
{ "||",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::LOW_OR, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 2 }
|
||||
}
|
||||
},
|
||||
{ "Xor",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::XOR, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "xor",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::XOR, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "Not",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::NOT, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "not",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::NOT, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 3 }
|
||||
}
|
||||
},
|
||||
{ "<",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::LESS, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 1 }
|
||||
}
|
||||
},
|
||||
{ "<=",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::LESS_EQUAL, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 2 }
|
||||
}
|
||||
},
|
||||
{ ">",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::GREATER, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 1 }
|
||||
}
|
||||
},
|
||||
{ ">=",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::GREATER_EQUAL, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 2 }
|
||||
}
|
||||
},
|
||||
{ "<>",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::NOT_EQUAL, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 2 }
|
||||
}
|
||||
},
|
||||
{ "=",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::EQUAL, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 1 }
|
||||
}
|
||||
},
|
||||
{ "Between",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::BETWEEN, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 7 }
|
||||
}
|
||||
},
|
||||
{ "between",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::BETWEEN, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 7 }
|
||||
}
|
||||
},
|
||||
{ "Like",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::LIKE, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 4 }
|
||||
}
|
||||
},
|
||||
{ "like",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::LIKE, 0 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 4 }
|
||||
}
|
||||
},
|
||||
// Multiple tokens
|
||||
{ "ab cd ef",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::IDENT, 0, "ab" },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::IDENT, 3, "cd" },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::IDENT, 6, "ef" },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 8 }
|
||||
}
|
||||
},
|
||||
// Complex tests
|
||||
{ "InComponent('LEDS1') or InComponent('LEDS2')",
|
||||
{
|
||||
{ ALTIUM_RULE_TOKEN_KIND::IDENT, 0, "InComponent" },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::LPAR, 11 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_STRING, 12, "LEDS1" },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::RPAR, 19 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::OR, 21 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::IDENT, 24, "InComponent" },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::LPAR, 35 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::CONST_STRING, 36, "LEDS2" },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::RPAR, 43 },
|
||||
{ ALTIUM_RULE_TOKEN_KIND::END_OF_EXPR, 44 }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test conversation from wxString to Altium tokens
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( AltiumRuleTokenizerParameterizedTest )
|
||||
{
|
||||
for( const auto& c : altium_rule_tokens_property )
|
||||
{
|
||||
BOOST_TEST_CONTEXT( wxString::Format( wxT( "'%s'" ), c.input ) )
|
||||
{
|
||||
ALTIUM_RULE_TOKENIZER tokenizer( c.input );
|
||||
|
||||
for( const auto& expected : c.exp_token )
|
||||
{
|
||||
const ALTIUM_RULE_TOKEN& token = tokenizer.Next();
|
||||
BOOST_CHECK( ( expected.kind == token.kind ) );
|
||||
BOOST_CHECK_EQUAL( expected.pos, token.pos );
|
||||
BOOST_CHECK_EQUAL( expected.iValue, token.iValue );
|
||||
BOOST_CHECK_EQUAL( expected.fValue, token.fValue );
|
||||
BOOST_CHECK_EQUAL( expected.sValue, token.sValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue