// // Copyright (C) 2004-2006 Autodesk, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of version 2.1 of the GNU Lesser // General Public License as published by the Free Software Foundation. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /////////////////////////////////////////////////////////////////////// // Name // yyExpression.y - YACC grammar // // Synopsis // FdoInt32 fdo_expression_yyparse(FdoParse* pParse) // // Description // Parse a FDO expression, and build a parse tree for it. // // Parameters // pParse pointer to context // // Function Value // 0 if successful, 1 otherwise (respect YYACCEPT and YYABORT macros). // If successful, the root node is set in FdoParse to be returned. /////////////////////////////////////////////////////////////////////// %{ #include "Parse.h" #pragma warning(disable:4102) // unreferenced labels in y.tab.c %} // Note, the unions in yyFilter.y and yyExpression.y must be identical %union _YYSTYPE { FdoIDisposable* m_node; // expression or filter parse tree node FdoInt32 m_id; // enumerations, keywords, ... FdoInt32 m_integer; // integer values (Int8, Int16, Int32 ) FdoInt64 m_int64; // 64-bit integer values double m_double; // floating point values (single(float), double) FdoString* m_string; // string _FdoDateTime m_datetime; // date time } // keywords // ... data values %token FdoToken_NULL %token FdoToken_TRUE FdoToken_FALSE %token FdoToken_DATE FdoToken_TIME FdoToken_TIMESTAMP %token FdoToken_GEOMFROMTEXT %token FdoToken_JOINNONE FdoToken_JOININNER FdoToken_JOINRIGHTOUTER FdoToken_JOINLEFTOUTER FdoToken_JOINFULLOUTER FdoToken_JOINCROSS // ... operators %token FdoToken_AND FdoToken_OR FdoToken_NOT FdoToken_LIKE FdoToken_IN FdoToken_SELECT FdoToken_JOIN // ... distance operations %token FdoToken_BEYOND FdoToken_WITHINDISTANCE // ... spatial operations %token FdoToken_CONTAINS FdoToken_COVEREDBY FdoToken_CROSSES %token FdoToken_DISJOINT FdoToken_ENVELOPEINTERSECTS FdoToken_EQUALS FdoToken_INTERSECTS FdoToken_INSIDE %token FdoToken_OVERLAPS FdoToken_TOUCHES FdoToken_WITHIN // ... future use %token FdoToken_RELATE // data types %token FdoToken_IDENTIFIER FdoToken_PARAMETER FdoToken_STRING %token FdoToken_INTEGER FdoToken_INT64 FdoToken_INTHEX FdoToken_INTBIN FdoToken_DOUBLE FdoToken_DATETIME %token FdoToken_BLOB FdoToken_CLOB // operators %token FdoToken_Add FdoToken_Subtract FdoToken_Multiply FdoToken_Divide %token FdoToken_Negate %token FdoToken_EQ FdoToken_NE FdoToken_GT FdoToken_GE FdoToken_LT FdoToken_LE %token FdoToken_LeftParenthesis FdoToken_RightParenthesis %token FdoToken_Comma FdoToken_Dot FdoToken_Colon FdoToken_AS // keywords %token FdoToken_BETWEEN // expression %type BinaryExpression DataValue Expression ExpressionCollection JoinCriteriaCollection %type Function GeometryValue Identifier ComputedIdentifier SubSelectExpression ComputedIdentifierOnly ComputedIdentifier3 %type ValueExpression LiteralValue Parameter UnaryExpression JoinCriteria // filter %type JoinOperations // both %type double string boolean FdoToken_Negate %type FdoToken_BLOB FdoToken_CLOB FdoToken_TRUE FdoToken_FALSE %type FdoToken_NULL FdoToken_GEOMFROMTEXT %type integer int64 inthex intbin datetime %type FdoToken_DOUBLE %type FdoToken_INTEGER %type FdoToken_INT64 %type FdoToken_INTHEX %type FdoToken_INTBIN %type FdoToken_IDENTIFIER FdoToken_STRING FdoToken_PARAMETER %type FdoToken_DATETIME // precedence %left FdoToken_Add FdoToken_Subtract %left FdoToken_Multiply FdoToken_Divide %left FdoToken_Negate %start fdo %% fdo : Expression {pParse->SetRoot(Node_Copy(L"Expression", $1)); YYACCEPT;} | error {Node_Trace(L"ERROR!"); pParse->SetRoot((FdoIDisposable*)NULL); YYABORT;} ; Expression : '(' Expression ')' {$$=Node_Copy(L"(Expression)", $2);} | UnaryExpression {$$=Node_Copy(L"UnaryExpression", $1);} | BinaryExpression {$$=Node_Copy(L"BinaryExpression", $1);} | Function {$$=Node_Copy(L"Function", $1);} | Identifier {$$=Node_Copy(L"Identifier", $1);} | ValueExpression {$$=Node_Copy(L"ValueExpression", $1);} | ComputedIdentifier {$$=Node_Copy(L"ComputedIdentifier", $1);} ; BinaryExpression : Expression FdoToken_Add Expression {$$=Node_Add(L"Add", FdoBinaryExpression::Create((FdoExpression*)$1, FdoBinaryOperations_Add, (FdoExpression*)$3));} | Expression FdoToken_Subtract Expression {$$=Node_Add(L"Subtract", FdoBinaryExpression::Create((FdoExpression*)$1, FdoBinaryOperations_Subtract, (FdoExpression*)$3));} | Expression FdoToken_Multiply Expression {$$=Node_Add(L"Multiply", FdoBinaryExpression::Create((FdoExpression*)$1, FdoBinaryOperations_Multiply, (FdoExpression*)$3));} | Expression FdoToken_Divide Expression {$$=Node_Add(L"Divide", FdoBinaryExpression::Create((FdoExpression*)$1, FdoBinaryOperations_Divide, (FdoExpression*)$3));} ; DataValue : boolean // e.g. TRUE or FALSE {$$=Node_Copy(L"boolean", $1);} // | byte | datetime {$$=Node_Copy(L"datetime", $1);} // | decimal | double // double and single precision {$$=Node_Copy(L"double", $1);} | integer // 16bit, 32bit {$$=Node_Copy(L"integer", $1);} | int64 // 64bit {$$=Node_Copy(L"int64", $1);} | inthex // hex 32bit {$$=Node_Copy(L"inthex", $1);} | intbin // binary 32bit {$$=Node_Copy(L"intbin", $1);} | string // e.g. 'abc', "abc" (NOT!) {$$=Node_Copy(L"string", $1);} | FdoToken_BLOB // '{' bytes... '}' // e.g. BLOB { \x01 \x02 } // TBD? {$$=Node_Copy(L"TODO:BLOB", NULL);} | FdoToken_CLOB // '{' bytes... '}' // e.g. CLOB { \x01 \x02 } // TBD? {$$=Node_Copy(L"TODO:CLOB", NULL);} | FdoToken_NULL // e.g. null {$$=Node_Add(L"NULL", FdoDataValue::Create(FdoDataType_Boolean));} ; boolean : FdoToken_TRUE {$$=Node_Add(L"TRUE", FdoBooleanValue::Create(true));} | FdoToken_FALSE {$$=Node_Add(L"FALSE", FdoBooleanValue::Create(false));} ; string : FdoToken_STRING {$$=Node_Add(L"STRING", FdoStringValue::Create($1));} ; integer : FdoToken_INTEGER {$$=Node_Add(L"INTEGER", FdoInt32Value::Create($1));} ; int64 : FdoToken_INT64 {$$=Node_Add(L"INT64", FdoInt64Value::Create($1));} ; inthex : FdoToken_INTHEX {$$=Node_Add(L"INTHEX", FdoIntHexValue::Create($1));} ; intbin : FdoToken_INTBIN {$$=Node_Add(L"INTBIN", FdoIntBinValue::Create($1));} ; double : FdoToken_DOUBLE {$$=Node_Add(L"DOUBLE", FdoDoubleValue::Create($1));} ; datetime : FdoToken_DATETIME {$$=Node_Add(L"DateTime", FdoDataValue::Create($1));} ; Function : Identifier '(' ExpressionCollection ')' {$$=Node_Add(L"ExpressionCollection", FdoFunction::Create(((FdoIdentifier*)$1)->GetName(), (FdoExpressionCollection*)$3));} ; ComputedIdentifierOnly : '(' Identifier ')' FdoToken_AS Identifier {$$ = Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$5)->GetName(), (FdoExpression*)$2));} | Identifier FdoToken_AS Identifier {$$ = Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$3)->GetName(), (FdoExpression*)$1));} ; ComputedIdentifier3 : '(' Identifier ')' FdoToken_AS Identifier {$$ = Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$5)->GetName(), (FdoExpression*)$2));} | Identifier FdoToken_AS Identifier {$$ = Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$3)->GetName(), (FdoExpression*)$1));} | Identifier {$$ = Node_Add(L"IDENTIFIER", FdoIdentifier::Create(((FdoIdentifier*)$1)->GetName()));} | '(' SubSelectExpression ')' FdoToken_AS Identifier {$$ = Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$5)->GetName(), (FdoExpression*)$2));} | SubSelectExpression FdoToken_AS Identifier {$$ = Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$3)->GetName(), (FdoExpression*)$1));} | '(' Expression ')' FdoToken_AS Identifier {$$ = Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$5)->GetName(), (FdoExpression*)$2));} | Expression FdoToken_AS Identifier {$$ = Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$3)->GetName(), (FdoExpression*)$1));} ; JoinCriteria : FdoToken_JOIN '(' Identifier ',' JoinOperations ')' {$$=Node_Add(L"JoinCriteria", FdoJoinCriteria::Create((FdoIdentifier*)$3, (FdoJoinType)$5));} | FdoToken_JOIN '(' Identifier ',' JoinOperations ',' string ')' {$$=Node_Add(L"JoinCriteria", FdoJoinCriteria::Create((FdoIdentifier*)$3, (FdoJoinType)$5, FdoPtr(FdoFilter::Parse(((FdoStringValue*)$7)->GetString()))));} | FdoToken_JOIN '(' ComputedIdentifierOnly ',' JoinOperations ')' {$$=Node_Add(L"JoinCriteria", FdoJoinCriteria::Create(((FdoComputedIdentifier*)$3)->GetName(), FdoPtr(static_cast(((FdoComputedIdentifier*)$3)->GetExpression())), (FdoJoinType)$5));} | FdoToken_JOIN '(' ComputedIdentifierOnly ',' JoinOperations ',' string ')' {$$=Node_Add(L"JoinCriteria", FdoJoinCriteria::Create(((FdoComputedIdentifier*)$3)->GetName(), FdoPtr(static_cast(((FdoComputedIdentifier*)$3)->GetExpression())), (FdoJoinType)$5, FdoPtr(FdoFilter::Parse(((FdoStringValue*)$7)->GetString()))));} ; JoinCriteriaCollection : JoinCriteria {$$=pParse->AddNodeToDelete(FdoJoinCriteriaCollection::Create()); ((FdoJoinCriteriaCollection*)$$)->Add((FdoJoinCriteria*)$1); Node_Trace(L"JoinCriteria 1");} | JoinCriteriaCollection ',' JoinCriteria {((FdoJoinCriteriaCollection*)$$)->Add((FdoJoinCriteria*)$3); Node_Trace(L"JoinCriteria n");} ; SubSelectExpression : FdoToken_SELECT '(' Identifier ',' ComputedIdentifier3 ')' {$$=Node_Add(L"SubSelectExpression", FdoSubSelectExpression::Create((FdoIdentifier*)$3, (FdoIdentifier*)$5));} | FdoToken_SELECT '(' Identifier ',' ComputedIdentifier3 ',' string ')' {$$=Node_Add(L"SubSelectExpression", FdoSubSelectExpression::Create((FdoIdentifier*)$3, (FdoIdentifier*)$5, FdoPtr(FdoFilter::Parse(((FdoStringValue*)$7)->GetString()))));} | FdoToken_SELECT '(' Identifier ',' ComputedIdentifier3 ',' JoinCriteriaCollection ')' {$$=Node_Add(L"SubSelectExpression", FdoSubSelectExpression::Create((FdoIdentifier*)$3, (FdoIdentifier*)$5, (FdoJoinCriteriaCollection*)$7));} | FdoToken_SELECT '(' Identifier ',' ComputedIdentifier3 ',' string ',' JoinCriteriaCollection ')' {$$=Node_Add(L"SubSelectExpression", FdoSubSelectExpression::Create((FdoIdentifier*)$3, (FdoIdentifier*)$5, FdoPtr(FdoFilter::Parse(((FdoStringValue*)$7)->GetString())), (FdoJoinCriteriaCollection*)$9));} ; ComputedIdentifier : '(' Expression ')' FdoToken_AS Identifier {$$=Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$5)->GetName(), (FdoExpression*)$2));} | Expression FdoToken_AS Identifier {$$=Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$3)->GetName(), (FdoExpression*)$1));} | '(' SubSelectExpression ')' FdoToken_AS Identifier {$$=Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$5)->GetName(), (FdoExpression*)$2));} | SubSelectExpression FdoToken_AS Identifier {$$=Node_Add(L"ComputedIdentifier", FdoComputedIdentifier::Create(((FdoIdentifier*)$3)->GetName(), (FdoExpression*)$1));} ; ExpressionCollection : {$$=pParse->AddNodeToDelete(FdoExpressionCollection::Create());} | Expression {$$=pParse->AddNodeToDelete(FdoExpressionCollection::Create()); ((FdoExpressionCollection*)$$)->Add((FdoExpression*)$1); Node_Trace(L"Expression Arg 1,");} | ExpressionCollection ',' Expression {((FdoExpressionCollection*)$$)->Add((FdoExpression*)$3); Node_Trace(L"Expression Arg N,");} ; GeometryValue : FdoToken_GEOMFROMTEXT '(' FdoToken_STRING ')' {$$=Node_Add(L"GeomFromText('FGFT')", pParse->FgftToGeometryValue($3));} ; Identifier : // e.g. "Address.City", "Street", "City", and "Zip Code" FdoToken_IDENTIFIER {$$ = Node_Add(L"IDENTIFIER", FdoIdentifier::Create($1));} ; ValueExpression : LiteralValue {$$=Node_Copy(L"LiteralValue", $1);} | Parameter {$$=Node_Copy(L"Parameter", $1);} ; LiteralValue : GeometryValue {$$=Node_Copy(L"GeometryValue", $1);} | DataValue {$$=Node_Copy(L"DataValue", $1);} ; Parameter : FdoToken_PARAMETER // ':' string // e.g. "Enter city" {$$ = Node_Add(L"PARAMETER", FdoParameter::Create($1));} | FdoToken_Colon FdoToken_STRING {$$ = Node_Add(L":Parameter", FdoParameter::Create($2));} ; UnaryExpression : FdoToken_Negate Expression {$$ = Node_Add(L"UnaryExpression", FdoUnaryExpression::Create(FdoUnaryOperations_Negate, (FdoExpression*)$2));} ; JoinOperations : FdoToken_JOINNONE {$$=FdoJoinType_None; Node_Trace(L"NONE");} | FdoToken_JOININNER {$$=FdoJoinType_Inner; Node_Trace(L"INNER");} | FdoToken_JOINRIGHTOUTER {$$=FdoJoinType_RightOuter; Node_Trace(L"RIGHTOUTER");} | FdoToken_JOINLEFTOUTER {$$=FdoJoinType_LeftOuter; Node_Trace(L"LEFTOUTER");} | FdoToken_JOINFULLOUTER {$$=FdoJoinType_FullOuter; Node_Trace(L"FULLOUTER");} | FdoToken_JOINCROSS {$$=FdoJoinType_Cross; Node_Trace(L"CROSS");} ; %% /////////////////////////////////////////////////////////////////////// #include FdoInt32 yyerror_default(char *str, FdoInt32 lineno) { #ifdef FDO_YYDEBUG fprintf(stderr, "line %d: %s\n", lineno, str); #endif return 0; } typedef FdoInt32 (*ERRFUNC)(char*, FdoInt32); static ERRFUNC yyerror_func = yyerror_default; FdoInt32 yyerror(FdoParse *pParse, char* str) { return (*yyerror_func)(str, yylineno); } ERRFUNC yyerror_set(ERRFUNC func) { ERRFUNC old_func = yyerror_func; if (func != NULL) yyerror_func = func; return old_func; } static void print_current_token() { //TODO: this has not been updated, but it is unused anyway #ifdef FDO_YYDEBUG char *token_name; if( yychar <= YYMAXTOKEN ) { switch( yychar ) { case IDENTIFIER: token_name = yylval.id; break; default: token_name = yyname[yychar]; break; } } else { token_name = "illegal-name"; } printf( "*** current token is %d (%s) ***\n", yychar, token_name ); #endif }