Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Unified Diff: utils/template/parser.dart

Issue 137013002: Removed obsolete code (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Removed libraries not used Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « utils/template/htmltree.dart ('k') | utils/template/source.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utils/template/parser.dart
diff --git a/utils/template/parser.dart b/utils/template/parser.dart
deleted file mode 100644
index 9f23d8a9931de613cc27821de51af3e6b7a1a66e..0000000000000000000000000000000000000000
--- a/utils/template/parser.dart
+++ /dev/null
@@ -1,720 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-
-class TagStack {
- List<ASTNode> _stack;
-
- TagStack(var elem) : _stack = [] {
- _stack.add(elem);
- }
-
- void push(var elem) {
- _stack.add(elem);
- }
-
- ASTNode pop() {
- return _stack.removeLast();
- }
-
- top() {
- return _stack.last;
- }
-}
-
-// TODO(terry): Cleanup returning errors from CSS to common World error
-// handler.
-class ErrorMsgRedirector {
- void displayError(String msg) {
- if (world.printHandler != null) {
- world.printHandler(msg);
- } else {
- print("Unhandler Error: ${msg}");
- }
- world.errors++;
- }
-}
-
-/**
- * A simple recursive descent parser for HTML.
- */
-class Parser {
- Tokenizer tokenizer;
-
- var _fs; // If non-null filesystem to read files.
-
- final SourceFile source;
-
- Token _previousToken;
- Token _peekToken;
-
- PrintHandler printHandler;
-
- Parser(this.source, [int start = 0, this._fs = null]) {
- tokenizer = new Tokenizer(source, true, start);
- _peekToken = tokenizer.next();
- _previousToken = null;
- }
-
- // Main entry point for parsing an entire HTML file.
- List<Template> parse([PrintHandler handler = null]) {
- printHandler = handler;
-
- List<Template> productions = [];
-
- int start = _peekToken.start;
- while (!_maybeEat(TokenKind.END_OF_FILE)) {
- Template template = processTemplate();
- if (template != null) {
- productions.add(template);
- }
- }
-
- return productions;
- }
-
- /** Generate an error if [source] has not been completely consumed. */
- void checkEndOfFile() {
- _eat(TokenKind.END_OF_FILE);
- }
-
- /** Guard to break out of parser when an unexpected end of file is found. */
- // TODO(jimhug): Failure to call this method can lead to inifinite parser
- // loops. Consider embracing exceptions for more errors to reduce
- // the danger here.
- bool isPrematureEndOfFile() {
- if (_maybeEat(TokenKind.END_OF_FILE)) {
- _error('unexpected end of file', _peekToken.span);
- return true;
- } else {
- return false;
- }
- }
-
- ///////////////////////////////////////////////////////////////////
- // Basic support methods
- ///////////////////////////////////////////////////////////////////
- int _peek() {
- return _peekToken.kind;
- }
-
- Token _next([bool inTag = true]) {
- _previousToken = _peekToken;
- _peekToken = tokenizer.next(inTag);
- return _previousToken;
- }
-
- bool _peekKind(int kind) {
- return _peekToken.kind == kind;
- }
-
- /* Is the next token a legal identifier? This includes pseudo-keywords. */
- bool _peekIdentifier([String name = null]) {
- if (TokenKind.isIdentifier(_peekToken.kind)) {
- return (name != null) ? _peekToken.text == name : true;
- }
-
- return false;
- }
-
- bool _maybeEat(int kind) {
- if (_peekToken.kind == kind) {
- _previousToken = _peekToken;
- if (kind == TokenKind.GREATER_THAN) {
- _peekToken = tokenizer.next(false);
- } else {
- _peekToken = tokenizer.next();
- }
- return true;
- } else {
- return false;
- }
- }
-
- void _eat(int kind) {
- if (!_maybeEat(kind)) {
- _errorExpected(TokenKind.kindToString(kind));
- }
- }
-
- void _eatSemicolon() {
- _eat(TokenKind.SEMICOLON);
- }
-
- void _errorExpected(String expected) {
- var tok = _next();
- var message;
- try {
- message = 'expected $expected, but found $tok';
- } catch (e) {
- message = 'parsing error expected $expected';
- }
- _error(message, tok.span);
- }
-
- void _error(String message, [SourceSpan location=null]) {
- if (location == null) {
- location = _peekToken.span;
- }
-
- if (printHandler == null) {
- world.fatal(message, location); // syntax errors are fatal for now
- } else {
- // TODO(terry): Need common World view for css and template parser.
- // For now this is how we return errors from CSS - ugh.
- printHandler(message);
- }
- }
-
- void _warning(String message, [SourceSpan location=null]) {
- if (location == null) {
- location = _peekToken.span;
- }
-
- if (printHandler == null) {
- world.warning(message, location);
- } else {
- // TODO(terry): Need common World view for css and template parser.
- // For now this is how we return errors from CSS - ugh.
- printHandler(message);
- }
- }
-
- SourceSpan _makeSpan(int start) {
- return new SourceSpan(source, start, _previousToken.end);
- }
-
- ///////////////////////////////////////////////////////////////////
- // Top level productions
- ///////////////////////////////////////////////////////////////////
-
- Template processTemplate() {
- var template;
-
- int start = _peekToken.start;
-
- // Handle the template keyword followed by template signature.
- _eat(TokenKind.TEMPLATE_KEYWORD);
-
- if (_peekIdentifier()) {
- final templateName = identifier();
-
- List<Map<Identifier, Identifier>> params =
- new List<Map<Identifier, Identifier>>();
-
- _eat(TokenKind.LPAREN);
-
- start = _peekToken.start;
- while (true) {
- // TODO(terry): Need robust Dart argument parser (e.g.,
- // List<String> arg1, etc).
- var type = processAsIdentifier();
- var paramName = processAsIdentifier();
- if (type != null && paramName != null) {
- params.add({'type': type, 'name' : paramName});
-
- if (!_maybeEat(TokenKind.COMMA)) {
- break;
- }
- } else {
- // No parameters we're done.
- break;
- }
- }
-
- _eat(TokenKind.RPAREN);
-
- TemplateSignature sig =
- new TemplateSignature(templateName.name, params, _makeSpan(start));
-
- TemplateContent content = processTemplateContent();
-
- template = new Template(sig, content, _makeSpan(start));
- }
-
- return template;
- }
-
- // All tokens are identifiers tokenizer is geared to HTML if identifiers are
- // HTML element or attribute names we need them as an identifier. Used by
- // template signatures and expressions in ${...}
- Identifier processAsIdentifier() {
- int start = _peekToken.start;
-
- if (_peekIdentifier()) {
- return identifier();
- } else if (TokenKind.validTagName(_peek())) {
- var tok = _next();
- return new Identifier(TokenKind.tagNameFromTokenId(tok.kind),
- _makeSpan(start));
- }
- }
-
- css.Stylesheet processCSS() {
- // Is there a CSS block?
- if (_peekIdentifier('css')) {
- _next();
-
- int start = _peekToken.start;
- _eat(TokenKind.LBRACE);
-
- css.Stylesheet cssCtx = processCSSContent(source, tokenizer.startIndex);
-
- // TODO(terry): Hack, restart template parser where CSS parser stopped.
- tokenizer.index = lastCSSIndexParsed;
- _next(false);
-
- _eat(TokenKind.RBRACE); // close } of css block
-
- return cssCtx;
- }
- }
-
- // TODO(terry): get should be able to use all template control flow but return
- // a string instead of a node. Maybe expose both html and get
- // e.g.,
- //
- // A.)
- // html {
- // <div>...</div>
- // }
- //
- // B.)
- // html foo() {
- // <div>..</div>
- // }
- //
- // C.)
- // get {
- // <div>...</div>
- // }
- //
- // D.)
- // get foo {
- // <div>..</div>
- // }
- //
- // Only one default allower either A or C the constructor will
- // generate a string or a node.
- // Examples B and D would generate getters that either return
- // a node for B or a String for D.
- //
- List<TemplateGetter> processGetters() {
- List<TemplateGetter> getters = [];
-
- while (true) {
- if (_peekIdentifier('get')) {
- _next();
-
- int start = _peekToken.start;
- if (_peekIdentifier()) {
- String getterName = identifier().name;
-
- List<Map<Identifier, Identifier>> params =
- new List<Map<Identifier, Identifier>>();
-
- _eat(TokenKind.LPAREN);
-
- start = _peekToken.start;
- while (true) {
- // TODO(terry): Need robust Dart argument parser (e.g.,
- // List<String> arg1, etc).
- var type = processAsIdentifier();
- var paramName = processAsIdentifier();
- if (paramName == null && type != null) {
- paramName = type;
- type = "";
- }
- if (type != null && paramName != null) {
- params.add({'type': type, 'name' : paramName});
-
- if (!_maybeEat(TokenKind.COMMA)) {
- break;
- }
- } else {
- // No parameters we're done.
- break;
- }
- }
-
- _eat(TokenKind.RPAREN);
-
- _eat(TokenKind.LBRACE);
-
- var elems = new TemplateElement.fragment(_makeSpan(_peekToken.start));
- var templateDoc = processHTML(elems);
-
- _eat(TokenKind.RBRACE); // close } of get block
-
- getters.add(new TemplateGetter(getterName, params, templateDoc,
- _makeSpan(_peekToken.start)));
- }
- } else {
- break;
- }
- }
-
- return getters;
-
-/*
- get newTotal(value) {
- <div class="alignleft">${value}</div>
- }
-
- String get HTML_newTotal(value) {
- return '<div class="alignleft">${value}</div>
- }
-
-*/
- }
-
- TemplateContent processTemplateContent() {
- css.Stylesheet ss;
-
- _eat(TokenKind.LBRACE);
-
- int start = _peekToken.start;
-
- ss = processCSS();
-
- // TODO(terry): getters should be allowed anywhere not just after CSS.
- List<TemplateGetter> getters = processGetters();
-
- var elems = new TemplateElement.fragment(_makeSpan(_peekToken.start));
- var templateDoc = processHTML(elems);
-
- // TODO(terry): Should allow css { } to be at beginning or end of the
- // template's content. Today css only allow at beginning
- // because the css {...} is sucked in as a text node. We'll
- // need a special escape for css maybe:
- //
- // ${#css}
- // ${/css}
- //
- // uggggly!
-
-
- _eat(TokenKind.RBRACE);
-
- return new TemplateContent(ss, templateDoc, getters, _makeSpan(start));
- }
-
- int lastCSSIndexParsed; // TODO(terry): Hack, last good CSS parsed.
-
- css.Stylesheet processCSSContent(var cssSource, int start) {
- try {
- css.Parser parser = new css.Parser(new SourceFile(
- SourceFile.IN_MEMORY_FILE, cssSource.text), start);
-
- css.Stylesheet stylesheet = parser.parse(false, new ErrorMsgRedirector());
-
- var lastParsedChar = parser.tokenizer.startIndex;
-
- lastCSSIndexParsed = lastParsedChar;
-
- return stylesheet;
- } catch (cssParseException) {
- // TODO(terry): Need SourceSpan from CSS parser to pass onto _error.
- _error("Unexcepted CSS error: ${cssParseException.toString()}");
- }
- }
-
- /* TODO(terry): Assume template { }, single close curley as a text node
- * inside of the template would need to be escaped maybe \}
- */
- processHTML(TemplateElement root) {
- assert(root.isFragment);
- TagStack stack = new TagStack(root);
-
- int start = _peekToken.start;
-
- bool done = false;
- while (!done) {
- if (_maybeEat(TokenKind.LESS_THAN)) {
- // Open tag
- start = _peekToken.start;
-
- if (TokenKind.validTagName(_peek())) {
- Token tagToken = _next();
-
- Map<String, TemplateAttribute> attrs = processAttributes();
-
- String varName;
- if (attrs.containsKey('var')) {
- varName = attrs['var'].value;
- attrs.remove('var');
- }
-
- int scopeType; // 1 implies scoped, 2 implies non-scoped element.
- if (_maybeEat(TokenKind.GREATER_THAN)) {
- // Scoped unless the tag is explicitly known as an unscoped tag
- // e.g., <br>.
- scopeType = TokenKind.unscopedTag(tagToken.kind) ? 2 : 1;
- } else if (_maybeEat(TokenKind.END_NO_SCOPE_TAG)) {
- scopeType = 2;
- }
- if (scopeType > 0) {
- var elem = new TemplateElement.attributes(tagToken.kind,
- attrs.values.toList(), varName, _makeSpan(start));
- stack.top().add(elem);
-
- if (scopeType == 1) {
- // Maybe more nested tags/text?
- stack.push(elem);
- }
- }
- } else {
- // Close tag
- _eat(TokenKind.SLASH);
- if (TokenKind.validTagName(_peek())) {
- Token tagToken = _next();
-
- _eat(TokenKind.GREATER_THAN);
-
- var elem = stack.pop();
- if (elem is TemplateElement && !elem.isFragment) {
- if (elem.tagTokenId != tagToken.kind) {
- _error('Tag doesn\'t match expected </${elem.tagName}> got ' +
- '</${TokenKind.tagNameFromTokenId(tagToken.kind)}>');
- }
- } else {
- // Too many end tags.
- _error('Too many end tags at ' +
- '</${TokenKind.tagNameFromTokenId(tagToken.kind)}>');
- }
- }
- }
- } else if (_maybeEat(TokenKind.START_COMMAND)) {
- Identifier commandName = processAsIdentifier();
- if (commandName != null) {
- switch (commandName.name) {
- case "each":
- case "with":
- var listName = processAsIdentifier();
- if (listName != null) {
- var loopItem = processAsIdentifier();
- // Is the optional item name specified?
- // #each lists [item]
- // #with expression [item]
-
- _eat(TokenKind.RBRACE);
-
- var frag = new TemplateElement.fragment(
- _makeSpan(_peekToken.start));
- TemplateDocument docFrag = processHTML(frag);
-
- if (docFrag != null) {
- var span = _makeSpan(start);
- var cmd;
- if (commandName.name == "each") {
- cmd = new TemplateEachCommand(listName, loopItem, docFrag,
- span);
- } else if (commandName.name == "with") {
- cmd = new TemplateWithCommand(listName, loopItem, docFrag,
- span);
- }
-
- stack.top().add(cmd);
- stack.push(cmd);
- }
-
- // Process ${/commandName}
- _eat(TokenKind.END_COMMAND);
-
- // Close command ${/commandName}
- if (_peekIdentifier()) {
- commandName = identifier();
- switch (commandName.name) {
- case "each":
- case "with":
- case "if":
- case "else":
- break;
- default:
- _error('Unknown command \${#${commandName}}');
- }
- var elem = stack.pop();
- if (elem is TemplateEachCommand &&
- commandName.name == "each") {
-
- } else if (elem is TemplateWithCommand &&
- commandName.name == "with") {
-
- } /*else if (elem is TemplateIfCommand && commandName == "if") {
-
- }
- */else {
- String expectedCmd;
- if (elem is TemplateEachCommand) {
- expectedCmd = "\${/each}";
- } /* TODO(terry): else other commands as well */
- _error('mismatched command expected ${expectedCmd} got...');
- return;
- }
- _eat(TokenKind.RBRACE);
- } else {
- _error('Missing command name \${/commandName}');
- }
- } else {
- _error("Missing listname for #each command");
- }
- break;
- case "if":
- break;
- case "else":
- break;
- default:
- // Calling another template.
- int startPos = this._previousToken.end;
- // Gobble up everything until we hit }
- while (_peek() != TokenKind.RBRACE &&
- _peek() != TokenKind.END_OF_FILE) {
- _next(false);
- }
-
- if (_peek() == TokenKind.RBRACE) {
- int endPos = this._previousToken.end;
- TemplateCall callNode = new TemplateCall(commandName.name,
- source.text.substring(startPos, endPos), _makeSpan(start));
- stack.top().add(callNode);
-
- _next(false);
- } else {
- _error("Unknown template command");
- }
- } // End of switch/case
- }
- } else if (_peekKind(TokenKind.END_COMMAND)) {
- break;
- } else {
- // Any text or expression nodes?
- var nodes = processTextNodes();
- if (nodes.length > 0) {
- assert(stack.top() != null);
- for (var node in nodes) {
- stack.top().add(node);
- }
- } else {
- break;
- }
- }
- }
-/*
- if (elems.children.length != 1) {
- print("ERROR: No closing end-tag for elems ${elems[elems.length - 1]}");
- }
-*/
- var docChildren = new List<ASTNode>();
- docChildren.add(stack.pop());
- return new TemplateDocument(docChildren, _makeSpan(start));
- }
-
- /* Map is used so only last unique attribute name is remembered and to quickly
- * find the var attribute.
- */
- Map<String, TemplateAttribute> processAttributes() {
- Map<String, TemplateAttribute> attrs = new Map();
-
- int start = _peekToken.start;
- String elemName;
- while (_peekIdentifier() ||
- (elemName = TokenKind.tagNameFromTokenId(_peek())) != null) {
- var attrName;
- if (elemName == null) {
- attrName = identifier();
- } else {
- attrName = new Identifier(elemName, _makeSpan(start));
- _next();
- }
-
- var attrValue;
-
- // Attribute value?
- if (_peek() == TokenKind.ATTR_VALUE) {
- var tok = _next();
- attrValue = new StringValue(tok.value, _makeSpan(tok.start));
- }
-
- attrs[attrName.name] =
- new TemplateAttribute(attrName, attrValue, _makeSpan(start));
-
- start = _peekToken.start;
- elemName = null;
- }
-
- return attrs;
- }
-
- identifier() {
- var tok = _next();
- if (!TokenKind.isIdentifier(tok.kind)) {
- _error('expected identifier, but found $tok', tok.span);
- }
-
- return new Identifier(tok.text, _makeSpan(tok.start));
- }
-
- List<ASTNode> processTextNodes() {
- // May contain TemplateText and TemplateExpression.
- List<ASTNode> nodes = [];
-
- int start = _peekToken.start;
- bool inExpression = false;
- StringBuffer stringValue = new StringBuffer();
-
- // Any text chars between close of tag and text node?
- if (_previousToken.kind == TokenKind.GREATER_THAN) {
- // If the next token is } could be the close template token. If user
- // needs } as token in text node use the entity &125;
- // TODO(terry): Probably need a &RCURLY entity instead of 125.
- if (_peek() == TokenKind.ERROR) {
- // Backup, just past previous token, & rescan we're outside of the tag.
- tokenizer.index = _previousToken.end;
- _next(false);
- } else if (_peek() != TokenKind.RBRACE) {
- // Yes, grab the chars after the >
- stringValue.write(_previousToken.source.text.substring(
- this._previousToken.end, this._peekToken.start));
- }
- }
-
- // Gobble up everything until we hit <
- while (_peek() != TokenKind.LESS_THAN &&
- _peek() != TokenKind.START_COMMAND &&
- _peek() != TokenKind.END_COMMAND &&
- (_peek() != TokenKind.RBRACE ||
- (_peek() == TokenKind.RBRACE && inExpression)) &&
- _peek() != TokenKind.END_OF_FILE) {
-
- // Beginning of expression?
- if (_peek() == TokenKind.START_EXPRESSION) {
- if (stringValue.length > 0) {
- // We have a real text node create the text node.
- nodes.add(new TemplateText(stringValue.toString(), _makeSpan(start)));
- stringValue = new StringBuffer();
- start = _peekToken.start;
- }
- inExpression = true;
- }
-
- var tok = _next(false);
- if (tok.kind == TokenKind.RBRACE && inExpression) {
- // We have an expression create the expression node, don't save the }
- inExpression = false;
- nodes.add(new TemplateExpression(stringValue.toString(),
- _makeSpan(start)));
- stringValue = new StringBuffer();
- start = _peekToken.start;
- } else if (tok.kind != TokenKind.START_EXPRESSION) {
- // Only save the the contents between ${ and }
- stringValue.write(tok.text);
- }
- }
-
- if (stringValue.length > 0) {
- nodes.add(new TemplateText(stringValue.toString(), _makeSpan(start)));
- }
-
- return nodes;
- }
-
-}
« no previous file with comments | « utils/template/htmltree.dart ('k') | utils/template/source.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698