[GRASS5] PATCH: sql expression parser

Glynn Clements glynn at gclements.plus.com
Mon Jun 13 05:30:43 EDT 2005


Daniel Calvelo Aros wrote:

> > Can you try the patch I have sent in response to your previous
> > message? It explicitly refactors the grammar to use multiple "levels"
> > of expression rather than relying upon yacc to handle of precedence
> > and fixity.
> 
> It compiles and works under MacOSX too. To test, I use the
> lib/db/sqlp/test/sqlptest command. 
> 
> I like your fixing the grammar better. However, it won't deal with AND/OR
> precedence. I guess the same kind of grammar fixing for y_comparison is
> required, isn't it?

Yes.

I don't know if it handles "NOT x OR y" correctly either (it depends
upon how yacc interprets multiple matching rules; I prefer to write
the grammar so that such situations never arise).

Also, there was a bug in the definition of y_product; it used
y_expression where it should have used y_product.

The attached patch (which supersedes the previous version) should
handle boolean operations correctly, and fix the bug.

-- 
Glynn Clements <glynn at gclements.plus.com>

-------------- next part --------------
Index: lib/db/sqlp/lex.l
===================================================================
RCS file: /grassrepository/grass51/lib/db/sqlp/lex.l,v
retrieving revision 1.19
diff -u -r1.19 lex.l
--- lib/db/sqlp/lex.l	9 Sep 2004 20:02:23 -0000	1.19
+++ lib/db/sqlp/lex.l	13 Jun 2005 09:25:42 -0000
@@ -82,18 +82,6 @@
 		}
  
  /***************************************
-  * ARITHMETICAL OPERATOR
-  * Conflict of  * as operator with * as all columns, what to do?    
-  ***************************************/
-
-"+" 	|
-"-" 	|
-"/" 		{
-			yylval.strval = (char*)strdup(yytext);
-			return ARITHMETICAL_OPERATOR;
-		}
-
- /***************************************
   * COMPARISON OPERATOR
   ***************************************/
 
Index: lib/db/sqlp/yac.y
===================================================================
RCS file: /grassrepository/grass51/lib/db/sqlp/yac.y,v
retrieving revision 1.20
diff -u -r1.20 yac.y
--- lib/db/sqlp/yac.y	9 Sep 2004 20:02:23 -0000	1.20
+++ lib/db/sqlp/yac.y	13 Jun 2005 09:25:42 -0000
@@ -41,13 +41,16 @@
 	/* operators */
 %type <node>	y_column
 %type <node>	y_value
+%type <node>	y_atom
+%type <node>	y_product
 %type <node>	y_expression
 %type <node>	y_comparison
-%type <node>	y_condition
+%type <node>	y_boolean
+%type <node>	y_sub_condition2
 %type <node>	y_sub_condition
+%type <node>	y_condition
 
 	/* literal keyword tokens */
-%token <strval> ARITHMETICAL_OPERATOR
 %token <strval> COMPARISON_OPERATOR
 %token <strval> NAME
 %token <strval> STRING
@@ -194,13 +197,20 @@
 	;
 
 y_sub_condition:	
-		y_comparison { $$ = $1;	}	
-	|	'(' y_sub_condition ')' { $$ = $2; }
-	|	y_sub_condition AND y_sub_condition { $$ = sqpNewExpressionNode (SQLP_AND, $1, $3); }
-	|	y_sub_condition OR y_sub_condition { $$ = sqpNewExpressionNode (SQLP_OR, $1, $3); }
-	|	NOT y_sub_condition { $$ = sqpNewExpressionNode ( SQLP_NOT, NULL, $2); }
+		y_sub_condition2 { $$ = $1; }
+	|	y_sub_condition OR y_sub_condition2 { $$ = sqpNewExpressionNode (SQLP_OR, $1, $3); }
 	;
 
+y_sub_condition2:	
+		y_boolean { $$ = $1; }
+	|	y_sub_condition2 AND y_boolean { $$ = sqpNewExpressionNode (SQLP_AND, $1, $3); }
+	;
+
+y_boolean:	
+		y_comparison { $$ = $1; }
+	|	'(' y_sub_condition ')' { $$ = $2; }
+	|	NOT y_boolean { $$ = sqpNewExpressionNode ( SQLP_NOT, NULL, $2); }
+	;
 
 /* Note EQUAL should be one of COMPARISON but there is maybe some reason ... */
 y_comparison:
@@ -220,14 +230,29 @@
 
 /* Mathematical expression */
 y_expression:
-		y_value				{ $$ = $1; }
-	|	y_column			{ $$ = $1; }
-	|	y_expression ARITHMETICAL_OPERATOR y_expression {
-		    $$ = sqpNewExpressionNode ( sqpOperatorCode($2), $1, $3 );
+		y_product			{ $$ = $1; }
+	|	y_expression '+' y_product {
+		    $$ = sqpNewExpressionNode ( sqpOperatorCode("+"), $1, $3 );
 		}
-	|	y_expression '*' y_expression {
+	|	y_expression '-' y_product {
+		    $$ = sqpNewExpressionNode ( sqpOperatorCode("-"), $1, $3 );
+		}
+	;
+
+y_product:
+		y_atom				{ $$ = $1; }
+	|	y_product '*' y_atom {
 		    $$ = sqpNewExpressionNode ( sqpOperatorCode("*"), $1, $3 );
 		}
+	|	y_product '/' y_atom {
+		    $$ = sqpNewExpressionNode ( sqpOperatorCode("/"), $1, $3 );
+		}
+	;
+
+y_atom:
+		y_value				{ $$ = $1; }
+	|	y_column			{ $$ = $1; }
+	|	'(' y_expression ')'		{ $$ = $2; }
 	;
 
 /* Value used in expressions */ 


More information about the grass-dev mailing list