Merge pull request #1 from tree-sitter/c++99

Make the scanner compile without C++11 features
This commit is contained in:
Ashi Krishnan 2018-06-15 19:40:41 -04:00 committed by GitHub
commit bd235b794b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 156 additions and 148 deletions

View File

@ -26,15 +26,16 @@ struct Scanner {
unsigned serialize(char *buffer) { unsigned serialize(char *buffer) {
unsigned i = 0; unsigned i = 0;
for (Tag &tag : tags) {
for (unsigned j = 0, n = tags.size(); j < n; j++) {
Tag &tag = tags[j];
buffer[i] = static_cast<char>(tag.type); buffer[i] = static_cast<char>(tag.type);
i++; i++;
if (tag.type == CUSTOM) { if (tag.type == CUSTOM) {
buffer[i++] = tag.custom_tag_name.size(); buffer[i++] = tag.custom_tag_name.size();
for (char c : tag.custom_tag_name) { tag.custom_tag_name.copy(&buffer[i], tag.custom_tag_name.size());
buffer[i++] = c; i += tag.custom_tag_name.size();
}
} }
} }
@ -46,13 +47,12 @@ struct Scanner {
unsigned i = 0; unsigned i = 0;
while (i < length) { while (i < length) {
Tag tag { static_cast<TagType>(buffer[i]), "" }; Tag tag(static_cast<TagType>(buffer[i]), "");
i++; i++;
if (tag.type == CUSTOM) { if (tag.type == CUSTOM) {
tag.custom_tag_name.resize(buffer[i++]); unsigned length = buffer[i++];
for (unsigned j = 0; j < tag.custom_tag_name.size(); j++) { tag.custom_tag_name.assign(&buffer[i], &buffer[i + length]);
tag.custom_tag_name[j] = buffer[i++]; i += length;
}
} }
tags.push_back(tag); tags.push_back(tag);
} }
@ -74,9 +74,8 @@ struct Scanner {
lexer->advance(lexer, false); lexer->advance(lexer, false);
unsigned dashes = 0; unsigned dashes = 0;
auto c = lexer->lookahead; while (lexer->lookahead) {
while (c) { switch (lexer->lookahead) {
switch (c) {
case '-': case '-':
++dashes; ++dashes;
break; break;
@ -92,7 +91,6 @@ struct Scanner {
dashes = 0; dashes = 0;
} }
lexer->advance(lexer, false); lexer->advance(lexer, false);
c = lexer->lookahead;
} }
return false; return false;
} }
@ -137,7 +135,7 @@ struct Scanner {
} }
} }
auto tag_name = scan_tag_name(lexer); string tag_name = scan_tag_name(lexer);
if (tag_name.empty()) return false; if (tag_name.empty()) return false;
Tag next_tag = Tag::for_name(tag_name); Tag next_tag = Tag::for_name(tag_name);
@ -163,7 +161,7 @@ struct Scanner {
} }
bool scan_start_tag_name(TSLexer *lexer) { bool scan_start_tag_name(TSLexer *lexer) {
auto tag_name = scan_tag_name(lexer); string tag_name = scan_tag_name(lexer);
if (tag_name.empty()) return false; if (tag_name.empty()) return false;
Tag tag = Tag::for_name(tag_name); Tag tag = Tag::for_name(tag_name);
tags.push_back(tag); tags.push_back(tag);
@ -176,7 +174,7 @@ struct Scanner {
} }
bool scan_end_tag_name(TSLexer *lexer) { bool scan_end_tag_name(TSLexer *lexer) {
auto tag_name = scan_tag_name(lexer); string tag_name = scan_tag_name(lexer);
if (tag_name.empty()) return false; if (tag_name.empty()) return false;
Tag tag = Tag::for_name(tag_name); Tag tag = Tag::for_name(tag_name);
if (!tags.empty() && tags.back() == tag) { if (!tags.empty() && tags.back() == tag) {

274
src/tag.h
View File

@ -4,7 +4,7 @@
using std::string; using std::string;
using std::unordered_map; using std::unordered_map;
enum TagType : char { enum TagType {
AREA, AREA,
BASE, BASE,
BASEFONT, BASEFONT,
@ -136,133 +136,140 @@ enum TagType : char {
CUSTOM, CUSTOM,
}; };
static const unordered_map<string, TagType> TAG_TYPES_BY_TAG_NAME = {
{"AREA", AREA}, static const unordered_map<string, TagType> get_tag_map() {
{"BASE", BASE}, unordered_map<string, TagType> result;
{"BASEFONT", BASEFONT}, #define TAG(name) result[#name] = name
{"BGSOUND", BGSOUND}, TAG(AREA);
{"BR", BR}, TAG(BASE);
{"COL", COL}, TAG(BASEFONT);
{"COMMAND", COMMAND}, TAG(BGSOUND);
{"EMBED", EMBED}, TAG(BR);
{"FRAME", FRAME}, TAG(COL);
{"HR", HR}, TAG(COMMAND);
{"IMAGE", IMAGE}, TAG(EMBED);
{"IMG", IMG}, TAG(FRAME);
{"INPUT", INPUT}, TAG(HR);
{"ISINDEX", ISINDEX}, TAG(IMAGE);
{"KEYGEN", KEYGEN}, TAG(IMG);
{"LINK", LINK}, TAG(INPUT);
{"MENUITEM", MENUITEM}, TAG(ISINDEX);
{"META", META}, TAG(KEYGEN);
{"NEXTID", NEXTID}, TAG(LINK);
{"PARAM", PARAM}, TAG(MENUITEM);
{"SOURCE", SOURCE}, TAG(META);
{"TRACK", TRACK}, TAG(NEXTID);
{"WBR", WBR}, TAG(PARAM);
{"A", A}, TAG(SOURCE);
{"ABBR", ABBR}, TAG(TRACK);
{"ADDRESS", ADDRESS}, TAG(WBR);
{"ARTICLE", ARTICLE}, TAG(A);
{"ASIDE", ASIDE}, TAG(ABBR);
{"AUDIO", AUDIO}, TAG(ADDRESS);
{"B", B}, TAG(ARTICLE);
{"BDI", BDI}, TAG(ASIDE);
{"BDO", BDO}, TAG(AUDIO);
{"BLOCKQUOTE", BLOCKQUOTE}, TAG(B);
{"BODY", BODY}, TAG(BDI);
{"BUTTON", BUTTON}, TAG(BDO);
{"CANVAS", CANVAS}, TAG(BLOCKQUOTE);
{"CAPTION", CAPTION}, TAG(BODY);
{"CITE", CITE}, TAG(BUTTON);
{"CODE", CODE}, TAG(CANVAS);
{"COLGROUP", COLGROUP}, TAG(CAPTION);
{"DATA", DATA}, TAG(CITE);
{"DATALIST", DATALIST}, TAG(CODE);
{"DD", DD}, TAG(COLGROUP);
{"DEL", DEL}, TAG(DATA);
{"DETAILS", DETAILS}, TAG(DATALIST);
{"DFN", DFN}, TAG(DD);
{"DIALOG", DIALOG}, TAG(DEL);
{"DIV", DIV}, TAG(DETAILS);
{"DL", DL}, TAG(DFN);
{"DT", DT}, TAG(DIALOG);
{"EM", EM}, TAG(DIV);
{"FIELDSET", FIELDSET}, TAG(DL);
{"FIGCAPTION", FIGCAPTION}, TAG(DT);
{"FIGURE", FIGURE}, TAG(EM);
{"FOOTER", FOOTER}, TAG(FIELDSET);
{"FORM", FORM}, TAG(FIGCAPTION);
{"H1", H1}, TAG(FIGURE);
{"H2", H2}, TAG(FOOTER);
{"H3", H3}, TAG(FORM);
{"H4", H4}, TAG(H1);
{"H5", H5}, TAG(H2);
{"H6", H6}, TAG(H3);
{"HEAD", HEAD}, TAG(H4);
{"HEADER", HEADER}, TAG(H5);
{"HGROUP", HGROUP}, TAG(H6);
{"HTML", HTML}, TAG(HEAD);
{"I", I}, TAG(HEADER);
{"IFRAME", IFRAME}, TAG(HGROUP);
{"INS", INS}, TAG(HTML);
{"KBD", KBD}, TAG(I);
{"LABEL", LABEL}, TAG(IFRAME);
{"LEGEND", LEGEND}, TAG(INS);
{"LI", LI}, TAG(KBD);
{"MAIN", MAIN}, TAG(LABEL);
{"MAP", MAP}, TAG(LEGEND);
{"MARK", MARK}, TAG(LI);
{"MATH", MATH}, TAG(MAIN);
{"MENU", MENU}, TAG(MAP);
{"METER", METER}, TAG(MARK);
{"NAV", NAV}, TAG(MATH);
{"NOSCRIPT", NOSCRIPT}, TAG(MENU);
{"OBJECT", OBJECT}, TAG(METER);
{"OL", OL}, TAG(NAV);
{"OPTGROUP", OPTGROUP}, TAG(NOSCRIPT);
{"OPTION", OPTION}, TAG(OBJECT);
{"OUTPUT", OUTPUT}, TAG(OL);
{"P", P}, TAG(OPTGROUP);
{"PICTURE", PICTURE}, TAG(OPTION);
{"PRE", PRE}, TAG(OUTPUT);
{"PROGRESS", PROGRESS}, TAG(P);
{"Q", Q}, TAG(PICTURE);
{"RB", RB}, TAG(PRE);
{"RP", RP}, TAG(PROGRESS);
{"RT", RT}, TAG(Q);
{"RTC", RTC}, TAG(RB);
{"RUBY", RUBY}, TAG(RP);
{"S", S}, TAG(RT);
{"SAMP", SAMP}, TAG(RTC);
{"SCRIPT", SCRIPT}, TAG(RUBY);
{"SECTION", SECTION}, TAG(S);
{"SELECT", SELECT}, TAG(SAMP);
{"SLOT", SLOT}, TAG(SCRIPT);
{"SMALL", SMALL}, TAG(SECTION);
{"SPAN", SPAN}, TAG(SELECT);
{"STRONG", STRONG}, TAG(SLOT);
{"STYLE", STYLE}, TAG(SMALL);
{"SUB", SUB}, TAG(SPAN);
{"SUMMARY", SUMMARY}, TAG(STRONG);
{"SUP", SUP}, TAG(STYLE);
{"SVG", SVG}, TAG(SUB);
{"TABLE", TABLE}, TAG(SUMMARY);
{"TBODY", TBODY}, TAG(SUP);
{"TD", TD}, TAG(SVG);
{"TEMPLATE", TEMPLATE}, TAG(TABLE);
{"TEXTAREA", TEXTAREA}, TAG(TBODY);
{"TFOOT", TFOOT}, TAG(TD);
{"TH", TH}, TAG(TEMPLATE);
{"THEAD", THEAD}, TAG(TEXTAREA);
{"TIME", TIME}, TAG(TFOOT);
{"TITLE", TITLE}, TAG(TH);
{"TR", TR}, TAG(THEAD);
{"U", U}, TAG(TIME);
{"UL", UL}, TAG(TITLE);
{"VAR", VAR}, TAG(TR);
{"VIDEO", VIDEO}, TAG(U);
}; TAG(UL);
TAG(VAR);
TAG(VIDEO);
#undef TAG
return result;
}
static const unordered_map<string, TagType> TAG_TYPES_BY_TAG_NAME = get_tag_map();
static const TagType TAG_TYPES_NOT_ALLOWED_IN_PARAGRAPHS[] = { static const TagType TAG_TYPES_NOT_ALLOWED_IN_PARAGRAPHS[] = {
ADDRESS, ADDRESS,
@ -303,9 +310,11 @@ struct Tag {
TagType type; TagType type;
string custom_tag_name; string custom_tag_name;
Tag(TagType type, const string &name) : type(type), custom_tag_name(name) {}
bool operator==(const Tag &other) const { bool operator==(const Tag &other) const {
if (type != other.type) return false; if (type != other.type) return false;
if (type == TagType::CUSTOM && custom_tag_name != other.custom_tag_name) return false; if (type == CUSTOM && custom_tag_name != other.custom_tag_name) return false;
return true; return true;
} }
@ -358,10 +367,11 @@ struct Tag {
} }
static inline Tag for_name(const string &name) { static inline Tag for_name(const string &name) {
auto type = TAG_TYPES_BY_TAG_NAME.find(name); unordered_map<string, TagType>::const_iterator type = TAG_TYPES_BY_TAG_NAME.find(name);
if (type != TAG_TYPES_BY_TAG_NAME.end()) { if (type != TAG_TYPES_BY_TAG_NAME.end()) {
return Tag { type->second, "" }; return Tag(type->second, string());
} else {
return Tag(CUSTOM, name);
} }
return Tag { CUSTOM, name };
} }
}; };