First commit

This commit is contained in:
GotPPay
2018-02-23 00:40:26 +01:00
commit f9a08ea8da
333 changed files with 50313 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "XPathLexer.h"
#include "XPathLexerErrorListener.h"
#include "XPathElement.h"
#include "XPathWildcardAnywhereElement.h"
#include "XPathWildcardElement.h"
#include "XPathTokenAnywhereElement.h"
#include "XPathTokenElement.h"
#include "XPathRuleAnywhereElement.h"
#include "XPathRuleElement.h"
#include "XPath.h"
using namespace antlr4;
using namespace antlr4::tree;
using namespace antlr4::tree::xpath;
const std::string XPath::WILDCARD = "*";
const std::string XPath::NOT = "!";
XPath::XPath(Parser *parser, const std::string &path) {
_parser = parser;
_path = path;
_elements = split(path);
}
std::vector<XPathElement> XPath::split(const std::string &path) {
ANTLRFileStream in(path);
XPathLexer lexer(&in);
lexer.removeErrorListeners();
XPathLexerErrorListener listener;
lexer.addErrorListener(&listener);
CommonTokenStream tokenStream(&lexer);
try {
tokenStream.fill();
} catch (LexerNoViableAltException &) {
size_t pos = lexer.getCharPositionInLine();
std::string msg = "Invalid tokens or characters at index " + std::to_string(pos) + " in path '" + path + "'";
throw IllegalArgumentException(msg);
}
std::vector<Token *> tokens = tokenStream.getTokens();
std::vector<XPathElement> elements;
size_t n = tokens.size();
size_t i = 0;
bool done = false;
while (!done && i < n) {
Token *el = tokens[i];
Token *next = nullptr;
switch (el->getType()) {
case XPathLexer::ROOT:
case XPathLexer::ANYWHERE: {
bool anywhere = el->getType() == XPathLexer::ANYWHERE;
i++;
next = tokens[i];
bool invert = next->getType() == XPathLexer::BANG;
if (invert) {
i++;
next = tokens[i];
}
XPathElement pathElement = getXPathElement(next, anywhere);
pathElement.setInvert(invert);
elements.push_back(pathElement);
i++;
break;
}
case XPathLexer::TOKEN_REF:
case XPathLexer::RULE_REF:
case XPathLexer::WILDCARD:
elements.push_back(getXPathElement(el, false));
i++;
break;
case Token::EOF:
done = true;
break;
default :
throw IllegalArgumentException("Unknow path element " + el->toString());
}
}
return elements;
}
XPathElement XPath::getXPathElement(Token *wordToken, bool anywhere) {
if (wordToken->getType() == Token::EOF) {
throw IllegalArgumentException("Missing path element at end of path");
}
std::string word = wordToken->getText();
size_t ttype = _parser->getTokenType(word);
ssize_t ruleIndex = _parser->getRuleIndex(word);
switch (wordToken->getType()) {
case XPathLexer::WILDCARD :
if (anywhere)
return XPathWildcardAnywhereElement();
return XPathWildcardElement();
case XPathLexer::TOKEN_REF:
case XPathLexer::STRING :
if (ttype == Token::INVALID_TYPE) {
throw IllegalArgumentException(word + " at index " + std::to_string(wordToken->getStartIndex()) + " isn't a valid token name");
}
if (anywhere)
return XPathTokenAnywhereElement(word, (int)ttype);
return XPathTokenElement(word, (int)ttype);
default :
if (ruleIndex == -1) {
throw IllegalArgumentException(word + " at index " + std::to_string(wordToken->getStartIndex()) + " isn't a valid rule name");
}
if (anywhere)
return XPathRuleAnywhereElement(word, (int)ruleIndex);
return XPathRuleElement(word, (int)ruleIndex);
}
}
static ParserRuleContext dummyRoot;
std::vector<ParseTree *> XPath::evaluate(ParseTree *t) {
dummyRoot.children = { t }; // don't set t's parent.
std::vector<ParseTree *> work = { &dummyRoot };
size_t i = 0;
while (i < _elements.size()) {
std::vector<ParseTree *> next;
for (auto node : work) {
if (!node->children.empty()) {
// only try to match next element if it has children
// e.g., //func/*/stat might have a token node for which
// we can't go looking for stat nodes.
auto matching = _elements[i].evaluate(node);
next.insert(next.end(), matching.begin(), matching.end());
}
}
i++;
work = next;
}
return work;
}

