Parser.jay 6.6 KB

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