First commit
This commit is contained in:
147
runtime-linux/antlr4-runtime/tree/xpath/XPath.cpp
Executable file
147
runtime-linux/antlr4-runtime/tree/xpath/XPath.cpp
Executable 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;
|
||||
}
|
||||
85
runtime-linux/antlr4-runtime/tree/xpath/XPath.h
Executable file
85
runtime-linux/antlr4-runtime/tree/xpath/XPath.h
Executable 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
|
||||
31
runtime-linux/antlr4-runtime/tree/xpath/XPathElement.cpp
Executable file
31
runtime-linux/antlr4-runtime/tree/xpath/XPathElement.cpp
Executable 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;
|
||||
}
|
||||
40
runtime-linux/antlr4-runtime/tree/xpath/XPathElement.h
Executable file
40
runtime-linux/antlr4-runtime/tree/xpath/XPathElement.h
Executable 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
|
||||
173
runtime-linux/antlr4-runtime/tree/xpath/XPathLexer.cpp
Normal file
173
runtime-linux/antlr4-runtime/tree/xpath/XPathLexer.cpp
Normal 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;
|
||||
64
runtime-linux/antlr4-runtime/tree/xpath/XPathLexer.g4
Normal file
64
runtime-linux/antlr4-runtime/tree/xpath/XPathLexer.g4
Normal 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 ;
|
||||
|
||||
56
runtime-linux/antlr4-runtime/tree/xpath/XPathLexer.h
Normal file
56
runtime-linux/antlr4-runtime/tree/xpath/XPathLexer.h
Normal 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;
|
||||
};
|
||||
|
||||
12
runtime-linux/antlr4-runtime/tree/xpath/XPathLexer.tokens
Normal file
12
runtime-linux/antlr4-runtime/tree/xpath/XPathLexer.tokens
Normal 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
|
||||
13
runtime-linux/antlr4-runtime/tree/xpath/XPathLexerErrorListener.cpp
Executable file
13
runtime-linux/antlr4-runtime/tree/xpath/XPathLexerErrorListener.cpp
Executable 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*/) {
|
||||
}
|
||||
22
runtime-linux/antlr4-runtime/tree/xpath/XPathLexerErrorListener.h
Executable file
22
runtime-linux/antlr4-runtime/tree/xpath/XPathLexerErrorListener.h
Executable 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
|
||||
20
runtime-linux/antlr4-runtime/tree/xpath/XPathRuleAnywhereElement.cpp
Executable file
20
runtime-linux/antlr4-runtime/tree/xpath/XPathRuleAnywhereElement.cpp
Executable 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);
|
||||
}
|
||||
27
runtime-linux/antlr4-runtime/tree/xpath/XPathRuleAnywhereElement.h
Executable file
27
runtime-linux/antlr4-runtime/tree/xpath/XPathRuleAnywhereElement.h
Executable 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
|
||||
30
runtime-linux/antlr4-runtime/tree/xpath/XPathRuleElement.cpp
Executable file
30
runtime-linux/antlr4-runtime/tree/xpath/XPathRuleElement.cpp
Executable 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;
|
||||
}
|
||||
26
runtime-linux/antlr4-runtime/tree/xpath/XPathRuleElement.h
Executable file
26
runtime-linux/antlr4-runtime/tree/xpath/XPathRuleElement.h
Executable 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
|
||||
20
runtime-linux/antlr4-runtime/tree/xpath/XPathTokenAnywhereElement.cpp
Executable file
20
runtime-linux/antlr4-runtime/tree/xpath/XPathTokenAnywhereElement.cpp
Executable 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);
|
||||
}
|
||||
25
runtime-linux/antlr4-runtime/tree/xpath/XPathTokenAnywhereElement.h
Executable file
25
runtime-linux/antlr4-runtime/tree/xpath/XPathTokenAnywhereElement.h
Executable 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
|
||||
33
runtime-linux/antlr4-runtime/tree/xpath/XPathTokenElement.cpp
Executable file
33
runtime-linux/antlr4-runtime/tree/xpath/XPathTokenElement.cpp
Executable 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;
|
||||
}
|
||||
26
runtime-linux/antlr4-runtime/tree/xpath/XPathTokenElement.h
Executable file
26
runtime-linux/antlr4-runtime/tree/xpath/XPathTokenElement.h
Executable 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
|
||||
23
runtime-linux/antlr4-runtime/tree/xpath/XPathWildcardAnywhereElement.cpp
Executable file
23
runtime-linux/antlr4-runtime/tree/xpath/XPathWildcardAnywhereElement.cpp
Executable 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);
|
||||
}
|
||||
23
runtime-linux/antlr4-runtime/tree/xpath/XPathWildcardAnywhereElement.h
Executable file
23
runtime-linux/antlr4-runtime/tree/xpath/XPathWildcardAnywhereElement.h
Executable 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
|
||||
24
runtime-linux/antlr4-runtime/tree/xpath/XPathWildcardElement.cpp
Executable file
24
runtime-linux/antlr4-runtime/tree/xpath/XPathWildcardElement.cpp
Executable 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;
|
||||
}
|
||||
23
runtime-linux/antlr4-runtime/tree/xpath/XPathWildcardElement.h
Executable file
23
runtime-linux/antlr4-runtime/tree/xpath/XPathWildcardElement.h
Executable 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
|
||||
Reference in New Issue
Block a user