/* This file is part of mhmake.
*
* Copyright (C) 2001-2010 marha@sourceforge.net
*
* Mhmake is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Mhmake 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Mhmake. If not, see .
*/
/* $Rev$ */
/* -------------- declaration section -------------- */
%require "2.4.1"
%defines
%define parser_class_name "mhmakeparser"
%define parser_base_class_name "mhmakeparserbase"
%define parser_class_constructor_init ": mhmakeparserbase(pMakefile,pLexer)"
%define parser_class_constructor_param "mhmakefileparser *pMakefile, mhmakeFlexLexer *pLexer"
%error-verbose
%code requires {
#include "mhmakefileparser.h"
}
%code provides {
const char Test[]="dit is een test";
}
%{
#include "mhmakefileparser.h"
#include "rule.h"
#include "util.h"
%}
%locations
%initial-action
{
// Initialize the initial location.
@$.initialize(&m_ptheLexer->GetInputFilename());
};
%token END 0 "end of file"
%token COMMAND
%token COMMA
%token STRING DOLLAREXPR EQUAL COLON DOUBLECOLON VARDEF VARVAL
%token IMEQUAL PEQUAL OPTEQUAL PHONY AUTODEPS EXPORT NEWLINE INCLUDEMAK SPACE VPATH ENVVARS_TOIGNORE
%type expression nonspaceexpression simpleexpression
%type maybeemptyexpression
%type expression_nocolorequal simpleexpression_nocolorequal nonspaceexpression_nocolorequal
%type rulecolon
%start file
/* -------------- rules section -------------- */
/* Sample parser. Does count Chars in a line, and lines in file */
%%
file : statements
{
if (m_pMakefile->m_pCurrentItems)
{
PRINTF(("Adding rule : %s\n",(*m_pMakefile->m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
m_pMakefile->AddRule();
}
}
;
statements :
| statements statement
;
space : SPACE |
space SPACE
;
statement: NEWLINE |
SPACE |
DOLLAREXPR NEWLINE {
m_pMakefile->ExpandExpression($1);
} |
includemak |
ruledef |
phonyrule |
autodepsrule |
envvarstoignorerule |
varassignment |
imvarassignment |
pvarassignment |
optvarassignment |
exportrule |
vpathrule |
COMMAND
{
if (!m_pMakefile->m_pCurrentRule)
{
m_pMakefile->m_pCurrentRule=refptr(new rule(m_pMakefile));
}
m_pMakefile->m_pCurrentRule->AddCommand($1);
PRINTF(("Adding command : %s\n",$1.c_str()));
}
;
includemak:
{
if (m_pMakefile->m_pCurrentItems)
{
PRINTF(("Adding rule : %s\n",(*m_pMakefile->m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
m_pMakefile->AddRule();
}
} INCLUDEMAK
;
ruledef: expression_nocolorequal rulecolon maybeemptyexpression
{
if (m_pMakefile->m_pCurrentItems)
{
PRINTF(("Adding rule : %s\n",(*m_pMakefile->m_pCurrentItems)[0]->GetQuotedFullFileName().c_str()));
m_pMakefile->AddRule();
}
m_pMakefile->m_pCurrentItems=new fileinfoarray;
m_pMakefile->m_pCurrentDeps=new fileinfoarray;
#ifdef _DEBUG
if (!m_pMakefile->ExpandExpression($1).size())
{
throw string("Empty left hand side in rule: ") + $1 + " : " + $3;
}
#endif
m_pMakefile->SplitToItems(m_pMakefile->ExpandExpression($1),*m_pMakefile->m_pCurrentItems);
m_pMakefile->SplitToItems(m_pMakefile->ExpandExpression($3),*m_pMakefile->m_pCurrentDeps);
m_pMakefile->m_DoubleColonRule= ($2==1) ;
PRINTF(("Defining rule %s : %s\n",$1.c_str(),$3.c_str()));
PRINTF((" Expanded to %s : %s\n",m_pMakefile->ExpandExpression($1).c_str(),m_pMakefile->ExpandExpression($3).c_str()));
}
;
rulecolon: COLON {$$=0;} |
DOUBLECOLON {$$=1;}
;
phonyrule: PHONY COLON expression
{
vector Items;
m_pMakefile->SplitToItems(m_pMakefile->ExpandExpression($3),Items);
vector::iterator pIt=Items.begin();
while (pIt!=Items.end())
{
(*pIt)->SetPhony();
pIt++;
}
PRINTF(("Defining phony rule : %s\n",$3.c_str()));
PRINTF((" Expanded to : %s\n",m_pMakefile->ExpandExpression($3).c_str()));
}
NEWLINE
;
autodepsrule: AUTODEPS COLON expression
{
vector Items;
m_pMakefile->SplitToItems(m_pMakefile->ExpandExpression($3),Items);
vector::iterator pIt=Items.begin();
while (pIt!=Items.end())
{
(*pIt)->SetAutoDepsScan(m_pMakefile);
pIt++;
}
PRINTF(("Defining autodeps rule : %s\n",$3.c_str()));
PRINTF((" Expanded to : %s\n",m_pMakefile->ExpandExpression($3).c_str()));
}
NEWLINE
;
envvarstoignorerule: ENVVARS_TOIGNORE COLON expression
{
string VarsStr=m_pMakefile->ExpandExpression($3);
PRINTF(("Defining envvarstoignore rule : %s\n",$3.c_str()));
PRINTF((" Expanded to : %s\n",m_pMakefile->ExpandExpression($3).c_str()));
const char *pTmp=VarsStr.c_str();
while (*pTmp)
{
string Var;
pTmp=NextItem(pTmp,Var);
if (!Var.empty())
{ // Add it to the list of env vars to ignore
m_pMakefile->m_EnvVarsToIgnore.insert(Var);
}
}
}
NEWLINE
;
exportrule: EXPORT space exportstrings NEWLINE |
EXPORT space STRING EQUAL maybeemptyexpression
{
string Val=m_pMakefile->ExpandExpression($5);
m_pMakefile->SetVariable($3,Val);
m_pMakefile->SetExport($3,Val);
PRINTF(("Exporting %s : %s\n",$3.c_str(), Val.c_str()));
}
;
exportstrings : exportstring |
exportstring space exportstrings
;
exportstring : STRING
{
m_pMakefile->SetExport($1,m_pMakefile->ExpandExpression(m_pMakefile->ExpandVar($1)));
PRINTF(("Exporting %s : %s\n",$1.c_str(),m_pMakefile->ExpandExpression(m_pMakefile->ExpandVar($1)).c_str()));
}
;
vpathrule: VPATH space nonspaceexpression space expression NEWLINE
{
m_pMakefile->SetvPath(m_pMakefile->ExpandExpression($3),m_pMakefile->ExpandExpression($5));
PRINTF(("Setting vpath %s to %s\n",$3.c_str(),m_pMakefile->ExpandExpression($5).c_str()));
}
;
varassignment: VARDEF VARVAL
{
m_pMakefile->m_Variables[m_pMakefile->f_strip($1)]=$2;
PRINTF(("Defining variable %s to %s\n",m_pMakefile->f_strip($1).c_str(), $2.c_str()));
}
| STRING EQUAL maybeemptyexpression
{
m_pMakefile->m_Variables[$1]=$3;
PRINTF(("Setting variable %s to %s\n",$1.c_str(), $3.c_str()));
}
;
imvarassignment: STRING IMEQUAL maybeemptyexpression
{
m_pMakefile->m_Variables[$1]=m_pMakefile->ExpandExpression($3);
PRINTF(("Setting variable %s to %s\n",$1.c_str(), m_pMakefile->m_Variables[$1].c_str()));
}
;
pvarassignment: STRING PEQUAL maybeemptyexpression
{
m_pMakefile->m_Variables[$1]=m_pMakefile->ExpandVar($1)+g_SpaceString+$3;
PRINTF(("Adding to variable %s: %s\n",$1.c_str(), $3.c_str()));
}
;
optvarassignment: STRING OPTEQUAL maybeemptyexpression
{
if (!m_pMakefile->IsDefined($1))
{
m_pMakefile->m_Variables[$1]=$3;
PRINTF(("Setting variable %s to %s\n",$1.c_str(), $3.c_str()));
}
}
;
maybeemptyexpression: NEWLINE {$$=g_EmptyString;} |
expression NEWLINE |
expression space NEWLINE
;
expression: nonspaceexpression |
expression space nonspaceexpression {$$=$1+g_SpaceString+$3;}
;
expression_nocolorequal: nonspaceexpression_nocolorequal |
expression_nocolorequal space nonspaceexpression_nocolorequal {$$=$1+g_SpaceString+$3;}
;
nonspaceexpression: simpleexpression |
nonspaceexpression simpleexpression {$$=$1+$2;}
;
nonspaceexpression_nocolorequal: simpleexpression_nocolorequal |
nonspaceexpression_nocolorequal simpleexpression_nocolorequal {$$=$1+$2;}
;
simpleexpression: simpleexpression_nocolorequal |
EQUAL |
COLON |
DOUBLECOLON |
COMMA
;
simpleexpression_nocolorequal: STRING |
DOLLAREXPR
;
%%
/* -------------- body section -------------- */
void yy::mhmakeparser::error (const yy::mhmakeparser::location_type& l, const std::string& m)
{
cerr << l << " -> "<