Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

265 lines
8.0 KiB
Plaintext

//
// ExpressionParser.jay
//
// Author:
// Atsushi Enomoto (atsushi@xamarin.com)
//
// Copyright (C) 2013 Xamarin Inc. (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
%{
using System;
using System.Text;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Exceptions;
using Microsoft.Build.Framework;
/*
Pseudo formal syntax for .NET 4.0 expression:
Condition = Expression
Include = Expression*
Expression
BooleanLiteral
TrueLiteral
FalseLiteral
BinaryExpression
Expression "==" Expression
Expression "!=" Expression
Expression ">" Expression
Expression ">=" Expression
Expression "<" Expression
Expression "<=" Expression
Expression "And" Expression
Expression "Or" Expression
UnaryExpression
"!" Expression
PropertyExpression
"$(" PropertyApplication ")"
ItemExpression
"@(" ItemApplication ")"
MetadataBatchingExpression
"%(" MetadataBatchingApplication ")"
StringLiteralOrFunction
StringLiteralOrFunctionName ( "(" FunctionArguments ")" )?
.NET error messages are so detailed which is something like "you forgot '(' after '$' ?" - so
it is likely that the MS tokenizer is hand-written.
*/
namespace Microsoft.Build.Internal.Expressions
{
class ExpressionParser
{
static readonly int yacc_verbose_flag = Environment.GetEnvironmentVariable ("MONO_MSBUILD_PARSER_DEBUG") == "1" ? 1 : 0;
object debug_obj = yacc_verbose_flag == 0 ? null : new yydebug.yyDebugSimple ();
public ExpressionList Parse (string source, ExpressionValidationType validationType)
{
var tokenizer = new ExpressionTokenizer (source, validationType);
return (ExpressionList) yyparse (tokenizer, debug_obj);
}
BinaryExpression Binary (Operator op, object left, object right)
{
return new BinaryExpression () { Operator = op, Left = (Expression) left, Right = (Expression) right, Location = (ILocation) left };
}
%}
%token TRUE_LITERAL
%token FALSE_LITERAL
%token STRING_LITERAL
%token EQ // ==
%token NE // !=
%token GT // >
%token GE // >=
%token LT // <
%token LE // <=
%token AND // AND
%token OR // OR
%token NOT //!
%token DOT //.
%token COMMA //,
%token PROP_OPEN // $(
%token ITEM_OPEN // @(
%token METADATA_OPEN // %(
%token PAREN_OPEN // (
%token PAREN_CLOSE // )
%token BRACE_OPEN // [
%token BRACE_CLOSE // ]
%token COLON2 // ::
%token ARROW // ->
%token NAME
%token ERROR
%start ExpressionList
%%
ExpressionList
: /* empty */
{ $$ = new ExpressionList (); }
| ExpressionList Expression
{ $$ = ((ExpressionList) $1).Add ((Expression) $2); }
;
Expression
: LogicalExpression
;
LogicalExpression
: ComparisonExpression
| LogicalExpression AND LogicalExpression
{ $$ = Binary (Operator.And, $1, $3); }
| LogicalExpression OR LogicalExpression
{ $$ = Binary (Operator.Or, $1, $3); }
;
ComparisonExpression
: UnaryExpression
| UnaryExpression EQ UnaryExpression
{ $$ = Binary (Operator.EQ, $1, $3); }
| UnaryExpression NE UnaryExpression
{ $$ = Binary (Operator.NE, $1, $3); }
| UnaryExpression GT UnaryExpression
{ $$ = Binary (Operator.GT, $1, $3); }
| UnaryExpression GE UnaryExpression
{ $$ = Binary (Operator.GE, $1, $3); }
| UnaryExpression LT UnaryExpression
{ $$ = Binary (Operator.LT, $1, $3); }
| UnaryExpression LE UnaryExpression
{ $$ = Binary (Operator.LE, $1, $3); }
;
UnaryExpression
: PrimaryExpression
| NOT UnaryExpression
{ $$ = new NotExpression () { Negated = (Expression) $2, Location = (ILocation) $1 }; }
;
PrimaryExpression
: BooleanLiteral
| StringLiteral
| UnaryExpression
| PropertyAccessExpression
| ItemAccessExpression
| MetadataAccessExpression
| RawStringLiteralOrFunction
| ParenthesizedExpression
;
BooleanLiteral
: TRUE_LITERAL
{ $$ = new BooleanLiteral () { Value = true, Location = (ILocation) $1 }; }
| FALSE_LITERAL
{ $$ = new BooleanLiteral () { Value = false, Location = (ILocation) $1 }; }
;
PropertyAccessExpression
: PROP_OPEN PropertyAccess PAREN_CLOSE
{ $$ = new PropertyAccessExpression () { Access = (PropertyAccess) $2, Location = (ILocation) $1 }; }
;
PropertyAccess
: NAME
{ $$ = new PropertyAccess () { Name = (NameToken) $1, TargetType = PropertyTargetType.Object, Location = (NameToken) $1 }; }
| Expression DOT NAME
{ $$ = new PropertyAccess () { Name = (NameToken) $3, Target = (Expression) $1, TargetType = PropertyTargetType.Object, Location = (ILocation) $1 }; }
| BRACE_OPEN QualifiedNameExpression BRACE_CLOSE COLON2 NAME
{ $$ = new PropertyAccess () { Name = (NameToken) $5, Target = (Expression) $2, TargetType = PropertyTargetType.Type, Location = (ILocation) $1 }; }
| BRACE_OPEN QualifiedNameExpression BRACE_CLOSE COLON2 NAME PAREN_OPEN FunctionCallArguments PAREN_CLOSE
{ $$ = new PropertyAccess () { Name = (NameToken) $5, Target = (Expression) $2, TargetType = PropertyTargetType.Type, Arguments = (ExpressionList) $7, Location = (ILocation) $1 }; }
;
QualifiedNameExpression
: QualifiedName
{ $$ = new StringLiteral () { Value = (NameToken) $1, Location = (ILocation) $1 }; }
;
QualifiedName
: NAME
| QualifiedName DOT NAME
{ $$ = new NameToken () { Name = ((NameToken) $1).Name + "." + ((NameToken) $3).Name, Column = ((ILocation) $1).Column }; }
;
ItemAccessExpression
: ITEM_OPEN ItemApplication PAREN_CLOSE
{ $$ = new ItemAccessExpression () { Application = (ItemApplication) $2, Location = (ILocation) $1 }; }
;
// looking a bit messy, but gives different location
ItemApplication
: NAME
{ $$ = new ItemApplication () { Name = (NameToken) $1, Location = (ILocation) $1 }; }
| NAME ARROW ExpressionList
{ $$ = new ItemApplication () { Name = (NameToken) $1, Expressions = (ExpressionList) $3, Location = (ILocation) $1 }; }
;
MetadataAccessExpression
: METADATA_OPEN MetadataAccess PAREN_CLOSE
{ $$ = new MetadataAccessExpression () { Access = (MetadataAccess) $2, Location = (ILocation) $1 }; }
;
// looking a bit messy, but gives different location
MetadataAccess
: NAME
{ $$ = new MetadataAccess () { Metadata = (NameToken) $1, Location = (ILocation) $1 }; }
| NAME DOT NAME
{ $$ = new MetadataAccess () { ItemType = (NameToken) $1, Metadata = (NameToken) $3, Location = (ILocation) $1 }; }
;
StringLiteral
: STRING_LITERAL
{ $$ = new StringLiteral () { Value = (NameToken) $1, Location = (ILocation) $1 }; }
;
RawStringLiteralOrFunction
: NAME
{ $$ = new RawStringLiteral () { Value = (NameToken) $1, Location = (ILocation) $1 }; }
| NAME PAREN_OPEN PAREN_CLOSE
{ $$ = new FunctionCallExpression () { Name = (NameToken) $1, Arguments = new ExpressionList (), Location = (ILocation) $1 }; }
| NAME PAREN_OPEN FunctionCallArguments PAREN_CLOSE
{ $$ = new FunctionCallExpression () { Name = (NameToken) $1, Arguments = (ExpressionList) $3, Location = (ILocation) $1 }; }
;
FunctionCallArguments
: /* empty */
{ $$ = new ExpressionList (); }
| Expression
{ $$ = new ExpressionList ().Add ((Expression) $1); }
| FunctionCallArguments COMMA Expression
{ $$ = ((ExpressionList) $1).Add ((Expression) $3); }
;
ParenthesizedExpression
: PAREN_OPEN Expression PAREN_CLOSE
{ $$ = (Expression) $2; }
;
%%
}