Warning, /kdevelop/kdevelop/plugins/qmakemanager/parser/qmake.g is written in an unsupported language. File is not indexed.
0001 ------------------------------------------------------------------------------- 0002 -- This file is part of the QMake parser in KDevelop4 0003 -- SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de> 0004 -- 0005 -- SPDX-License-Identifier: GPL-2.0-or-later 0006 ------------------------------------------------------------------------------- 0007 0008 ----------------------------------------------------------- 0009 -- Global declarations 0010 ----------------------------------------------------------- 0011 0012 0013 [: 0014 0015 namespace QMake 0016 { 0017 class Lexer; 0018 } 0019 0020 #include <QString> 0021 0022 :] 0023 0024 %parser_declaration_header "QtCore/QString" 0025 0026 0027 ------------------------------------------------------------ 0028 -- Parser class members 0029 ------------------------------------------------------------ 0030 0031 %parserclass (public declaration) 0032 [: 0033 /** 0034 * Transform the raw input into tokens. 0035 * When this method returns, the parser's token stream has been filled 0036 * and any parse_*() method can be called. 0037 */ 0038 void tokenize( const QString& contents ); 0039 0040 enum ProblemType { 0041 Error, 0042 Warning, 0043 Info 0044 }; 0045 void reportProblem( Parser::ProblemType type, const QString& message ); 0046 0047 QString tokenText(qint64 begin, qint64 end) const; 0048 0049 void setDebug( bool debug ); 0050 0051 :] 0052 0053 %parserclass (private declaration) 0054 [: 0055 QString m_contents; 0056 bool m_debug; 0057 :] 0058 ----------------------------------------------------------- 0059 -- List of defined tokens 0060 ----------------------------------------------------------- 0061 0062 %token LBRACE("lbrace"), RBRACE("rbrace"), LPAREN("lparen"),RPAREN("rparen") ;; 0063 0064 %token PLUSEQ("pluseq"),EQUAL("equal"),MINUSEQ("minuseq"),STAREQ("stareq"), 0065 TILDEEQ("tildeeq") ;; 0066 0067 %token COLON("colon"), COMMA("comma"), CONT("cont"), EXCLAM("exclam"), 0068 NEWLINE("newline"), OR("or"), ELSE("else") ;; 0069 0070 %token IDENTIFIER("identifier"), VALUE("value") ;; 0071 0072 -- token that makes the parser fail in any case: 0073 %token INVALID ("invalid token") ;; 0074 0075 -- The actual grammar starts here. 0076 0077 ( #statements=statement )* 0078 -> project ;; 0079 0080 ( id=IDENTIFIER ( var=variableAssignment | scope=scope ) 0081 [: 0082 (*yynode)->isNewline = false; 0083 (*yynode)->isExclam = false; 0084 :] 0085 ) | ( EXCLAM id=IDENTIFIER scope=scope 0086 [: 0087 (*yynode)->isNewline = false; 0088 (*yynode)->isExclam = true; 0089 :] 0090 ) | NEWLINE 0091 [: 0092 (*yynode)->isNewline = true; 0093 (*yynode)->isExclam = false; 0094 :] 0095 -> statement [ member variable isNewline: bool; 0096 member variable isExclam: bool; ] ;; 0097 0098 functionArguments=functionArguments ( ifElse=ifElse | orOperator=orOperator ifElse=ifElse | 0 ) 0099 | ( orOperator=orOperator | 0 ) ifElse=ifElse 0100 -> scope ;; 0101 0102 ( OR #item=item )+ 0103 -> orOperator ;; 0104 0105 id=IDENTIFIER ( functionArguments=functionArguments | 0 ) 0106 -> item ;; 0107 0108 op=op ( values=valueList ( NEWLINE | 0 ) | NEWLINE | 0 ) 0109 -> variableAssignment ;; 0110 0111 optoken=PLUSEQ | optoken=MINUSEQ | optoken=STAREQ | optoken=EQUAL | optoken=TILDEEQ 0112 -> op ;; 0113 0114 ( #list=value | CONT NEWLINE )+ 0115 -> valueList ;; 0116 0117 value=VALUE 0118 -> value ;; 0119 0120 LPAREN args=argumentList RPAREN 0121 -> functionArguments ;; 0122 0123 ( ( #args=value | CONT NEWLINE ) ( ( COMMA | CONT NEWLINE ) #args=value )* | 0 ) 0124 -> argumentList ;; 0125 0126 LBRACE ( NEWLINE | 0 ) ( #statements=statement )* RBRACE | COLON #statements=statement 0127 -> scopeBody ;; 0128 0129 ELSE body=scopeBody 0130 -> elseBody ;; 0131 0132 ifBody=scopeBody ( elseBody=elseBody | 0 ) 0133 -> ifElse ;; 0134 0135 ----------------------------------------------------------------- 0136 -- Code segments copied to the implementation (.cpp) file. 0137 -- If existent, kdevelop-pg's current syntax requires this block 0138 -- to occur at the end of the file. 0139 ----------------------------------------------------------------- 0140 0141 [: 0142 #include "qmakelexer.h" 0143 #include <QString> 0144 #include <debug.h> 0145 0146 namespace QMake 0147 { 0148 0149 void Parser::tokenize( const QString& contents ) 0150 { 0151 m_contents = contents; 0152 QMake::Lexer lexer( this, contents ); 0153 int kind = Parser::Token_EOF; 0154 0155 do 0156 { 0157 kind = lexer.nextTokenKind(); 0158 0159 if ( !kind ) // when the lexer returns 0, the end of file is reached 0160 kind = Parser::Token_EOF; 0161 0162 Parser::Token &t = this->tokenStream->push(); 0163 t.kind = kind; 0164 if( t.kind == Parser::Token_EOF ) 0165 { 0166 t.begin = -1; 0167 t.end = -1; 0168 }else 0169 { 0170 t.begin = lexer.tokenBegin(); 0171 t.end = lexer.tokenEnd(); 0172 } 0173 0174 if( m_debug ) 0175 { 0176 qCDebug(KDEV_QMAKE) << kind << "(" << t.begin << "," << t.end << ")::" << tokenText(t.begin, t.end) << (tokenStream->size()-1); 0177 } 0178 0179 } 0180 while ( kind != Parser::Token_EOF ); 0181 0182 this->yylex(); // produce the look ahead token 0183 } 0184 0185 QString Parser::tokenText( qint64 begin, qint64 end ) const 0186 { 0187 return m_contents.mid((int)begin, (int)end-begin+1); 0188 } 0189 0190 void Parser::reportProblem( Parser::ProblemType type, const QString& message ) 0191 { 0192 if (type == Error) 0193 qCDebug(KDEV_QMAKE) << "** ERROR:" << message; 0194 else if (type == Warning) 0195 qCDebug(KDEV_QMAKE) << "** WARNING:" << message; 0196 else if (type == Info) 0197 qCDebug(KDEV_QMAKE) << "** Info:" << message; 0198 } 0199 0200 0201 // custom error recovery 0202 void Parser::expectedToken(int actualToken, qint64 expectedToken, const QString& name) 0203 { 0204 qint64 line; 0205 qint64 col; 0206 size_t index = tokenStream->index()-1; 0207 tokenStream->startPosition(index, &line, &col); 0208 0209 reportProblem( 0210 Parser::Error, 0211 QStringLiteral("Expected token \"%1\" (%2) instead of %3 at line: %4 col: %5, token index %6") 0212 .arg(name, QString::number(expectedToken), QString::number(actualToken), 0213 QString::number(line), QString::number(col), QString::number(index))); 0214 } 0215 0216 void Parser::expectedSymbol(int /*expected_symbol*/, const QString& name) 0217 { 0218 qint64 line; 0219 qint64 col; 0220 size_t index = tokenStream->index()-1; 0221 Token &token = tokenStream->at(index); 0222 qCDebug(KDEV_QMAKE) << "token starts at:" << token.begin; 0223 qCDebug(KDEV_QMAKE) << "index is:" << index; 0224 tokenStream->startPosition(index, &line, &col); 0225 QString tokenValue = tokenText(token.begin, token.end); 0226 reportProblem( 0227 Parser::Error, 0228 QStringLiteral("Expected symbol \"%1\" (current token: \"%2\" [%3] at line: %4 col: %5)") 0229 .arg(name, token.kind != 0 ? tokenValue : QStringLiteral("EOF")) 0230 .arg(token.kind) 0231 .arg(line) 0232 .arg(col)); 0233 } 0234 0235 void Parser::setDebug( bool debug ) 0236 { 0237 m_debug = debug; 0238 } 0239 0240 } // end of namespace QMake 0241 0242 :]