View File

@@ -0,0 +1,85 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "antlr4-common.h"
namespace antlr4 {
namespace tree {
namespace xpath {
/// Represent a subset of XPath XML path syntax for use in identifying nodes in
/// parse trees.
///
/// <para>
/// Split path into words and separators {@code /} and {@code //} via ANTLR
/// itself then walk path elements from left to right. At each separator-word
/// pair, find set of nodes. Next stage uses those as work list.</para>
///
/// <para>
/// The basic interface is
/// <seealso cref="XPath#findAll ParseTree.findAll"/>{@code (tree, pathString, parser)}.
/// But that is just shorthand for:</para>
///
/// <pre>
/// <seealso cref="XPath"/> p = new <seealso cref="XPath#XPath XPath"/>(parser, pathString);
/// return p.<seealso cref="#evaluate evaluate"/>(tree);
/// </pre>
///
/// <para>
/// See {@code org.antlr.v4.test.TestXPath} for descriptions. In short, this
/// allows operators:</para>
///
/// <dl>
/// <dt>/</dt> <dd>root</dd>
/// <dt>//</dt> <dd>anywhere</dd>
/// <dt>!</dt> <dd>invert; this must appear directly after root or anywhere
/// operator</dd>
/// </dl>
///
/// <para>
/// and path elements:</para>
///
/// <dl>
/// <dt>ID</dt> <dd>token name</dd>
/// <dt>'string'</dt> <dd>any string literal token from the grammar</dd>
/// <dt>expr</dt> <dd>rule name</dd>
/// <dt>*</dt> <dd>wildcard matching any node</dd>
/// </dl>
///
/// <para>
/// Whitespace is not allowed.</para>
class ANTLR4CPP_PUBLIC XPath {
public:
static const std::string WILDCARD; // word not operator/separator
static const std::string NOT; // word for invert operator
XPath(Parser *parser, const std::string &path);
virtual ~XPath() {}
// TO_DO: check for invalid token/rule names, bad syntax
virtual std::vector<XPathElement> split(const std::string &path);
/// Return a list of all nodes starting at {@code t} as root that satisfy the
/// path. The root {@code /} is relative to the node passed to
/// <seealso cref="#evaluate"/>.
virtual std::vector<ParseTree *> evaluate(ParseTree *t);
protected:
std::string _path;
std::vector<XPathElement> _elements;
Parser *_parser;
/// Convert word like {@code *} or {@code ID} or {@code expr} to a path
/// element. {@code anywhere} is {@code true} if {@code //} precedes the
/// word.
virtual XPathElement getXPathElement(Token *wordToken, bool anywhere);
};
} // namespace xpath
} // namespace tree
} // namespace antlr4

View File

@@ -0,0 +1,31 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "support/CPPUtils.h"
#include "XPathElement.h"
using namespace antlr4::tree;
using namespace antlr4::tree::xpath;
XPathElement::XPathElement(const std::string &nodeName) {
_nodeName = nodeName;
}
XPathElement::~XPathElement() {
}
std::vector<ParseTree *> XPathElement::evaluate(ParseTree * /*t*/) {
return {};
}
std::string XPathElement::toString() const {
std::string inv = _invert ? "!" : "";
return antlrcpp::toString(*this) + "[" + inv + _nodeName + "]";
}
void XPathElement::setInvert(bool value) {
_invert = value;
}

View File

@@ -0,0 +1,40 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "antlr4-common.h"
namespace antlr4 {
namespace tree {
class ParseTree;
namespace xpath {
class ANTLR4CPP_PUBLIC XPathElement {
public:
/// Construct element like {@code /ID} or {@code ID} or {@code /*} etc...
/// op is null if just node
XPathElement(const std::string &nodeName);
XPathElement(XPathElement const&) = default;
virtual ~XPathElement();
XPathElement& operator=(XPathElement const&) = default;
/// Given tree rooted at {@code t} return all nodes matched by this path
/// element.
virtual std::vector<ParseTree *> evaluate(ParseTree *t);
virtual std::string toString() const;
void setInvert(bool value);
protected:
std::string _nodeName;
bool _invert = false;
};
} // namespace xpath
} // namespace tree
} // namespace antlr4

