Altered expression parser to hand-written one (which was kind of anticipated) for...
[mono.git] / mcs / class / Microsoft.Build / Microsoft.Build.Internal / ExpressionParser.jay
1 %{
2
3 using System;
4 using System.Text;
5 using Microsoft.Build.Evaluation;
6 using Microsoft.Build.Exceptions;
7 using Microsoft.Build.Framework;
8
9 /*
10
11 Pseudo formal syntax for .NET 4.0 expression:
12
13 Condition = Expression
14 Include = Expression*
15
16  Expression
17         BooleanLiteral
18                 TrueLiteral
19                 FalseLiteral
20         BinaryExpression
21                 Expression "==" Expression
22                 Expression "!=" Expression
23                 Expression ">" Expression
24                 Expression ">=" Expression
25                 Expression "<" Expression
26                 Expression "<=" Expression
27                 Expression "And" Expression
28                 Expression "Or" Expression
29         UnaryExpression
30                 "!" Expression
31         PropertyExpression
32                 "$(" PropertyApplication ")"
33         ItemExpression
34                 "@(" ItemApplication ")"
35         MetadataBatchingExpression
36                 "%(" MetadataBatchingApplication ")"
37   StringLiteralOrFunction
38                 StringLiteralOrFunctionName ( "(" FunctionArguments ")" )?
39
40 .NET error messages are so detailed which is something like "you forgot '(' after '$' ?" - so
41 it is likely that the MS tokenizer is hand-written.
42
43 */
44
45 namespace Microsoft.Build.Internal
46 {
47         class ExpressionParser
48         {
49                 const int yacc_verbose_flag = 1;
50
51                 object debug_obj = yacc_verbose_flag == 0 ? null : new yydebug.yyDebugSimple ();
52                 
53                 public ExpressionList Parse (string source, ExpressionValidationType validationType)
54                 {
55                         var tokenizer = new ExpressionTokenizer (source, validationType);
56                         return (ExpressionList) yyparse (tokenizer, debug_obj);
57                 }
58 %}
59
60 %token TRUE_LITERAL
61 %token FALSE_LITERAL
62 %token EQ // ==
63 %token NE // !=
64 %token GT // >
65 %token GE // >=
66 %token LT // <
67 %token LE // <=
68 %token AND // AND
69 %token OR // OR
70 %token NOT //!
71 %token DOT //.
72 %token COMMA //,
73 %token APOS // '
74 %token QUOT // "
75 %token PROP_OPEN // $(
76 %token ITEM_OPEN // @(
77 %token METADATA_OPEN // %(
78 %token PAREN_OPEN // (
79 %token PAREN_CLOSE // )
80 %token COLON2 // ::
81 %token ARROW // ->
82 %token NAME
83 %token ERROR
84
85 %start ExpressionList
86
87 %%
88
89 ExpressionList
90         : /* empty */
91           { $$ = new ExpressionList (); }
92         | ExpressionList Expression
93           { $$ = ((ExpressionList) $1).Add ((Expression) $2); }
94         ;
95
96 ExpressionExceptStringLiteralList
97         : /* empty */
98           { $$ = new ExpressionList (); }
99         | ExpressionExceptStringLiteralList ExpressionExceptStringLiteral
100           { $$ = ((ExpressionList) $1).Add ((Expression) $2); }
101         ;
102
103 Expression
104         : ExpressionExceptStringLiteral
105         | StringLiteralExpression
106         ;
107
108 ExpressionExceptStringLiteral
109         : BooleanLiteral
110         | BinaryExpression
111         | UnaryExpression
112         | PropertyAccessExpression
113         | ItemAccessExpression
114         | MetadataAccessExpression
115         | RawStringLiteralOrFunction
116         | ParenthesizedExpression
117         ;
118
119 BooleanLiteral
120         : TRUE_LITERAL
121           { $$ = new BooleanLiteral () { Value = true, Location = (ILocation) $1 }; }
122         | FALSE_LITERAL
123           { $$ = new BooleanLiteral () { Value = false, Location = (ILocation) $1 }; }
124         ;
125
126 BinaryExpression
127         : Expression EQ Expression
128         | Expression NE Expression
129         | Expression GT Expression
130         | Expression GE Expression
131         | Expression LT Expression
132         | Expression LE Expression
133         | Expression AND Expression
134         | Expression OR Expression
135         ;
136
137 UnaryExpression
138         : NOT Expression
139           { $$ = new NotExpression () { Negated = (Expression) $2, Location = (ILocation) $1 }; }
140         ;
141
142 PropertyAccessExpression
143         : PROP_OPEN PropertyAccess PAREN_CLOSE
144           { $$ = new PropertyAccessExpression () { Access = (PropertyAccess) $2, Location = (ILocation) $1 }; }
145         ;
146
147 PropertyAccess
148         : NAME
149           { $$ = new PropertyAccess () { Name = (NameToken) $1, Location = (NameToken) $1 }; }
150         | Expression DOT NAME
151           { $$ = new PropertyAccess () { Name = (NameToken) $3, Target = (Expression) $1, Location = (ILocation) $1 }; }
152         ;
153
154 ItemAccessExpression
155         : ITEM_OPEN ItemApplication PAREN_CLOSE
156           { $$ = new ItemAccessExpression () { Application = (ItemApplication) $2, Location = (ILocation) $1 }; }
157         ;
158
159 // looking a bit messy, but gives different location
160 ItemApplication
161         : NAME
162         | NAME ARROW ExpressionList
163           { $$ = new ItemApplication () { Name = (NameToken) $1, Expressions = (ExpressionList) $3, Location = (ILocation) $1 }; }
164         ;
165
166 MetadataAccessExpression
167         : METADATA_OPEN MetadataAccess PAREN_CLOSE
168           { $$ = new MetadataAccessExpression () { Access = (MetadataAccess) $2, Location = (ILocation) $1 }; }
169         ;
170
171 // looking a bit messy, but gives different location
172 MetadataAccess
173         : NAME
174           { $$ = new MetadataAccess () { Metadata = (NameToken) $1, Location = (ILocation) $1 }; }
175         | NAME DOT NAME
176           { $$ = new MetadataAccess () { Item = (NameToken) $1, Metadata = (NameToken) $3, Location = (ILocation) $1 }; }
177         ;
178
179 StringLiteralExpression
180         : APOS ExpressionExceptStringLiteralList APOS
181           { $$ = new StringLiteralExpression () { Contents = (ExpressionList) $2, Location = (ILocation) $1 }; }
182         | QUOT ExpressionExceptStringLiteralList QUOT
183           { $$ = new StringLiteralExpression () { Contents = (ExpressionList) $2, Location = (ILocation) $1 }; }
184         ;
185
186 RawStringLiteralOrFunction
187         : NAME
188           { $$ = new RawStringLiteral () { Value = (NameToken) $1, Location = (ILocation) $1 }; }
189         | NAME PAREN_OPEN PAREN_CLOSE
190           { $$ = new FunctionCallExpression () { Name = (NameToken) $1, Arguments = new ExpressionList (), Location = (ILocation) $1 }; }
191         | NAME PAREN_OPEN FunctionCallArguments PAREN_CLOSE
192           { $$ = new FunctionCallExpression () { Name = (NameToken) $1, Arguments = (ExpressionList) $3, Location = (ILocation) $1 }; }
193         ;
194
195 FunctionCallArguments
196         : Expression
197           { $$ = new ExpressionList (); }
198         | FunctionCallArguments COMMA Expression
199           { $$ = ((ExpressionList) $1).Add ((Expression) $3); }
200         ;
201
202 ParenthesizedExpression
203         : PAREN_OPEN Expression PAREN_CLOSE
204           { $$ = (Expression) $2; }
205         ;
206
207 %%
208
209         }