mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-27 09:12:40 +01:00
8e0e07664a
Summary: Ref T13098. Historically, Phabricator was split into three parts: - Phabricator, the server. - Arcanist, the client. - libphutil, libraries shared between the client and server. One imagined use case for this was that `libphutil` might become a general-purpose library that other projects would use. However, this didn't really happen, and it seems unlikely to at this point: Phabricator has become a relatively more sophisticated application platform; we didn't end up seeing or encouraging much custom development; what custom development there is basically embraces all of Phabricator since there are huge advantages to doing so; and a general "open source is awful" sort of factor here in the sense that open source users often don't have goals well aligned to our goals. Turning "arc" into a client platform and building package management solidify us in this direction of being a standalone platform, not a standalone utility library. Phabricator also depends on `arcanist/`. If it didn't, there would be a small advantage to saying "shared code + client for client, shared code + server for server", but there's no such distinction and it seems unlikely that one will ever exist. Even if it did, I think this has little value. Nowadays, I think this separation has no advantages for us and one significant cost: it makes installing `arcanist` more difficult for end-users. This will need some more finesssing (Phabricator will need some changes for compatibility, and a lot of stuff that still says "libphutil" or "phutil" may eventually want to say "arcanist"), and some stuff (like xhpast) is probably straight-up broken right now and needs some tweaking, but I don't anticipate any major issues here. There was never anything particularly magical about libphutil as a separate standalone library. Test Plan: Ran `arc`, it gets about as far as it did before. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13098 Differential Revision: https://secure.phabricator.com/D19688
121 lines
2.7 KiB
C++
121 lines
2.7 KiB
C++
#include "ast.hpp"
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
using namespace std;
|
|
|
|
int xhpastparse(void*, xhpast::Node **);
|
|
|
|
int xhpast_process(std::string &in);
|
|
void print_node(xhpast::Node *node);
|
|
|
|
int main(int argc, char* argv[]) {
|
|
if (argc != 1) {
|
|
// Coupling: modify also src/parser/xhpast/bin/PhutilXHPASTBinary.php
|
|
cout << "7.1.2\n";
|
|
return 0;
|
|
}
|
|
|
|
ifstream inputFile;
|
|
istream *inputStream;
|
|
inputStream = &cin;
|
|
|
|
std::stringbuf sb;
|
|
*inputStream >> noskipws >> &sb;
|
|
std::string buffer = sb.str();
|
|
inputFile.close();
|
|
|
|
return xhpast_process(buffer);
|
|
}
|
|
|
|
int xhpast_process(std::string &in) {
|
|
|
|
char *buffer;
|
|
in.reserve(in.size() + 1);
|
|
buffer = const_cast<char*>(in.c_str());
|
|
buffer[in.size() + 1] = 0; // need double NULL for scan_buffer
|
|
|
|
void* scanner;
|
|
yy_extra_type extra;
|
|
extra.insert_token = 0;//flags.eval ? T_OPEN_TAG_FAKE : 0;
|
|
|
|
xhpast::Node *root = NULL;
|
|
|
|
xhpastlex_init(&scanner);
|
|
xhpastset_extra(&extra, scanner);
|
|
xhpast_scan_buffer(buffer, in.size() + 2, scanner);
|
|
xhpastparse(scanner, &root);
|
|
xhpastlex_destroy(scanner);
|
|
|
|
if (extra.terminated) {
|
|
fprintf(
|
|
stderr,
|
|
"XHPAST Parse Error: %s on line %d\n",
|
|
extra.error.c_str(),
|
|
(int)extra.lineno);
|
|
return 1;
|
|
}
|
|
|
|
printf("{");
|
|
printf("\"tree\":");
|
|
if (root) {
|
|
// Extend the right token for the root node to the end of the concrete
|
|
// token stream. This ensure all tokens appear in the tree. If we don't
|
|
// do this and the file ends in tokens which don't go to the parser (like
|
|
// comments and whitespace) they won't be represented in the tree.
|
|
root->r_tok = (extra.token_list.size() - 1);
|
|
print_node(root);
|
|
} else {
|
|
printf("null");
|
|
}
|
|
printf(",");
|
|
printf("\"stream\":");
|
|
printf("[");
|
|
|
|
if (!extra.token_list.empty()) {
|
|
for (xhpast::token_list_t::iterator ii = extra.token_list.begin();;) {
|
|
printf("[%d, %d]", (*ii)->type, (int)(*ii)->value.length());
|
|
if (++ii != extra.token_list.end()) {
|
|
printf(",");
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
printf("]");
|
|
printf("}\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
void print_node(xhpast::Node *node) {
|
|
int l = -1;
|
|
if (node->l_tok != -1) {
|
|
l = node->l_tok;
|
|
}
|
|
|
|
if (l == -1) {
|
|
printf("[%u]", node->type);
|
|
} else {
|
|
int r = -1;
|
|
|
|
if (node->r_tok != -1) {
|
|
r = node->r_tok;
|
|
}
|
|
|
|
printf("[%u, %d, %d", node->type, l, r);
|
|
if (!node->children.empty()) {
|
|
printf(", [");
|
|
for (xhpast::node_list_t::iterator ii = node->children.begin();;) {
|
|
print_node(*ii);
|
|
if (++ii != node->children.end()) {
|
|
printf(",");
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
printf("]");
|
|
}
|
|
printf("]");
|
|
}
|
|
}
|