View File

@@ -0,0 +1,173 @@
#include "XPathLexer.h"
using namespace antlr4;
XPathLexer::XPathLexer(CharStream *input) : Lexer(input) {
_interpreter = new atn::LexerATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache);
}
XPathLexer::~XPathLexer() {
delete _interpreter;
}
std::string XPathLexer::getGrammarFileName() const {
return "XPathLexer.g4";
}
const std::vector<std::string>& XPathLexer::getRuleNames() const {
return _ruleNames;
}
const std::vector<std::string>& XPathLexer::getChannelNames() const {
return _channelNames;
}
const std::vector<std::string>& XPathLexer::getModeNames() const {
return _modeNames;
}
const std::vector<std::string>& XPathLexer::getTokenNames() const {
return _tokenNames;
}
dfa::Vocabulary& XPathLexer::getVocabulary() const {
return _vocabulary;
}
const std::vector<uint16_t> XPathLexer::getSerializedATN() const {
return _serializedATN;
}
const atn::ATN& XPathLexer::getATN() const {
return _atn;
}
void XPathLexer::action(RuleContext *context, size_t ruleIndex, size_t actionIndex) {
switch (ruleIndex) {
case 4: IDAction(dynamic_cast<antlr4::RuleContext *>(context), actionIndex); break;
default:
break;
}
}
void XPathLexer::IDAction(antlr4::RuleContext * /*context*/, size_t actionIndex) {
switch (actionIndex) {
case 0:
if (isupper(getText()[0]))
setType(TOKEN_REF);
else
setType(RULE_REF);
break;
default:
break;
}
}
// Static vars and initialization.
std::vector<dfa::DFA> XPathLexer::_decisionToDFA;
atn::PredictionContextCache XPathLexer::_sharedContextCache;
// We own the ATN which in turn owns the ATN states.
atn::ATN XPathLexer::_atn;
std::vector<uint16_t> XPathLexer::_serializedATN;
std::vector<std::string> XPathLexer::_ruleNames = {
"ANYWHERE", "ROOT", "WILDCARD", "BANG", "ID", "NameChar", "NameStartChar",
"STRING"
};
std::vector<std::string> XPathLexer::_channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
std::vector<std::string> XPathLexer::_modeNames = {
"DEFAULT_MODE"
};
std::vector<std::string> XPathLexer::_literalNames = {
"", "", "", "'//'", "'/'", "'*'", "'!'"
};
std::vector<std::string> XPathLexer::_symbolicNames = {
"", "TOKEN_REF", "RULE_REF", "ANYWHERE", "ROOT", "WILDCARD", "BANG", "ID",
"STRING"
};
dfa::Vocabulary XPathLexer::_vocabulary(_literalNames, _symbolicNames);
std::vector<std::string> XPathLexer::_tokenNames;
XPathLexer::Initializer::Initializer() {
// This code could be in a static initializer lambda, but VS doesn't allow access to private class members from there.
for (size_t i = 0; i < _symbolicNames.size(); ++i) {
std::string name = _vocabulary.getLiteralName(i);
if (name.empty()) {
name = _vocabulary.getSymbolicName(i);
}
if (name.empty()) {
_tokenNames.push_back("<INVALID>");
} else {
_tokenNames.push_back(name);
}
}
_serializedATN = {
0x3, 0x430, 0xd6d1, 0x8206, 0xad2d, 0x4417, 0xaef1, 0x8d80, 0xaadd,
0x2, 0xa, 0x34, 0x8, 0x1, 0x4, 0x2, 0x9, 0x2, 0x4, 0x3, 0x9, 0x3, 0x4,
0x4, 0x9, 0x4, 0x4, 0x5, 0x9, 0x5, 0x4, 0x6, 0x9, 0x6, 0x4, 0x7, 0x9,
0x7, 0x4, 0x8, 0x9, 0x8, 0x4, 0x9, 0x9, 0x9, 0x3, 0x2, 0x3, 0x2, 0x3,
0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x4, 0x3, 0x5, 0x3, 0x5, 0x3,
0x6, 0x3, 0x6, 0x7, 0x6, 0x1f, 0xa, 0x6, 0xc, 0x6, 0xe, 0x6, 0x22, 0xb,
0x6, 0x3, 0x6, 0x3, 0x6, 0x3, 0x7, 0x3, 0x7, 0x5, 0x7, 0x28, 0xa, 0x7,
0x3, 0x8, 0x3, 0x8, 0x3, 0x9, 0x3, 0x9, 0x7, 0x9, 0x2e, 0xa, 0x9, 0xc,
0x9, 0xe, 0x9, 0x31, 0xb, 0x9, 0x3, 0x9, 0x3, 0x9, 0x3, 0x2f, 0x2, 0xa,
0x3, 0x5, 0x5, 0x6, 0x7, 0x7, 0x9, 0x8, 0xb, 0x9, 0xd, 0x2, 0xf, 0x2,
0x11, 0xa, 0x3, 0x2, 0x4, 0x7, 0x2, 0x32, 0x3b, 0x61, 0x61, 0xb9, 0xb9,
0x302, 0x371, 0x2041, 0x2042, 0xf, 0x2, 0x43, 0x5c, 0x63, 0x7c, 0xc2,
0xd8, 0xda, 0xf8, 0xfa, 0x301, 0x372, 0x37f, 0x381, 0x2001, 0x200e,
0x200f, 0x2072, 0x2191, 0x2c02, 0x2ff1, 0x3003, 0xd801, 0xf902, 0xfdd1,
0xfdf2, 0x1, 0x34, 0x2, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x5, 0x3, 0x2,
0x2, 0x2, 0x2, 0x7, 0x3, 0x2, 0x2, 0x2, 0x2, 0x9, 0x3, 0x2, 0x2, 0x2,
0x2, 0xb, 0x3, 0x2, 0x2, 0x2, 0x2, 0x11, 0x3, 0x2, 0x2, 0x2, 0x3, 0x13,
0x3, 0x2, 0x2, 0x2, 0x5, 0x16, 0x3, 0x2, 0x2, 0x2, 0x7, 0x18, 0x3, 0x2,
0x2, 0x2, 0x9, 0x1a, 0x3, 0x2, 0x2, 0x2, 0xb, 0x1c, 0x3, 0x2, 0x2, 0x2,
0xd, 0x27, 0x3, 0x2, 0x2, 0x2, 0xf, 0x29, 0x3, 0x2, 0x2, 0x2, 0x11,
0x2b, 0x3, 0x2, 0x2, 0x2, 0x13, 0x14, 0x7, 0x31, 0x2, 0x2, 0x14, 0x15,
0x7, 0x31, 0x2, 0x2, 0x15, 0x4, 0x3, 0x2, 0x2, 0x2, 0x16, 0x17, 0x7,
0x31, 0x2, 0x2, 0x17, 0x6, 0x3, 0x2, 0x2, 0x2, 0x18, 0x19, 0x7, 0x2c,
0x2, 0x2, 0x19, 0x8, 0x3, 0x2, 0x2, 0x2, 0x1a, 0x1b, 0x7, 0x23, 0x2,
0x2, 0x1b, 0xa, 0x3, 0x2, 0x2, 0x2, 0x1c, 0x20, 0x5, 0xf, 0x8, 0x2,
0x1d, 0x1f, 0x5, 0xd, 0x7, 0x2, 0x1e, 0x1d, 0x3, 0x2, 0x2, 0x2, 0x1f,
0x22, 0x3, 0x2, 0x2, 0x2, 0x20, 0x1e, 0x3, 0x2, 0x2, 0x2, 0x20, 0x21,
0x3, 0x2, 0x2, 0x2, 0x21, 0x23, 0x3, 0x2, 0x2, 0x2, 0x22, 0x20, 0x3,
0x2, 0x2, 0x2, 0x23, 0x24, 0x8, 0x6, 0x2, 0x2, 0x24, 0xc, 0x3, 0x2,
0x2, 0x2, 0x25, 0x28, 0x5, 0xf, 0x8, 0x2, 0x26, 0x28, 0x9, 0x2, 0x2,
0x2, 0x27, 0x25, 0x3, 0x2, 0x2, 0x2, 0x27, 0x26, 0x3, 0x2, 0x2, 0x2,
0x28, 0xe, 0x3, 0x2, 0x2, 0x2, 0x29, 0x2a, 0x9, 0x3, 0x2, 0x2, 0x2a,
0x10, 0x3, 0x2, 0x2, 0x2, 0x2b, 0x2f, 0x7, 0x29, 0x2, 0x2, 0x2c, 0x2e,
0xb, 0x2, 0x2, 0x2, 0x2d, 0x2c, 0x3, 0x2, 0x2, 0x2, 0x2e, 0x31, 0x3,
0x2, 0x2, 0x2, 0x2f, 0x30, 0x3, 0x2, 0x2, 0x2, 0x2f, 0x2d, 0x3, 0x2,
0x2, 0x2, 0x30, 0x32, 0x3, 0x2, 0x2, 0x2, 0x31, 0x2f, 0x3, 0x2, 0x2,
0x2, 0x32, 0x33, 0x7, 0x29, 0x2, 0x2, 0x33, 0x12, 0x3, 0x2, 0x2, 0x2,
0x6, 0x2, 0x20, 0x27, 0x2f, 0x3, 0x3, 0x6, 0x2,
};
atn::ATNDeserializer deserializer;
_atn = deserializer.deserialize(_serializedATN);
size_t count = _atn.getNumberOfDecisions();
_decisionToDFA.reserve(count);
for (size_t i = 0; i < count; i++) {
_decisionToDFA.emplace_back(_atn.getDecisionState(i), i);
}
}
XPathLexer::Initializer XPathLexer::_init;

