Parser.jay 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. %{
  2. //
  3. // Parser.jay
  4. //
  5. // Author:
  6. // Juraj Skripsky ([email protected])
  7. //
  8. // (C) 2004 HotFeet GmbH (http://www.hotfeet.ch)
  9. //
  10. using System;
  11. using System.Collections;
  12. using System.Data;
  13. namespace Mono.Data.SqlExpressions {
  14. public class Parser {
  15. bool cacheAggregationResults = false;
  16. DataRow[] aggregationRows = null;
  17. //called by DataTable.Select
  18. //called by DataColumn.set_Expression //FIXME: enable cache in this case?
  19. public Parser () {
  20. ErrorOutput = System.IO.TextWriter.Null;
  21. cacheAggregationResults = true;
  22. }
  23. //called by DataTable.Compute
  24. public Parser (DataRow[] aggregationRows)
  25. {
  26. ErrorOutput = System.IO.TextWriter.Null;
  27. this.aggregationRows = aggregationRows;
  28. }
  29. public IExpression Compile (string sqlExpr)
  30. {
  31. try {
  32. Tokenizer tokenizer = new Tokenizer (sqlExpr);
  33. return (IExpression) yyparse (tokenizer);
  34. } catch (yyParser.yyException e) {
  35. throw new SyntaxErrorException (String.Format ("Expression '{0}' is invalid.", sqlExpr));
  36. }
  37. }
  38. %}
  39. %token PAROPEN PARCLOSE
  40. %token AND OR
  41. %token NOT
  42. %token TRUE FALSE
  43. %token NULL
  44. %token PARENT CHILD
  45. %token EQ LT GT
  46. %token PLUS MINUS
  47. %token MUL DIV MOD
  48. %token DOT COMMA
  49. %token IS IN LIKE
  50. %token COUNT SUM AVG MAX MIN STDEV VAR
  51. %token IIF SUBSTRING ISNULL LEN TRIM CONVERT
  52. %token StringLiteral NumberLiteral DateLiteral
  53. %token Identifier
  54. %token FunctionName
  55. %start Expr
  56. %left OR
  57. %left AND
  58. %left NOT
  59. %left EQ
  60. %left PLUS MINUS
  61. %left MUL DIV MOD
  62. %left UMINUS
  63. %%
  64. Expr
  65. : BoolExpr
  66. | ArithExpr
  67. ;
  68. BoolExpr
  69. : PAROPEN BoolExpr PARCLOSE
  70. {
  71. $$ = (IExpression)$2;
  72. }
  73. | BoolExpr AND BoolExpr
  74. {
  75. $$ = new BoolOperation (Operation.AND, (IExpression)$1, (IExpression)$3);
  76. }
  77. | BoolExpr OR BoolExpr
  78. {
  79. $$ = new BoolOperation (Operation.OR, (IExpression)$1, (IExpression)$3);
  80. }
  81. | NOT BoolExpr
  82. {
  83. $$ = new Negation ((IExpression)$2);
  84. }
  85. | Predicate
  86. ;
  87. Predicate
  88. : CompPredicate
  89. | IsPredicate
  90. | LikePredicate
  91. | InPredicate
  92. ;
  93. CompPredicate
  94. : ArithExpr CompOp ArithExpr
  95. {
  96. $$ = new Comparison ((Operation)$2, (IExpression)$1, (IExpression)$3);
  97. }
  98. ;
  99. CompOp
  100. : EQ { $$ = Operation.EQ; }
  101. | NE { $$ = Operation.NE; }
  102. | LT { $$ = Operation.LT; }
  103. | GT { $$ = Operation.GT; }
  104. | LE { $$ = Operation.LE; }
  105. | GE { $$ = Operation.GE; }
  106. ;
  107. LE : LT EQ; // <=
  108. NE : LT GT; // <>
  109. GE : GT EQ; // >=
  110. ArithExpr
  111. : PAROPEN ArithExpr PARCLOSE
  112. {
  113. $$ = (IExpression)$2;
  114. }
  115. | ArithExpr MUL ArithExpr
  116. {
  117. $$ = new ArithmeticOperation (Operation.MUL, (IExpression)$1, (IExpression)$3);
  118. }
  119. | ArithExpr DIV ArithExpr
  120. {
  121. $$ = new ArithmeticOperation (Operation.DIV, (IExpression)$1, (IExpression)$3);
  122. }
  123. | ArithExpr MOD ArithExpr
  124. {
  125. $$ = new ArithmeticOperation (Operation.MOD, (IExpression)$1, (IExpression)$3);
  126. }
  127. | ArithExpr PLUS ArithExpr
  128. {
  129. $$ = new ArithmeticOperation (Operation.ADD, (IExpression)$1, (IExpression)$3);
  130. }
  131. | ArithExpr MINUS ArithExpr
  132. {
  133. $$ = new ArithmeticOperation (Operation.SUB, (IExpression)$1, (IExpression)$3);
  134. }
  135. | MINUS ArithExpr %prec UMINUS
  136. {
  137. $$ = new Negative ((IExpression)$1);
  138. }
  139. | Function
  140. | Value
  141. ;
  142. Value
  143. : LiteralValue
  144. | ColumnValue
  145. ;
  146. LiteralValue
  147. : StringLiteral { $$ = new Literal ($1); }
  148. | NumberLiteral { $$ = new Literal ($1); }
  149. | DateLiteral { $$ = new Literal ($1); }
  150. | BoolLiteral
  151. ;
  152. BoolLiteral
  153. : TRUE { $$ = new Literal (true); }
  154. | FALSE { $$ = new Literal (false); }
  155. ;
  156. ColumnValue
  157. : ColumnName
  158. {
  159. $$ = new ColumnReference ((string)$1);
  160. }
  161. | PARENT DOT ColumnName
  162. {
  163. $$ = new ColumnReference (ReferencedTable.Parent, null, (string)$3);
  164. }
  165. | PARENT PAROPEN RelationName PARCLOSE DOT ColumnName
  166. {
  167. $$ = new ColumnReference (ReferencedTable.Parent, (string)$3, (string)$6);
  168. }
  169. | CHILD DOT ColumnName
  170. {
  171. $$ = new ColumnReference (ReferencedTable.Child, null, (string)$3);
  172. }
  173. | CHILD PAROPEN RelationName PARCLOSE DOT ColumnName
  174. {
  175. $$ = new ColumnReference (ReferencedTable.Child, (string)$3, (string)$6);
  176. }
  177. ;
  178. ColumnName
  179. : Identifier;
  180. RelationName
  181. : Identifier;
  182. Function
  183. : CalcFunction
  184. | AggFunction
  185. ;
  186. AggFunction
  187. : AggFunctionName PAROPEN ColumnValue PARCLOSE
  188. {
  189. $$ = new Aggregation (cacheAggregationResults, aggregationRows, (AggregationFunction)$1, (ColumnReference)$3);
  190. }
  191. ;
  192. AggFunctionName
  193. : COUNT { $$ = AggregationFunction.Count; }
  194. | SUM { $$ = AggregationFunction.Sum; }
  195. | AVG { $$ = AggregationFunction.Avg; }
  196. | MAX { $$ = AggregationFunction.Max; }
  197. | MIN { $$ = AggregationFunction.Min; }
  198. | STDEV { $$ = AggregationFunction.StDev; }
  199. | VAR { $$ = AggregationFunction.Var; }
  200. ;
  201. CalcFunction
  202. : IIF PAROPEN BoolExpr COMMA Expr COMMA Expr PARCLOSE
  203. {
  204. $$ = new IifFunction ((IExpression)$3, (IExpression)$5, (IExpression)$7);
  205. }
  206. | SUBSTRING PAROPEN Expr COMMA NumberLiteral COMMA NumberLiteral PARCLOSE
  207. {
  208. $$ = new SubstringFunction ((IExpression)$3, (int)$5, (int)$7);
  209. }
  210. | ISNULL PAROPEN ColumnValue COMMA Expr PARCLOSE
  211. {
  212. $$ = new IsNullFunction ((IExpression)$3, (IExpression)$5);
  213. }
  214. | LEN PAROPEN Expr PARCLOSE
  215. {
  216. $$ = new LenFunction ((IExpression)$3);
  217. }
  218. | TRIM PAROPEN Expr PARCLOSE
  219. {
  220. $$ = new TrimFunction ((IExpression)$3);
  221. }
  222. | CONVERT PAROPEN Expr COMMA TypeSpecifier PARCLOSE
  223. {
  224. $$ = new ConvertFunction ((IExpression)$3, (string)$5);
  225. }
  226. ;
  227. TypeSpecifier
  228. : StringLiteral
  229. | Identifier
  230. ;
  231. IsPredicate
  232. : ColumnValue IS NULL
  233. {
  234. $$ = new Comparison (Operation.EQ, (IExpression)$1, new Literal (null));
  235. }
  236. | ColumnValue NOT IS NULL
  237. {
  238. $$ = new Comparison (Operation.NE, (IExpression)$1, new Literal (null));
  239. }
  240. ;
  241. LikePredicate
  242. : ColumnValue LIKE StringLiteral
  243. {
  244. $$ = new Like ((IExpression)$1, (string)$3);
  245. }
  246. | ColumnValue NOT LIKE StringLiteral
  247. {
  248. $$ = new Negation (new Like ((IExpression)$1, (string)$3));
  249. }
  250. ;
  251. InPredicate
  252. : ColumnValue IN InPredicateValue
  253. {
  254. $$ = new In ((IExpression)$1, (IList)$3);
  255. }
  256. | ColumnValue NOT IN InPredicateValue
  257. {
  258. $$ = new Negation (new In ((IExpression)$1, (IList)$4));
  259. }
  260. ;
  261. InPredicateValue
  262. : PAROPEN InValueList PARCLOSE { $$ = $2; }
  263. ;
  264. InValueList
  265. : LiteralValue
  266. {
  267. $$ = new ArrayList();
  268. ((IList)$$).Add ($1);
  269. }
  270. | InValueList COMMA LiteralValue
  271. {
  272. ((IList)($$ = $1)).Add ($3);
  273. }
  274. ;
  275. %%
  276. }