Author: kn Date: Sun Feb 24 14:30:54 2008 New Revision: 7443 Log: - Always add token in AST nodes - Enhanced parse errors this way with more context information - Restructured parser test files
Added: experimental/Document/tests/files/rst/parser/001_empty.rst - copied unchanged from r7442, experimental/Document/tests/files/rst/parser/empty.rst experimental/Document/tests/files/rst/parser/001_empty.txt - copied unchanged from r7442, experimental/Document/tests/files/rst/parser/empty.txt experimental/Document/tests/files/rst/parser/002_titles.rst - copied, changed from r7442, experimental/Document/tests/files/rst/parser/titles.rst experimental/Document/tests/files/rst/parser/002_titles.txt - copied unchanged from r7442, experimental/Document/tests/files/rst/parser/titles.txt Removed: experimental/Document/tests/files/rst/parser/empty.rst experimental/Document/tests/files/rst/parser/empty.txt experimental/Document/tests/files/rst/parser/titles.rst experimental/Document/tests/files/rst/parser/titles.txt Modified: experimental/Document/src/document/rst/node.php experimental/Document/src/document/rst/nodes/document.php experimental/Document/src/document/rst/nodes/section.php experimental/Document/src/document/rst/nodes/text_line.php experimental/Document/src/document/rst/nodes/title.php experimental/Document/src/document/rst/parser.php experimental/Document/src/exceptions/rst_parser.php Modified: experimental/Document/src/document/rst/node.php ============================================================================== --- experimental/Document/src/document/rst/node.php [iso-8859-1] (original) +++ experimental/Document/src/document/rst/node.php [iso-8859-1] Sun Feb 24 14:30:54 2008 @@ -31,6 +31,20 @@ // ... /** + * Line of node in source file. + * + * @var int + */ + public $line; + + /** + * Character position of node in source file. + * + * @var int + */ + public $position; + + /** * Node type * * @var int @@ -42,7 +56,14 @@ * * @var mixed */ - public $nodes; + public $nodes = array(); + + /** + * Optional reference to token, not available for all nodes. + * + * @var ezcDocumentRstToken + */ + public $token = null; /** * Construct RST node @@ -51,10 +72,38 @@ * @param array $nodes * @return void */ - public function __construct( $type, array $nodes = array() ) + public function __construct( ezcDocumentRstToken $token, $type ) { - $this->type = $type; - $this->nodes = $nodes; + $this->type = $type; + $this->line = $token->line; + $this->position = $token->position; + $this->token = $token; + } + + /** + * Get node name from type + * + * Return a user readable name from the numeric node type. + * + * @param int $type + * @return string + */ + public static function getTokenName( $type ) + { + $names = array( + self::DOCUMENT => 'Document', + self::SECTION => 'Section', + self::TITLE => 'Title', + self::PARAGRAPH => 'Paragraph', + self::TEXT_LINE => 'Text line', + ); + + if ( !isset( $names[$type] ) ) + { + return 'Unknown'; + } + + return $names[$type]; } /** Modified: experimental/Document/src/document/rst/nodes/document.php ============================================================================== --- experimental/Document/src/document/rst/nodes/document.php [iso-8859-1] (original) +++ experimental/Document/src/document/rst/nodes/document.php [iso-8859-1] Sun Feb 24 14:30:54 2008 @@ -33,9 +33,10 @@ */ public function __construct( array $nodes = array() ) { - // Perhaps check, that only node of type section and metadata are - // added. - parent::__construct( self::DOCUMENT, $nodes ); + $this->line = 0; + $this->position = 0; + $this->type = self::DOCUMENT; + $this->nodes = $nodes; } /** Modified: experimental/Document/src/document/rst/nodes/section.php ============================================================================== --- experimental/Document/src/document/rst/nodes/section.php [iso-8859-1] (original) +++ experimental/Document/src/document/rst/nodes/section.php [iso-8859-1] Sun Feb 24 14:30:54 2008 @@ -38,13 +38,11 @@ * @param array $nodes * @return void */ - public function __construct( ezcDocumentRstTextLineNode $title, $depth = 0 ) + public function __construct( ezcDocumentRstToken $token, $depth = 0 ) { - // Perhaps check, that only node of type section and metadata are - // added. - parent::__construct( self::SECTION, array() ); + parent::__construct( $token, self::SECTION ); - $this->title = $title; + $this->title = $token->content; $this->depth = $depth; } @@ -58,7 +56,7 @@ public static function __set_state( $properties ) { $node = new ezcDocumentRstSectionNode( - $properties['title'], + $properties['token'], $properties['depth'] ); Modified: experimental/Document/src/document/rst/nodes/text_line.php ============================================================================== --- experimental/Document/src/document/rst/nodes/text_line.php [iso-8859-1] (original) +++ experimental/Document/src/document/rst/nodes/text_line.php [iso-8859-1] Sun Feb 24 14:30:54 2008 @@ -28,7 +28,7 @@ { // Perhaps check, that only node of type section and metadata are // added. - parent::__construct( self::TEXT_LINE, array( $token ) ); + parent::__construct( $token, self::TEXT_LINE ); } /** @@ -41,7 +41,7 @@ public static function __set_state( $properties ) { return new ezcDocumentRstTextLineNode( - $properties['nodes'][0] + $properties['token'] ); } } Modified: experimental/Document/src/document/rst/nodes/title.php ============================================================================== --- experimental/Document/src/document/rst/nodes/title.php [iso-8859-1] (original) +++ experimental/Document/src/document/rst/nodes/title.php [iso-8859-1] Sun Feb 24 14:30:54 2008 @@ -19,13 +19,6 @@ class ezcDocumentRstTitleNode extends ezcDocumentRstNode { /** - * Token, which is used for the current title definition - * - * @var ezcDocumentRstToken - */ - public $token; - - /** * Construct RST document node * * @param array $nodes @@ -33,11 +26,7 @@ */ public function __construct( ezcDocumentRstToken $token ) { - // Perhaps check, that only node of type section and metadata are - // added. - parent::__construct( self::TITLE, array() ); - - $this->token = $token; + parent::__construct( $token, self::TITLE ); } /** Modified: experimental/Document/src/document/rst/parser.php ============================================================================== --- experimental/Document/src/document/rst/parser.php [iso-8859-1] (original) +++ experimental/Document/src/document/rst/parser.php [iso-8859-1] Sun Feb 24 14:30:54 2008 @@ -188,7 +188,11 @@ if ( ( count( $this->documentStack ) !== 1 ) || ( !( $document = reset( $this->documentStack ) ) instanceof ezcDocumentRstDocumentNode ) ) { - throw new ezcDocumentRstParserException(); + $node = isset( $document ) ? $document : reset( $this->documentStack ); + throw new ezcDocumentRstParserException( + $node->token, + 'Expected end of file, got: ' . ezcDocumentRstNode::getTokenName( $node->type ) . "." + ); } return $document; @@ -208,7 +212,7 @@ if ( count( $tokens ) ) { throw new ezcDocumentRstParserException( - $token, ezcDocumentRstParserException::FATAL, + $token, 'Unexpected end of file.' ); } @@ -280,10 +284,9 @@ ezcDocumentRstNode::SECTION, ), true ) ) { - // @TODO: Enhance error message throw new ezcDocumentRstParserException( - null, ezcDocumentRstParserException::FATAL, - 'Unexpected child.' + $child->token, + "Unexpected node: " . ezcDocumentRstNode::getTokenName( $child->type ) . "." ); } @@ -315,7 +318,7 @@ $titleType = $node->token->content[0]; // Check if the lengths of the top line and the text matches. - if ( strlen( $node->token->content ) !== strlen( $title->nodes[0]->content ) ) + if ( strlen( $node->token->content ) !== strlen( $title->token->content ) ) { $this->warnings[] = "Title underline length does not match text length in line {$node->token->line}."; } @@ -332,8 +335,7 @@ if ( strlen( $node->token->content ) !== strlen( $doubleTitle->token->content ) ) { throw new ezcDocumentRstParserException( - $node->token, ezcDocumentRstParserException::FATAL, - "Title overline & underline mismatch in line {$node->token->line}." + $node->token, "Title overline & underline mismatch." ); } } @@ -350,8 +352,7 @@ // Prepend section element to document stack return new ezcDocumentRstSectionNode( - $title, - $depth + $title->token, $depth ); } @@ -384,8 +385,8 @@ { // @TODO: Enhance error message throw new ezcDocumentRstParserException( - null, ezcDocumentRstParserException::FATAL, - 'Unexpected child.' + $child->token, + "Unexpected node: " . ezcDocumentRstNode::getTokenName( $child->type ) . "." ); } @@ -404,11 +405,9 @@ if ( ( $lastSectionDepth - $child->depth ) > 1 ) { - $token = $child->title->token; - throw new ezcDocumentRstParserException( - $token, ezcDocumentRstParserException::FATAL, - "Title depth inconsitency in line {$node->token->line}." + $child->token, + "Title depth inconsitency." ); } Modified: experimental/Document/src/exceptions/rst_parser.php ============================================================================== --- experimental/Document/src/exceptions/rst_parser.php [iso-8859-1] (original) +++ experimental/Document/src/exceptions/rst_parser.php [iso-8859-1] Sun Feb 24 14:30:54 2008 @@ -16,8 +16,6 @@ */ class ezcDocumentRstParserException extends ezcDocumentException { - const FATAL = 1; - /** * Construct exception from errnous string and current position * @@ -26,10 +24,14 @@ * @param string $string * @return void */ - public function __construct( ) + public function __construct( ezcDocumentRstToken $token, $message ) { parent::__construct( - "Parse error." + sprintf( "Parse error in line %d at %d: %s", + $token->line, + $token->position, + $message + ) ); } } Copied: experimental/Document/tests/files/rst/parser/002_titles.rst (from r7442, experimental/Document/tests/files/rst/parser/titles.rst) ============================================================================== --- experimental/Document/tests/files/rst/parser/titles.rst [iso-8859-1] (original) +++ experimental/Document/tests/files/rst/parser/002_titles.rst [iso-8859-1] Sun Feb 24 14:30:54 2008 @@ -2,405 +2,336 @@ return ezcDocumentRstDocumentNode::__set_state(array( 'depth' => 0, + 'line' => 0, + 'position' => 0, 'type' => 0, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 2, - 'position' => 2, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 1, + 'line' => 2, + 'position' => 2, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 6, - 'position' => 2, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 2, + 'line' => 6, + 'position' => 2, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 48, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 3, + 'line' => 48, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 51, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 4, + 'line' => 51, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 54, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 5, + 'line' => 54, + 'position' => 1, 'type' => 1, 'nodes' => array ( ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 54, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 51, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 48, + 'position' => 1, + )), )), 1 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 9, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 3, + 'line' => 9, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 12, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 4, + 'line' => 12, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 21, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 5, + 'line' => 21, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 24, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 6, + 'line' => 24, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 33, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 7, + 'line' => 33, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 36, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 8, + 'line' => 36, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 39, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 9, + 'line' => 39, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 42, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 10, + 'line' => 42, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 45, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 11, + 'line' => 45, + 'position' => 1, 'type' => 1, 'nodes' => array ( ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 45, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 42, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 39, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 36, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 33, + 'position' => 1, + )), )), 1 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 27, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 7, + 'line' => 27, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 30, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 8, + 'line' => 30, + 'position' => 1, 'type' => 1, 'nodes' => array ( ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 30, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 27, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 24, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 21, + 'position' => 1, + )), )), 1 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 15, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 5, + 'line' => 15, + 'position' => 1, 'type' => 1, 'nodes' => array ( 0 => ezcDocumentRstSectionNode::__set_state(array( - 'title' => - ezcDocumentRstTextLineNode::__set_state(array( - 'type' => 4, - 'nodes' => - array ( - 0 => - ezcDocumentRstToken::__set_state(array( - 'type' => 5, - 'content' => 'Section Title', - 'line' => 18, - 'position' => 1, - )), - ), - )), + 'title' => 'Section Title', 'depth' => 6, + 'line' => 18, + 'position' => 1, 'type' => 1, 'nodes' => array ( ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 18, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 15, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 12, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 9, + 'position' => 1, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 6, + 'position' => 2, + )), )), ), + 'token' => + ezcDocumentRstToken::__set_state(array( + 'type' => 5, + 'content' => 'Section Title', + 'line' => 2, + 'position' => 2, + )), )), ), + 'token' => NULL, )); -- svn-components mailing list svn-components@lists.ez.no http://lists.ez.no/mailman/listinfo/svn-components