View File

@@ -0,0 +1,64 @@
lexer grammar XPathLexer;
tokens { TOKEN_REF, RULE_REF }
/*
path : separator? word (separator word)* EOF ;
separator
: '/' '!'
| '//' '!'
| '/'
| '//'
;
word: TOKEN_REF
| RULE_REF
| STRING
| '*'
;
*/
ANYWHERE : '//' ;
ROOT : '/' ;
WILDCARD : '*' ;
BANG : '!' ;
ID : NameStartChar NameChar*
{
if (isupper(getText()[0]))
setType(TOKEN_REF);
else
setType(RULE_REF);
}
;
fragment
NameChar : NameStartChar
| '0'..'9'
| '_'
| '\u00B7'
| '\u0300'..'\u036F'
| '\u203F'..'\u2040'
;
fragment
NameStartChar
: 'A'..'Z' | 'a'..'z'
| '\u00C0'..'\u00D6'
| '\u00D8'..'\u00F6'
| '\u00F8'..'\u02FF'
| '\u0370'..'\u037D'
| '\u037F'..'\u1FFF'
| '\u200C'..'\u200D'
| '\u2070'..'\u218F'
| '\u2C00'..'\u2FEF'
| '\u3001'..'\uD7FF'
| '\uF900'..'\uFDCF'
| '\uFDF0'..'\uFFFF' // implicitly includes ['\u10000-'\uEFFFF]
;
STRING : '\'' .*? '\'';
//WS : [ \t\r\n]+ -> skip ;

