Chromium Code Reviews| Index: content/test/data/tree_parser_util.js |
| diff --git a/content/test/data/tree_parser_util.js b/content/test/data/tree_parser_util.js |
| index 4f83fddab07451f56358012bf81bbd9d6919171a..661f2419230b37a2c65c091ffe53974460c656cd 100644 |
| --- a/content/test/data/tree_parser_util.js |
| +++ b/content/test/data/tree_parser_util.js |
| @@ -36,6 +36,15 @@ |
| * // ]} |
| * TreeParserUtil.parse('e(f(g(h(),i(j))))'; |
| * |
| + * @example <caption>Tree nodes can also have attributes, which are a comma- |
| + * separated list of identifiers, surrounded by braces, after the node name. |
| + * </caption> |
| + * // returns { value: 'b', attributes: [red,blue], children: [ |
| + * // { value: 'c', children: [] }, |
| + * // { value: 'd', attributes: [green], children: [] } |
| + * // ]} |
| + * TreeParserUtil.parse('b{red,blue}(c,d{green})'; |
|
ncarter (slow)
2017/05/05 22:34:05
So it turns out that I did write unittests for thi
iclelland
2017/05/06 03:03:10
Thanks! I will definitely take a look.
|
| + * |
| * @example <caption>flatten() converts a [sub]tree back to a string.</caption> |
| * var tree = TreeParserUtil.parse('b.com (c.com(e.com), d.com)'); |
| * TreeParserUtil.flatten(tree.children[0]); // returns 'c.com(e.com())' |
| @@ -62,7 +71,10 @@ var TreeParserUtil = (function() { |
| * used to forward a subtree as an argument to a nested document. |
| */ |
| function flatten(tree) { |
| - return tree.value + '(' + tree.children.map(flatten).join(',') + ')'; |
| + var result = tree.value; |
| + if (tree.attributes && tree.attributes.length) |
| + result += '{' + tree.attributes.join(",") + "}"; |
| + return result + '(' + tree.children.map(flatten).join(',') + ')'; |
| } |
| /** |
| @@ -74,7 +86,7 @@ var TreeParserUtil = (function() { |
| * @return {Array.<string>} The resulting token stream. |
| */ |
| function lex(input) { |
| - return input.split(/(\s+|\(|\)|,)/).reduce( |
| + return input.split(/(\s+|\(|\)|{|}|,)/).reduce( |
| function (resultArray, token) { |
| var trimmed = token.trim(); |
| if (trimmed) { |
| @@ -84,13 +96,13 @@ var TreeParserUtil = (function() { |
| }, []); |
| } |
| - |
| /** |
| * Consumes from the stream an identifier and optional child list, returning |
| * its parsed representation. |
| */ |
| function takeIdAndChild(tokenStream) { |
| return { value: takeIdentifier(tokenStream), |
| + attributes: takeAttributeList(tokenStream), |
|
ncarter (slow)
2017/05/05 22:34:05
The jsdoc suggests that attributes here will be om
iclelland
2017/05/06 03:03:10
Updated.
|
| children: takeChildList(tokenStream) }; |
| } |
| @@ -101,12 +113,52 @@ var TreeParserUtil = (function() { |
| if (tokenStream.length == 0) |
| throw new Error('Expected an identifier, but found end-of-stream.'); |
| var token = tokenStream.shift(); |
| - if (!token.match(/[a-zA-Z0-9.-]+/)) |
| + if (!token.match(/^[a-zA-Z0-9.-]+$/)) |
| throw new Error('Expected an identifier, but found "' + token + '".'); |
| return token; |
| } |
| /** |
| + * Consumes an optional attribute list from the token stream, returning a list |
| + * of the parsed attribute identifiers. |
| + */ |
| + function takeAttributeList(tokenStream) { |
| + // Remove the next token from the stream if it matches |token|. |
| + function tryToEatA(token) { |
| + if (tokenStream[0] == token) { |
| + tokenStream.shift(); |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + // Bare identifier case, as in 'b' in the input '(a (b, c))' |
| + if (!tryToEatA('{')) |
| + return []; |
| + |
| + // Empty list case, as in 'b' in the input 'a (b {}, c)'. |
| + if (tryToEatA('}')) { |
| + return []; |
| + } |
| + |
| + // List with at least one entry. |
| + var result = [ takeIdentifier(tokenStream) ]; |
| + |
| + // Additional entries allowed with comman. |
|
ncarter (slow)
2017/05/05 22:34:05
comman -> comma
iclelland
2017/05/06 03:03:10
Thanks, done
|
| + while (tryToEatA(',')) { |
| + result.push(takeIdentifier(tokenStream)); |
| + } |
| + |
| + // End of list. |
| + if (tryToEatA('}')) { |
| + return result; |
| + } |
| + if (tokenStream.length == 0) |
| + throw new Error('Expected "}" or ",", but found end-of-stream.'); |
| + throw new Error('Expected "}" or ",", but found "' + tokenStream[0] + '".'); |
| + } |
| + |
| + /** |
| * Consumes an optional child list from the token stream, returning a list of |
| * the parsed children. |
| */ |