Warning, /frameworks/khtml/src/xpath/parser.y is written in an unsupported language. File is not indexed.

0001 %{
0002 #include "functions.h"
0003 #include "path.h"
0004 #include "predicate.h"
0005 #include "util.h"
0006 #include "tokenizer.h"
0007 
0008 #include "expression.h"
0009 #include "util.h"
0010 #include "variablereference.h"
0011 
0012 #include "dom/dom_string.h"
0013 #include "dom/dom_exception.h"
0014 #include "dom/dom3_xpath.h"
0015 #include "xml/dom_stringimpl.h"
0016 #include "xml/dom3_xpathimpl.h"
0017 
0018 using namespace DOM;
0019 using namespace DOM::XPath;
0020 using namespace khtml;
0021 using namespace khtml::XPath;
0022 
0023 
0024 
0025 #include <QList>
0026 #include <QPair>
0027 #include <QtDebug>
0028 
0029 #define YYDEBUG 1
0030 
0031 Expression * khtmlParseXPathStatement( const DOM::DOMString &statement, int& ec );
0032 
0033 static Expression *_topExpr;
0034 static int xpathParseException;
0035 
0036 %}
0037 
0038 %union
0039 {
0040         khtml::XPath::Step::AxisType axisType;
0041         int        num;
0042         DOM::DOMString *str; // we use this and not DOMStringImpl*, so the
0043                              // memory management for this is entirely manual,
0044                              // and not an RC/manual hybrid
0045         khtml::XPath::Expression *expr;
0046         QList<khtml::XPath::Predicate *> *predList;
0047         QList<khtml::XPath::Expression *> *argList;
0048         khtml::XPath::Step *step;
0049         khtml::XPath::LocationPath *locationPath;
0050 }
0051 
0052 %{
0053 %}
0054 
0055 %left <num> MULOP RELOP EQOP
0056 %left <str> PLUS MINUS
0057 %left <str> OR AND
0058 %token <axisType> AXISNAME
0059 %token <str> NODETYPE PI FUNCTIONNAME LITERAL
0060 %token <str> VARIABLEREFERENCE NUMBER
0061 %token <str> DOTDOT SLASHSLASH NAMETEST
0062 %token ERROR
0063 
0064 %type <locationPath> LocationPath
0065 %type <locationPath> AbsoluteLocationPath
0066 %type <locationPath> RelativeLocationPath
0067 %type <step> Step
0068 %type <axisType> AxisSpecifier
0069 %type <step> DescendantOrSelf
0070 %type <str> NodeTest
0071 %type <expr> Predicate
0072 %type <predList> PredicateList
0073 %type <step> AbbreviatedStep
0074 %type <expr> Expr
0075 %type <expr> PrimaryExpr
0076 %type <expr> FunctionCall
0077 %type <argList> ArgumentList
0078 %type <expr> Argument
0079 %type <expr> UnionExpr
0080 %type <expr> PathExpr
0081 %type <expr> FilterExpr
0082 %type <expr> OrExpr
0083 %type <expr> AndExpr
0084 %type <expr> EqualityExpr
0085 %type <expr> RelationalExpr
0086 %type <expr> AdditiveExpr
0087 %type <expr> MultiplicativeExpr
0088 %type <expr> UnaryExpr
0089 
0090 %%
0091 
0092 Expr:
0093         OrExpr
0094         {
0095                 _topExpr = $1;
0096         }
0097         ;
0098 
0099 LocationPath:
0100         RelativeLocationPath
0101         {
0102                 $$->m_absolute = false;
0103         }
0104         |
0105         AbsoluteLocationPath
0106         {
0107                 $$->m_absolute = true;
0108         }
0109         ;
0110 
0111 AbsoluteLocationPath:
0112         '/'
0113         {
0114                 $$ = new LocationPath;
0115         }
0116         |
0117         '/' RelativeLocationPath
0118         {
0119                 $$ = $2;
0120         }
0121         |
0122         DescendantOrSelf RelativeLocationPath
0123         {
0124                 $$ = $2;
0125                 $$->m_steps.prepend( $1 );
0126         }
0127         ;
0128 
0129 RelativeLocationPath:
0130         Step
0131         {
0132                 $$ = new LocationPath;
0133                 $$->m_steps.append( $1 );
0134         }
0135         |
0136         RelativeLocationPath '/' Step
0137         {
0138                 $$->m_steps.append( $3 );
0139         }
0140         |
0141         RelativeLocationPath DescendantOrSelf Step
0142         {
0143                 $$->m_steps.append( $2 );
0144                 $$->m_steps.append( $3 );
0145         }
0146         ;
0147 
0148 Step:
0149         NodeTest
0150         {
0151                 $$ = new Step( Step::ChildAxis, *$1 );
0152                 delete $1;
0153         }
0154         |
0155         NodeTest PredicateList
0156         {
0157                 $$ = new Step( Step::ChildAxis, *$1, *$2 );
0158                 delete $1;
0159                 delete $2;
0160         }
0161         |
0162         AxisSpecifier NodeTest
0163         {
0164                 $$ = new Step( $1, *$2 );
0165                 delete $2;
0166         }
0167         |
0168         AxisSpecifier NodeTest PredicateList
0169         {
0170                 $$ = new Step( $1, *$2,  *$3 );
0171                 delete $2;
0172                 delete $3;
0173         }
0174         |
0175         AbbreviatedStep
0176         ;
0177 
0178 AxisSpecifier:
0179         AXISNAME
0180         |
0181         '@'
0182         {
0183                 $$ = Step::AttributeAxis;
0184         }
0185         ;
0186 
0187 NodeTest:
0188         NAMETEST
0189         {
0190                 const int colon = $1->find( ':' );
0191                 if ( colon > -1 ) {
0192                         DOMString prefix( $1->substring( 0, colon ) );
0193                         XPathNSResolverImpl *resolver = Expression::evaluationContext().resolver;
0194                         if ( !resolver || resolver->lookupNamespaceURI( prefix ).isNull() ) {
0195                                 qWarning() << "Found unknown namespace prefix " << prefix.string();
0196                                 xpathParseException = DOMException::NAMESPACE_ERR;
0197                                 YYABORT;
0198                         }
0199                 }
0200         }
0201         |
0202         NODETYPE '(' ')'
0203         {
0204                 $$ = new DOMString( *$1 + DOMString("()") );
0205         }
0206         |
0207         PI '(' ')'
0208         |
0209         PI '(' LITERAL ')'
0210         {
0211                 QString s = $1->string() + QLatin1Char(' ') + $3->string();
0212                 s = s.trimmed();
0213                 $$ = new DOMString( s );
0214                 delete $1;
0215                 delete $3;
0216         }
0217         ;
0218 
0219 PredicateList:
0220         Predicate
0221         {
0222                 $$ = new QList<Predicate *>;
0223                 $$->append( new Predicate( $1 ) );
0224         }
0225         |
0226         PredicateList Predicate
0227         {
0228                 $$->append( new Predicate( $2 ) );
0229         }
0230         ;
0231 
0232 Predicate:
0233         '[' Expr ']'
0234         {
0235                 $$ = $2;
0236         }
0237         ;
0238 
0239 DescendantOrSelf:
0240         SLASHSLASH
0241         {
0242                 $$ = new Step( Step::DescendantOrSelfAxis, "node()" );
0243         }
0244         ;
0245 
0246 AbbreviatedStep:
0247         '.'
0248         {
0249                 $$ = new Step( Step::SelfAxis, "node()" );
0250         }
0251         |
0252         DOTDOT
0253         {
0254                 $$ = new Step( Step::ParentAxis, "node()" );
0255         }
0256         ;
0257 
0258 PrimaryExpr:
0259         VARIABLEREFERENCE
0260         {
0261                 $$ = new VariableReference( *$1 );
0262                 delete $1;
0263         }
0264         |
0265         '(' Expr ')'
0266         {
0267                 $$ = $2;
0268         }
0269         |
0270         LITERAL
0271         {
0272                 $$ = new String( *$1 );
0273                 delete $1;
0274         }
0275         |
0276         NUMBER
0277         {
0278                 $$ = new Number( $1->toFloat() );
0279                 delete $1;
0280         }
0281         |
0282         FunctionCall
0283         ;
0284 
0285 FunctionCall:
0286         FUNCTIONNAME '(' ')'
0287         {
0288                 Function* f = FunctionLibrary::self().getFunction( *$1 );
0289                 delete $1;
0290                 if (!f) {
0291                         xpathParseException = XPathException::toCode(INVALID_EXPRESSION_ERR);
0292                         YYABORT;
0293                 }
0294                 
0295                 $$ = f;
0296         }
0297         |
0298         FUNCTIONNAME '(' ArgumentList ')'
0299         {
0300                 Function* f = FunctionLibrary::self().getFunction( *$1, *$3 );
0301                 delete $1;
0302                 delete $3;
0303                 if (!f) {
0304                         xpathParseException = XPathException::toCode(INVALID_EXPRESSION_ERR);
0305                         YYABORT;
0306                 }
0307                 $$ = f;
0308         }
0309         ;
0310 
0311 ArgumentList:
0312         Argument
0313         {
0314                 $$ = new QList<Expression *>;
0315                 $$->append( $1 );
0316         }
0317         |
0318         ArgumentList ',' Argument
0319         {
0320                 $$->append( $3 );
0321         }
0322         ;
0323 
0324 Argument:
0325         Expr
0326         ;
0327 
0328 
0329 UnionExpr:
0330         PathExpr
0331         |
0332         UnionExpr '|' PathExpr
0333         {
0334                 $$ = new Union;
0335                 $$->addSubExpression( $1 );
0336                 $$->addSubExpression( $3 );
0337         }
0338         ;
0339 
0340 PathExpr:
0341         LocationPath
0342         {
0343                 $$ = $1;
0344         }
0345         |
0346         FilterExpr
0347         {
0348                 $$ = $1;
0349         }
0350         |
0351         FilterExpr '/' RelativeLocationPath
0352         {
0353                 $$ = new Path( static_cast<Filter *>( $1 ), $3 );
0354         }
0355         |
0356         FilterExpr DescendantOrSelf RelativeLocationPath
0357         {
0358                 $3->m_steps.prepend( $2 );
0359                 $$ = new Path( static_cast<Filter *>( $1 ), $3 );
0360         }
0361         ;
0362 
0363 FilterExpr:
0364         PrimaryExpr
0365         {
0366                 $$ = $1;
0367         }
0368         |
0369         PrimaryExpr PredicateList
0370         {
0371                 $$ = new Filter( $1, *$2 );
0372         }
0373         ;
0374 
0375 OrExpr:
0376         AndExpr
0377         |
0378         OrExpr OR AndExpr
0379         {
0380                 $$ = new LogicalOp( LogicalOp::OP_Or, $1, $3 );
0381         }
0382         ;
0383 
0384 AndExpr:
0385         EqualityExpr
0386         |
0387         AndExpr AND EqualityExpr
0388         {
0389                 $$ = new LogicalOp( LogicalOp::OP_And, $1, $3 );
0390         }
0391         ;
0392 
0393 EqualityExpr:
0394         RelationalExpr
0395         |
0396         EqualityExpr EQOP RelationalExpr
0397         {
0398                 $$ = new RelationOp( $2, $1, $3 );
0399         }
0400         ;
0401 
0402 RelationalExpr:
0403         AdditiveExpr
0404         |
0405         RelationalExpr RELOP AdditiveExpr
0406         {
0407                 $$ = new RelationOp( $2, $1, $3 );
0408         }
0409         ;
0410 
0411 AdditiveExpr:
0412         MultiplicativeExpr
0413         |
0414         AdditiveExpr PLUS MultiplicativeExpr
0415         {
0416                 $$ = new NumericOp( NumericOp::OP_Add, $1, $3 );
0417         }
0418         |
0419         AdditiveExpr MINUS MultiplicativeExpr
0420         {
0421                 $$ = new NumericOp( NumericOp::OP_Sub, $1, $3 );
0422         }
0423         ;
0424 
0425 MultiplicativeExpr:
0426         UnaryExpr
0427         |
0428         MultiplicativeExpr MULOP UnaryExpr
0429         {
0430                 $$ = new NumericOp( $2, $1, $3 );
0431         }
0432         ;
0433 
0434 UnaryExpr:
0435         UnionExpr
0436         |
0437         MINUS UnaryExpr
0438         {
0439                 $$ = new Negative;
0440                 $$->addSubExpression( $2 );
0441         }
0442         ;
0443 
0444 %%
0445 
0446 namespace khtml {
0447 namespace XPath {
0448 
0449 Expression *khtmlParseXPathStatement( const DOM::DOMString &statement, int& ec )
0450 {
0451 //      qDebug() << "Parsing " << statement;
0452         xpathParseException = 0;
0453         _topExpr = 0;
0454         initTokenizer( statement );
0455         yyparse();
0456 
0457         if (xpathParseException)
0458                 ec = xpathParseException;
0459         return _topExpr;
0460 }
0461 
0462 void khtmlxpathyyerror(const char *str)
0463 {
0464         // XXX Clean xpathyylval.str up to avoid leaking it.
0465         fprintf(stderr, "error: %s\n", str);
0466         xpathParseException = XPathException::toCode(INVALID_EXPRESSION_ERR);
0467 }
0468 
0469 } // namespace XPath
0470 } // namespace khtml
0471 
0472 // kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off;