View File

@@ -0,0 +1,56 @@
#pragma once
#include "antlr4-runtime.h"
class XPathLexer : public antlr4::Lexer {
public:
enum {
TOKEN_REF = 1, RULE_REF = 2, ANYWHERE = 3, ROOT = 4, WILDCARD = 5, BANG = 6,
ID = 7, STRING = 8
};
XPathLexer(antlr4::CharStream *input);
~XPathLexer();
virtual std::string getGrammarFileName() const override;
virtual const std::vector<std::string>& getRuleNames() const override;
virtual const std::vector<std::string>& getChannelNames() const override;
virtual const std::vector<std::string>& getModeNames() const override;
virtual const std::vector<std::string>& getTokenNames() const override; // deprecated, use vocabulary instead
virtual antlr4::dfa::Vocabulary& getVocabulary() const override;
virtual const std::vector<uint16_t> getSerializedATN() const override;
virtual const antlr4::atn::ATN& getATN() const override;
virtual void action(antlr4::RuleContext *context, size_t ruleIndex, size_t actionIndex) override;
private:
static std::vector<antlr4::dfa::DFA> _decisionToDFA;
static antlr4::atn::PredictionContextCache _sharedContextCache;
static std::vector<std::string> _ruleNames;
static std::vector<std::string> _tokenNames;
static std::vector<std::string> _channelNames;
static std::vector<std::string> _modeNames;
static std::vector<std::string> _literalNames;
static std::vector<std::string> _symbolicNames;
static antlr4::dfa::Vocabulary _vocabulary;
static antlr4::atn::ATN _atn;
static std::vector<uint16_t> _serializedATN;
// Individual action functions triggered by action() above.
void IDAction(antlr4::RuleContext *context, size_t actionIndex);
// Individual semantic predicate functions triggered by sempred() above.
struct Initializer {
Initializer();
};
static Initializer _init;
};

View File

@@ -0,0 +1,12 @@
TOKEN_REF=1
RULE_REF=2
ANYWHERE=3
ROOT=4
WILDCARD=5
BANG=6
ID=7
STRING=8
'//'=3
'/'=4
'*'=5
'!'=6

View File

@@ -0,0 +1,13 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "XPathLexerErrorListener.h"
using namespace antlr4;
using namespace antlr4::tree::xpath;
void XPathLexerErrorListener::syntaxError(Recognizer * /*recognizer*/, Token * /*offendingSymbol*/,
size_t /*line*/, size_t /*charPositionInLine*/, const std::string &/*msg*/, std::exception_ptr /*e*/) {
}

View File

@@ -0,0 +1,22 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "BaseErrorListener.h"
namespace antlr4 {
namespace tree {
namespace xpath {
class ANTLR4CPP_PUBLIC XPathLexerErrorListener : public BaseErrorListener {
public:
virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line,
size_t charPositionInLine, const std::string &msg, std::exception_ptr e) override;
};
} // namespace xpath
} // namespace tree
} // namespace antlr4

View File

@@ -0,0 +1,20 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "tree/ParseTree.h"
#include "tree/Trees.h"
#include "tree/xpath/XPathRuleAnywhereElement.h"
using namespace antlr4::tree;
using namespace antlr4::tree::xpath;
XPathRuleAnywhereElement::XPathRuleAnywhereElement(const std::string &ruleName, int ruleIndex) : XPathElement(ruleName) {
_ruleIndex = ruleIndex;
}
std::vector<ParseTree *> XPathRuleAnywhereElement::evaluate(ParseTree *t) {
return Trees::findAllRuleNodes(t, _ruleIndex);
}

View File

@@ -0,0 +1,27 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "XPathElement.h"
namespace antlr4 {
namespace tree {
namespace xpath {
/// Either {@code ID} at start of path or {@code ...//ID} in middle of path.
class ANTLR4CPP_PUBLIC XPathRuleAnywhereElement : public XPathElement {
public:
XPathRuleAnywhereElement(const std::string &ruleName, int ruleIndex);
virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
protected:
int _ruleIndex = 0;
};
} // namespace xpath
} // namespace tree
} // namespace antlr4

View File

@@ -0,0 +1,30 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "tree/ParseTree.h"
#include "tree/Trees.h"
#include "XPathRuleElement.h"
using namespace antlr4::tree;
using namespace antlr4::tree::xpath;
XPathRuleElement::XPathRuleElement(const std::string &ruleName, size_t ruleIndex) : XPathElement(ruleName) {
_ruleIndex = ruleIndex;
}
std::vector<ParseTree *> XPathRuleElement::evaluate(ParseTree *t) {
// return all children of t that match nodeName
std::vector<ParseTree *> nodes;
for (auto c : t->children) {
if (antlrcpp::is<ParserRuleContext *>(c)) {
ParserRuleContext *ctx = dynamic_cast<ParserRuleContext *>(c);
if ((ctx->getRuleIndex() == _ruleIndex && !_invert) || (ctx->getRuleIndex() != _ruleIndex && _invert)) {
nodes.push_back(ctx);
}
}
}
return nodes;
}

View File

@@ -0,0 +1,26 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "XPathElement.h"
namespace antlr4 {
namespace tree {
namespace xpath {
class ANTLR4CPP_PUBLIC XPathRuleElement : public XPathElement {
public:
XPathRuleElement(const std::string &ruleName, size_t ruleIndex);
virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
protected:
size_t _ruleIndex = 0;
};
} // namespace xpath
} // namespace tree
} // namespace antlr4

View File

