?? parser.y
字號(hào):
%{
/*
* This file is part of the KDE libraries
* Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
* Copyright (C) 2004 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <dom/dom_string.h>
#include <xml/dom_docimpl.h>
#include <css/css_ruleimpl.h>
#include <css/css_stylesheetimpl.h>
#include <css/css_valueimpl.h>
#include <misc/htmlhashes.h>
#include "cssparser.h"
#include "xml_namespace_table.h"
#include <assert.h>
#include <kdebug.h>
// #define CSS_DEBUG
using namespace DOM;
//
// The following file defines the function
// const struct props *findProp(const char *word, int len)
//
// with 'props->id' a CSS property in the range from CSS_PROP_MIN to
// (and including) CSS_PROP_TOTAL-1
// turn off inlining to void warning with newer gcc
#undef __inline
#define __inline
#include "cssproperties.c"
#include "cssvalues.c"
#undef __inline
int DOM::getPropertyID(const char *tagStr, int len)
{
const struct props *propsPtr = findProp(tagStr, len);
if (!propsPtr)
return 0;
return propsPtr->id;
}
static inline int getValueID(const char *tagStr, int len)
{
const struct css_value *val = findValue(tagStr, len);
if (!val)
return 0;
return val->id;
}
#define YYDEBUG 0
#define YYMAXDEPTH 0
#define YYPARSE_PARAM parser
%}
%pure_parser
%union {
CSSRuleImpl *rule;
CSSSelector *selector;
bool ok;
MediaListImpl *mediaList;
CSSMediaRuleImpl *mediaRule;
CSSRuleListImpl *ruleList;
ParseString string;
float val;
int prop_id;
int attribute;
int element;
CSSSelector::Relation relation;
bool b;
char tok;
Value value;
ValueList *valueList;
}
%{
static inline int cssyyerror(const char *x ) {
#ifdef CSS_DEBUG
qDebug( x );
#else
Q_UNUSED( x );
#endif
return 1;
}
static int cssyylex( YYSTYPE *yylval ) {
return CSSParser::current()->lex( yylval );
}
%}
%expect 12
%token WHITESPACE SGML_CD
%token INCLUDES
%token DASHMATCH
%token BEGINSWITH
%token ENDSWITH
%token CONTAINS
%token <string> STRING
%token <string> IDENT
%token <string> HASH
%token ':'
%token '.'
%token '['
%token IMPORT_SYM
%token PAGE_SYM
%token MEDIA_SYM
%token FONT_FACE_SYM
%token CHARSET_SYM
%token NAMESPACE_SYM
%token KHTML_RULE_SYM
%token KHTML_DECLS_SYM
%token KHTML_VALUE_SYM
%token IMPORTANT_SYM
%token <val> QEMS
%token <val> EMS
%token <val> EXS
%token <val> PXS
%token <val> CMS
%token <val> MMS
%token <val> INS
%token <val> PTS
%token <val> PCS
%token <val> DEGS
%token <val> RADS
%token <val> GRADS
%token <val> MSECS
%token <val> SECS
%token <val> HERZ
%token <val> KHERZ
%token <string> DIMEN
%token <val> PERCENTAGE
%token <val> NUMBER
%token <string> URI
%token <string> FUNCTION
%token <string> UNICODERANGE
%type <relation> combinator
%type <rule> ruleset
%type <rule> media
%type <rule> import
%type <rule> page
%type <rule> font_face
%type <rule> invalid_rule
%type <rule> invalid_at
%type <rule> invalid_import
%type <rule> rule
%type <string> maybe_ns_prefix
%type <string> namespace_selector
%type <string> string_or_uri
%type <string> ident_or_string
%type <string> medium
%type <string> hexcolor
%type <mediaList> media_list
%type <mediaList> maybe_media_list
%type <ruleList> ruleset_list
%type <prop_id> property
%type <selector> specifier
%type <selector> specifier_list
%type <selector> simple_selector
%type <selector> selector
%type <selector> selector_list
%type <selector> class
%type <selector> attrib
%type <selector> pseudo
%type <ok> declaration_list
%type <ok> decl_list
%type <ok> declaration
%type <b> prio
%type <val> match
%type <val> unary_operator
%type <tok> operator
%type <valueList> expr
%type <value> term
%type <value> unary_term
%type <value> function
%type <element> element_name
%type <attribute> attrib_id
%%
stylesheet:
maybe_charset maybe_sgml import_list namespace_list rule_list
| khtml_rule maybe_space
| khtml_decls maybe_space
| khtml_value maybe_space
;
khtml_rule:
KHTML_RULE_SYM '{' maybe_space ruleset maybe_space '}' {
CSSParser *p = static_cast<CSSParser *>(parser);
p->rule = $4;
}
;
khtml_decls:
KHTML_DECLS_SYM '{' maybe_space declaration_list '}' {
/* can be empty */
}
;
khtml_value:
KHTML_VALUE_SYM '{' maybe_space expr '}' {
CSSParser *p = static_cast<CSSParser *>(parser);
if ( $4 ) {
p->valueList = $4;
#ifdef CSS_DEBUG
kdDebug( 6080 ) << " got property for " << p->id <<
(p->important?" important":"")<< endl;
bool ok =
#endif
p->parseValue( p->id, p->important );
#ifdef CSS_DEBUG
if ( !ok )
kdDebug( 6080 ) << " couldn't parse value!" << endl;
#endif
}
#ifdef CSS_DEBUG
else
kdDebug( 6080 ) << " no value found!" << endl;
#endif
delete p->valueList;
p->valueList = 0;
}
;
maybe_space:
/* empty */
| maybe_space WHITESPACE
;
maybe_sgml:
/* empty */
| maybe_sgml SGML_CD
| maybe_sgml WHITESPACE
;
maybe_charset:
/* empty */
| CHARSET_SYM maybe_space STRING maybe_space ';' {
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "charset rule: " << qString($3) << endl;
#endif
}
| CHARSET_SYM error invalid_block
| CHARSET_SYM error ';'
;
import_list:
/* empty */
| import_list import maybe_sgml {
CSSParser *p = static_cast<CSSParser *>(parser);
if ( $2 && p->styleElement && p->styleElement->isCSSStyleSheet() ) {
p->styleElement->append( $2 );
} else {
delete $2;
}
}
;
namespace_list:
/* empty */
| namespace_list namespace maybe_sgml
;
rule_list:
/* empty */
| rule_list rule maybe_sgml {
CSSParser *p = static_cast<CSSParser *>(parser);
if ( $2 && p->styleElement && p->styleElement->isCSSStyleSheet() ) {
p->styleElement->append( $2 );
} else {
delete $2;
}
}
;
rule:
ruleset
| media
| page
| font_face
| invalid_rule
| invalid_at
| invalid_import
;
import:
IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' {
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "@import: " << qString($3) << endl;
#endif
CSSParser *p = static_cast<CSSParser *>(parser);
if ( $5 && p->styleElement && p->styleElement->isCSSStyleSheet() )
$$ = new CSSImportRuleImpl( p->styleElement, domString($3), $5 );
else {
$$ = 0;
delete $5;
}
}
| IMPORT_SYM error invalid_block {
$$ = 0;
}
| IMPORT_SYM error ';' {
$$ = 0;
}
;
namespace:
NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "@namespace: " << qString($4) << endl;
#endif
CSSParser *p = static_cast<CSSParser *>(parser);
if (p->styleElement && p->styleElement->isCSSStyleSheet())
static_cast<CSSStyleSheetImpl*>(p->styleElement)->addNamespace(p, domString($3), domString($4));
}
| NAMESPACE_SYM error invalid_block
| NAMESPACE_SYM error ';'
;
maybe_ns_prefix:
/* empty */ { $$.string = 0; }
| IDENT WHITESPACE { $$ = $1; }
;
string_or_uri:
STRING
| URI
;
maybe_media_list:
/* empty */ {
$$ = new MediaListImpl();
}
| media_list
;
media_list:
/* empty */ {
$$ = 0;
}
| medium {
$$ = new MediaListImpl();
$$->appendMedium( domString($1).lower() );
}
| media_list ',' maybe_space medium {
$$ = $1;
if ($$)
$$->appendMedium( domString($4) );
}
| media_list error {
delete $1;
$$ = 0;
}
;
media:
MEDIA_SYM maybe_space media_list '{' maybe_space ruleset_list '}' {
CSSParser *p = static_cast<CSSParser *>(parser);
if ( $3 && $6 &&
p->styleElement && p->styleElement->isCSSStyleSheet() ) {
$$ = new CSSMediaRuleImpl( static_cast<CSSStyleSheetImpl*>(p->styleElement), $3, $6 );
} else {
$$ = 0;
delete $3;
delete $6;
}
}
;
ruleset_list:
/* empty */ { $$ = 0; }
| ruleset_list ruleset maybe_space {
$$ = $1;
if ( $2 ) {
if ( !$$ ) $$ = new CSSRuleListImpl();
$$->append( $2 );
}
}
;
medium:
IDENT maybe_space {
$$ = $1;
}
;
/*
page:
PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space
'{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
;
pseudo_page
: ':' IDENT
;
font_face
: FONT_FACE_SYM maybe_space
'{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
;
*/
page:
PAGE_SYM error invalid_block {
$$ = 0;
}
| PAGE_SYM error ';' {
$$ = 0;
}
;
font_face:
FONT_FACE_SYM error invalid_block {
$$ = 0;
}
| FONT_FACE_SYM error ';' {
$$ = 0;
}
;
combinator:
'+' maybe_space { $$ = CSSSelector::Sibling; }
| '>' maybe_space { $$ = CSSSelector::Child; }
| /* empty */ { $$ = CSSSelector::Descendant; }
;
unary_operator:
'-' { $$ = -1; }
| '+' { $$ = 1; }
;
ruleset:
selector_list '{' maybe_space declaration_list '}' {
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "got ruleset" << endl << " selector:" << endl;
#endif
CSSParser *p = static_cast<CSSParser *>(parser);
if ( $1 ) {
CSSStyleRuleImpl *rule = new CSSStyleRuleImpl( p->styleElement );
CSSMutableStyleDeclarationImpl *decl = p->createStyleDeclaration( rule );
rule->setSelector( $1 );
rule->setDeclaration(decl);
$$ = rule;
} else {
$$ = 0;
p->clearProperties();
}
}
;
selector_list:
selector {
if ( $1 ) {
$$ = $1;
#ifdef CSS_DEBUG
kdDebug( 6080 ) << " got simple selector:" << endl;
$1->print();
#endif
} else {
$$ = 0;
}
}
| selector_list ',' maybe_space selector {
if ( $1 && $4 ) {
$$ = $1;
$$->append( $4 );
#ifdef CSS_DEBUG
kdDebug( 6080 ) << " got simple selector:" << endl;
$4->print();
#endif
} else {
delete $1;
delete $4;
$$ = 0;
}
}
| selector_list error {
delete $1;
$$ = 0;
}
;
selector:
simple_selector {
$$ = $1;
}
| selector combinator simple_selector {
$$ = $3;
if (!$1) {
delete $3;
$$ = 0;
}
else if ($$) {
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -