intl.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,270 行 · 第 1/5 页
CPP
2,270 行
return node(0)->evaluate(n) >= node(1)->evaluate(n);
case wxPluralFormsToken::T_LESS:
return node(0)->evaluate(n) < node(1)->evaluate(n);
case wxPluralFormsToken::T_LESS_OR_EQUAL:
return node(0)->evaluate(n) <= node(1)->evaluate(n);
case wxPluralFormsToken::T_REMINDER:
{
wxPluralFormsToken::Number number = node(1)->evaluate(n);
if (number != 0)
{
return node(0)->evaluate(n) % number;
}
else
{
return 0;
}
}
case wxPluralFormsToken::T_LOGICAL_AND:
return node(0)->evaluate(n) && node(1)->evaluate(n);
case wxPluralFormsToken::T_LOGICAL_OR:
return node(0)->evaluate(n) || node(1)->evaluate(n);
// 3 args
case wxPluralFormsToken::T_QUESTION:
return node(0)->evaluate(n)
? node(1)->evaluate(n)
: node(2)->evaluate(n);
default:
return 0;
}
}
class wxPluralFormsCalculator
{
public:
wxPluralFormsCalculator() : m_nplurals(0), m_plural(0) {}
// input: number, returns msgstr index
int evaluate(int n) const;
// input: text after "Plural-Forms:" (e.g. "nplurals=2; plural=(n != 1);"),
// if s == 0, creates default handler
// returns 0 if error
static wxPluralFormsCalculator* make(const char* s = 0);
~wxPluralFormsCalculator() {}
void init(wxPluralFormsToken::Number nplurals, wxPluralFormsNode* plural);
private:
wxPluralFormsToken::Number m_nplurals;
wxPluralFormsNodePtr m_plural;
};
wxDEFINE_SCOPED_PTR_TYPE(wxPluralFormsCalculator);
void wxPluralFormsCalculator::init(wxPluralFormsToken::Number nplurals,
wxPluralFormsNode* plural)
{
m_nplurals = nplurals;
m_plural.reset(plural);
}
int wxPluralFormsCalculator::evaluate(int n) const
{
if (m_plural.get() == 0)
{
return 0;
}
wxPluralFormsToken::Number number = m_plural->evaluate(n);
if (number < 0 || number > m_nplurals)
{
return 0;
}
return number;
}
class wxPluralFormsParser
{
public:
wxPluralFormsParser(wxPluralFormsScanner& scanner) : m_scanner(scanner) {}
bool parse(wxPluralFormsCalculator& rCalculator);
private:
wxPluralFormsNode* parsePlural();
// stops at T_SEMICOLON, returns 0 if error
wxPluralFormsScanner& m_scanner;
const wxPluralFormsToken& token() const;
bool nextToken();
wxPluralFormsNode* expression();
wxPluralFormsNode* logicalOrExpression();
wxPluralFormsNode* logicalAndExpression();
wxPluralFormsNode* equalityExpression();
wxPluralFormsNode* multiplicativeExpression();
wxPluralFormsNode* relationalExpression();
wxPluralFormsNode* pmExpression();
};
bool wxPluralFormsParser::parse(wxPluralFormsCalculator& rCalculator)
{
if (token().type() != wxPluralFormsToken::T_NPLURALS)
return false;
if (!nextToken())
return false;
if (token().type() != wxPluralFormsToken::T_ASSIGN)
return false;
if (!nextToken())
return false;
if (token().type() != wxPluralFormsToken::T_NUMBER)
return false;
wxPluralFormsToken::Number nplurals = token().number();
if (!nextToken())
return false;
if (token().type() != wxPluralFormsToken::T_SEMICOLON)
return false;
if (!nextToken())
return false;
if (token().type() != wxPluralFormsToken::T_PLURAL)
return false;
if (!nextToken())
return false;
if (token().type() != wxPluralFormsToken::T_ASSIGN)
return false;
if (!nextToken())
return false;
wxPluralFormsNode* plural = parsePlural();
if (plural == 0)
return false;
if (token().type() != wxPluralFormsToken::T_SEMICOLON)
return false;
if (!nextToken())
return false;
if (token().type() != wxPluralFormsToken::T_EOF)
return false;
rCalculator.init(nplurals, plural);
return true;
}
wxPluralFormsNode* wxPluralFormsParser::parsePlural()
{
wxPluralFormsNode* p = expression();
if (p == NULL)
{
return NULL;
}
wxPluralFormsNodePtr n(p);
if (token().type() != wxPluralFormsToken::T_SEMICOLON)
{
return NULL;
}
return n.release();
}
const wxPluralFormsToken& wxPluralFormsParser::token() const
{
return m_scanner.token();
}
bool wxPluralFormsParser::nextToken()
{
if (!m_scanner.nextToken())
return false;
return true;
}
wxPluralFormsNode* wxPluralFormsParser::expression()
{
wxPluralFormsNode* p = logicalOrExpression();
if (p == NULL)
return NULL;
wxPluralFormsNodePtr n(p);
if (token().type() == wxPluralFormsToken::T_QUESTION)
{
wxPluralFormsNodePtr qn(new wxPluralFormsNode(token()));
if (!nextToken())
{
return 0;
}
p = expression();
if (p == 0)
{
return 0;
}
qn->setNode(1, p);
if (token().type() != wxPluralFormsToken::T_COLON)
{
return 0;
}
if (!nextToken())
{
return 0;
}
p = expression();
if (p == 0)
{
return 0;
}
qn->setNode(2, p);
qn->setNode(0, n.release());
return qn.release();
}
return n.release();
}
wxPluralFormsNode*wxPluralFormsParser::logicalOrExpression()
{
wxPluralFormsNode* p = logicalAndExpression();
if (p == NULL)
return NULL;
wxPluralFormsNodePtr ln(p);
if (token().type() == wxPluralFormsToken::T_LOGICAL_OR)
{
wxPluralFormsNodePtr un(new wxPluralFormsNode(token()));
if (!nextToken())
{
return 0;
}
p = logicalOrExpression();
if (p == 0)
{
return 0;
}
wxPluralFormsNodePtr rn(p); // right
if (rn->token().type() == wxPluralFormsToken::T_LOGICAL_OR)
{
// see logicalAndExpression comment
un->setNode(0, ln.release());
un->setNode(1, rn->releaseNode(0));
rn->setNode(0, un.release());
return rn.release();
}
un->setNode(0, ln.release());
un->setNode(1, rn.release());
return un.release();
}
return ln.release();
}
wxPluralFormsNode* wxPluralFormsParser::logicalAndExpression()
{
wxPluralFormsNode* p = equalityExpression();
if (p == NULL)
return NULL;
wxPluralFormsNodePtr ln(p); // left
if (token().type() == wxPluralFormsToken::T_LOGICAL_AND)
{
wxPluralFormsNodePtr un(new wxPluralFormsNode(token())); // up
if (!nextToken())
{
return NULL;
}
p = logicalAndExpression();
if (p == 0)
{
return NULL;
}
wxPluralFormsNodePtr rn(p); // right
if (rn->token().type() == wxPluralFormsToken::T_LOGICAL_AND)
{
// transform 1 && (2 && 3) -> (1 && 2) && 3
// u r
// l r -> u 3
// 2 3 l 2
un->setNode(0, ln.release());
un->setNode(1, rn->releaseNode(0));
rn->setNode(0, un.release());
return rn.release();
}
un->setNode(0, ln.release());
un->setNode(1, rn.release());
return un.release();
}
return ln.release();
}
wxPluralFormsNode* wxPluralFormsParser::equalityExpression()
{
wxPluralFormsNode* p = relationalExpression();
if (p == NULL)
return NULL;
wxPluralFormsNodePtr n(p);
if (token().type() == wxPluralFormsToken::T_EQUAL
|| token().type() == wxPluralFormsToken::T_NOT_EQUAL)
{
wxPluralFormsNodePtr qn(new wxPluralFormsNode(token()));
if (!nextToken())
{
return NULL;
}
p = relationalExpression();
if (p == NULL)
{
return NULL;
}
qn->setNode(1, p);
qn->setNode(0, n.release());
return qn.release();
}
return n.release();
}
wxPluralFormsNode* wxPluralFormsParser::relationalExpression()
{
wxPluralFormsNode* p = multiplicativeExpression();
if (p == NULL)
return NULL;
wxPluralFormsNodePtr n(p);
if (token().type() == wxPluralFormsToken::T_GREATER
|| token().type() == wxPluralFormsToken::T_LESS
|| token().type() == wxPluralFormsToken::T_GREATER_OR_EQUAL
|| token().type() == wxPluralFormsToken::T_LESS_OR_EQUAL)
{
wxPluralFormsNodePtr qn(new wxPluralFormsNode(token()));
if (!nextToken())
{
return NULL;
}
p = multiplicativeExpression();
if (p == NULL)
{
return NULL;
}
qn->setNode(1, p);
qn->setNode(0, n.release());
return qn.release();
}
return n.release();
}
wxPluralFormsNode* wxPluralFormsParser::multiplicativeExpression()
{
wxPluralFormsNode* p = pmExpression();
if (p == NULL)
return NULL;
wxPluralFormsNodePtr n(p);
if (token().type() == wxPluralFormsToken::T_REMINDER)
{
wxPluralFormsNodePtr qn(new wxPluralFormsNode(token()));
if (!nextToken())
{
return NULL;
}
p = pmExpression();
if (p == NULL)
{
return NULL;
}
qn->setNode(1, p);
qn->setNode(0, n.release());
return qn.release();
}
return n.release();
}
wxPluralFormsNode* wxPluralFormsParser::pmExpression()
{
wxPluralFormsNodePtr n;
if (token().type() == wxPluralFormsToken::T_N
|| token().type() == wxPluralFormsToken::T_NUMBER)
{
n.reset(new wxPluralFormsNode(token()));
if (!nextToken())
{
return NULL;
}
}
else if (token().type() == wxPluralFormsToken::T_LEFT_BRACKET) {
if (!nextToken())
{
return NULL;
}
wxPluralFormsNode* p = expression();
if (p == NULL)
{
return NULL;
}
n.reset(p);
if (token().type() != wxPluralFormsToken::T_RIGHT_BRACKET)
{
return NULL;
}
if (!nextToken())
{
return NULL;
}
}
else
{
return NULL;
}
return n.release();
}
wxPluralFormsCalculator* wxPluralFormsCalculator::make(const char* s)
{
wxPluralFormsCalculatorPtr calculator(new wxPluralFormsCalculator);
if (s != NULL)
{
wxPluralFormsScanner scanner(s);
wxPluralFormsParser p(scanner);
if (!p.parse(*calculator))
{
return NULL;
}
}
return calculator.release();
}
// ----------------------------------------------------------------------------
// wxMsgCatalogFile corresponds to one disk-file message catalog.
//
// This is a "low-level" class and is used only by wxMsgCatalog
// ----------------------------------------------------------------------------
WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString, wxMessagesHash);
class wxMsgCatalogFile
{
public:
// ctor & dtor
wxMsgCatalogFile();
~wxMsgCatalogFile();
// load the catalog from disk (szDirPrefix corresponds to language)
bool Load(const wxChar *szDirPrefix, const wxChar *szName,
wxPluralFormsCalculatorPtr& rPluralFormsCalculator);
// fills the hash with string-translation pairs
void FillHash(wxMessagesHash& hash, const wxString& msgIdCharset,
bool convertEncoding) const;
private:
// this implementation is binary compatible with GNU gettext() version 0.10
// an entry in the string table
struct wxMsgTableEntry
{
size_t32 nLen; // length of the string
size_t32 ofsString; // pointer to the string
};
// header of a .mo file
struct wxMsgCatalogHeader
{
size_t32 magic, // offset +00: magic id
revision, // +04: revision
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?