@@ -0,0 +1,20 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "tree/ParseTree.h"
#include "tree/Trees.h"
#include "XPathTokenAnywhereElement.h"
using namespace antlr4::tree;
using namespace antlr4::tree::xpath;
XPathTokenAnywhereElement::XPathTokenAnywhereElement(const std::string &tokenName, int tokenType) : XPathElement(tokenName) {
this->tokenType = tokenType;
}
std::vector<ParseTree *> XPathTokenAnywhereElement::evaluate(ParseTree *t) {
return Trees::findAllTokenNodes(t, tokenType);
}

View File

@@ -0,0 +1,25 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "XPathElement.h"
namespace antlr4 {
namespace tree {
namespace xpath {
class ANTLR4CPP_PUBLIC XPathTokenAnywhereElement : public XPathElement {
protected:
int tokenType = 0;
public:
XPathTokenAnywhereElement(const std::string &tokenName, int tokenType);
virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
};
} // namespace xpath
} // namespace tree
} // namespace antlr4

View File

@@ -0,0 +1,33 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "tree/ParseTree.h"
#include "tree/Trees.h"
#include "support/CPPUtils.h"
#include "Token.h"
#include "XPathTokenElement.h"
using namespace antlr4;
using namespace antlr4::tree;
using namespace antlr4::tree::xpath;
XPathTokenElement::XPathTokenElement(const std::string &tokenName, size_t tokenType) : XPathElement(tokenName) {
_tokenType = tokenType;
}
std::vector<ParseTree *> XPathTokenElement::evaluate(ParseTree *t) {
// return all children of t that match nodeName
std::vector<ParseTree *> nodes;
for (auto c : t->children) {
if (antlrcpp::is<TerminalNode *>(c)) {
TerminalNode *tnode = dynamic_cast<TerminalNode *>(c);
if ((tnode->getSymbol()->getType() == _tokenType && !_invert) || (tnode->getSymbol()->getType() != _tokenType && _invert)) {
nodes.push_back(tnode);
}
}
}
return nodes;
}

View File

@@ -0,0 +1,26 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "XPathElement.h"
namespace antlr4 {
namespace tree {
namespace xpath {
class ANTLR4CPP_PUBLIC XPathTokenElement : public XPathElement {
public:
XPathTokenElement(const std::string &tokenName, size_t tokenType);
virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
protected:
size_t _tokenType = 0;
};
} // namespace xpath
} // namespace tree
} // namespace antlr4

View File

@@ -0,0 +1,23 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "XPath.h"
#include "tree/ParseTree.h"
#include "tree/Trees.h"
#include "XPathWildcardAnywhereElement.h"
using namespace antlr4::tree;
using namespace antlr4::tree::xpath;
XPathWildcardAnywhereElement::XPathWildcardAnywhereElement() : XPathElement(XPath::WILDCARD) {
}
std::vector<ParseTree *> XPathWildcardAnywhereElement::evaluate(ParseTree *t) {
if (_invert) {
return {}; // !* is weird but valid (empty)
}
return Trees::getDescendants(t);
}

View File

@@ -0,0 +1,23 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "XPathElement.h"
namespace antlr4 {
namespace tree {
namespace xpath {
class ANTLR4CPP_PUBLIC XPathWildcardAnywhereElement : public XPathElement {
public:
XPathWildcardAnywhereElement();
virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
};
} // namespace xpath
} // namespace tree
} // namespace antlr4

View File

@@ -0,0 +1,24 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#include "XPath.h"
#include "tree/ParseTree.h"
#include "tree/Trees.h"
#include "XPathWildcardElement.h"
using namespace antlr4::tree;
using namespace antlr4::tree::xpath;
XPathWildcardElement::XPathWildcardElement() : XPathElement(XPath::WILDCARD) {
}
std::vector<ParseTree *> XPathWildcardElement::evaluate(ParseTree *t) {
if (_invert) {
return {}; // !* is weird but valid (empty)
}
return t->children;
}

View File

@@ -0,0 +1,23 @@
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
#pragma once
#include "XPathElement.h"
namespace antlr4 {
namespace tree {
namespace xpath {
class ANTLR4CPP_PUBLIC XPathWildcardElement : public XPathElement {
public:
XPathWildcardElement();
virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
};
} // namespace xpath
} // namespace tree
} // namespace antlr4