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 :]