Parser.jay 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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. | ColumnName DOT Identifier
  203. {
  204. $$ = (string)$1 + "." + (string)$3;
  205. }
  206. ;
  207. RelationName
  208. : Identifier;
  209. Function
  210. : CalcFunction
  211. | AggFunction
  212. ;
  213. AggFunction
  214. : AggFunctionName PAROPEN MultiColumnValue PARCLOSE
  215. {
  216. $$ = new Aggregation (cacheAggregationResults, aggregationRows, (AggregationFunction)$1, (ColumnReference)$3);
  217. }
  218. ;
  219. AggFunctionName
  220. : COUNT { $$ = AggregationFunction.Count; }
  221. | SUM { $$ = AggregationFunction.Sum; }
  222. | AVG { $$ = AggregationFunction.Avg; }
  223. | MAX { $$ = AggregationFunction.Max; }
  224. | MIN { $$ = AggregationFunction.Min; }
  225. | STDEV { $$ = AggregationFunction.StDev; }
  226. | VAR { $$ = AggregationFunction.Var; }
  227. ;
  228. CalcFunction
  229. : IIF PAROPEN BoolExpr COMMA Expr COMMA Expr PARCLOSE
  230. {
  231. $$ = new IifFunction ((IExpression)$3, (IExpression)$5, (IExpression)$7);
  232. }
  233. | SUBSTRING PAROPEN Expr COMMA NumberLiteral COMMA NumberLiteral PARCLOSE
  234. {
  235. long arg1 = (long) $5;
  236. long arg2 = (long) $7;
  237. $$ = new SubstringFunction ((IExpression)$3, Convert.ToInt32(arg1), Convert.ToInt32(arg2));
  238. }
  239. | ISNULL PAROPEN Expr COMMA Expr PARCLOSE
  240. {
  241. $$ = new IsNullFunction ((IExpression)$3, (IExpression)$5);
  242. }
  243. | LEN PAROPEN Expr PARCLOSE
  244. {
  245. $$ = new LenFunction ((IExpression)$3);
  246. }
  247. | TRIM PAROPEN Expr PARCLOSE
  248. {
  249. $$ = new TrimFunction ((IExpression)$3);
  250. }
  251. | CONVERT PAROPEN Expr COMMA TypeSpecifier PARCLOSE
  252. {
  253. $$ = new ConvertFunction ((IExpression)$3, (string)$5);
  254. }
  255. ;
  256. TypeSpecifier
  257. : StringLiteral
  258. | Identifier
  259. ;
  260. IsPredicate
  261. : SingleColumnValue IS NULL
  262. {
  263. $$ = new Comparison (Operation.EQ, (IExpression)$1, new Literal (null));
  264. }
  265. | SingleColumnValue IS NOT NULL
  266. {
  267. $$ = new Comparison (Operation.NE, (IExpression)$1, new Literal (null));
  268. }
  269. ;
  270. LikePredicate
  271. : ArithExpr LIKE StringLiteral
  272. {
  273. $$ = new Like ((IExpression)$1, (string)$3);
  274. }
  275. | ArithExpr NOT LIKE StringLiteral
  276. {
  277. $$ = new Negation (new Like ((IExpression)$1, (string)$3));
  278. }
  279. ;
  280. InPredicate
  281. : SingleColumnValue IN InPredicateValue
  282. {
  283. $$ = new In ((IExpression)$1, (IList)$3);
  284. }
  285. | SingleColumnValue NOT IN InPredicateValue
  286. {
  287. $$ = new Negation (new In ((IExpression)$1, (IList)$4));
  288. }
  289. ;
  290. InPredicateValue
  291. : PAROPEN InValueList PARCLOSE { $$ = $2; }
  292. ;
  293. InValueList
  294. : LiteralValue
  295. {
  296. $$ = new ArrayList();
  297. ((IList)$$).Add ($1);
  298. }
  299. | InValueList COMMA LiteralValue
  300. {
  301. ((IList)($$ = $1)).Add ($3);
  302. }
  303. ;
  304. %%
  305. }