From 6bef4798f3b7890b5604a35d700cc98ecb458059 Mon Sep 17 00:00:00 2001 From: Ryszard Glab Date: Tue, 15 Jun 1999 06:14:45 +0000 Subject: [PATCH] See ChangeLog 1990615-07:00 --- harbour/ChangeLog | 18 +++++ harbour/include/hberrors.h | 1 + harbour/include/hbsetup.h | 2 +- harbour/source/compiler/harbour.l | 122 +++++++++++++++++++++--------- harbour/source/compiler/harbour.y | 3 - harbour/tests/broken/linecont.prg | 75 ++++++++++++++++++ 6 files changed, 181 insertions(+), 40 deletions(-) create mode 100644 harbour/tests/broken/linecont.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 224539d1a1..67b49d983f 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,21 @@ +19990615-07:00 Ryszard Glab + +* source/compiler/harbour.y + * removed bug in CodeblockEnd (the names of local variables shoudn't + be released here) + +* source/compiler/harbour.l + * corrected line continnuation logic + +* include/hberrors.h + + added new error message + +* include/hbsetup.h + * removed unneccessary '*/' defined for Watcom compiler + ++ broken/linecont.prg + + new file to test if linne continnuation ';' is handled correctly + 19990614-15:40 EDT David G. Holm * include/extend.h - Added declaration for hb_stricmp() diff --git a/harbour/include/hberrors.h b/harbour/include/hberrors.h index 38336a3766..669ed1c028 100644 --- a/harbour/include/hberrors.h +++ b/harbour/include/hberrors.h @@ -23,6 +23,7 @@ #define ERR_UNCLOSED_STRU 18 #define ERR_UNMATCHED_EXIT 19 #define ERR_SYNTAX2 20 +#define ERR_INCOMPLETE_STMT 21 #define WARN_AMBIGUOUS_VAR 1 #define WARN_VAR_NOT_USED 2 diff --git a/harbour/include/hbsetup.h b/harbour/include/hbsetup.h index 8f0bb51c4f..5f98aec172 100644 --- a/harbour/include/hbsetup.h +++ b/harbour/include/hbsetup.h @@ -17,7 +17,7 @@ * By default we are using automatic lookup (symbol not defined) */ #ifdef __WATCOMC__ - #define HARBOUR_START_PROCEDURE "MAIN" */ + #define HARBOUR_START_PROCEDURE "MAIN" #endif /* This symbol defines if we want an ability to create and link OBJ files diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index d1514e5a48..9bec81d495 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -59,7 +59,9 @@ long lNumber = 0; #define LOOKUP 0 /* scan from the begining of line */ #define OPERATOR -1 -int _iState = LOOKUP; +#define SEPARATOR -2 +static int _iState = LOOKUP; +static int _iOpenBracket = 0; /* Support for Array Index */ int iIndexSets = 0; @@ -95,13 +97,13 @@ SubArray "]"[ \t]*"[" Comment1 "/*"([^\*]|[\*][^\/])*"*/" Comment2 [\/][\/].* Comment ({Comment1}|{Comment2}) -LineCont (;.*\n) -Separator {SpaceTab}|{Comment}|{LineCont} +Separator {SpaceTab}|{Comment} %x COMMENT3 DEFINE DEFINE_PARAMS DEFINE_EXPR %x IFDEF IFNDEF STRING1 STRING2 STRING3 %x NEXT_ BREAK_ CASE_ DO_ WHILE_ WITH_ END_ EXIT_ EXTERNAL_ FIELD_ %x FOR_ FUNCTION_ IIF_ IF_ IN_ INCLUDE_ INIT_ LOCAL_ LOOP_ +%x LINECONT_ %s INDEX %% @@ -196,6 +198,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} i_INDEX_STATE = 0; BEGIN 0; } + _iState =OPERATOR; return yytext[ 0 ]; } @@ -220,7 +223,6 @@ Separator {SpaceTab}|{Comment}|{LineCont} {SpaceTab} ; {Identifier} LastDef( pDefs )->szValue = strdup( yytext ); BEGIN 0; {PseudoFunc} LastDef( pDefs )->szValue = strdup( yytext ); BEGIN 0; - -?{Number} LastDef( pDefs )->szValue = strdup( yytext ); BEGIN 0; {HexNumber} LastDef( pDefs )->szValue = strdup( yytext ); BEGIN 0; "/*".*"*/" ; @@ -254,8 +256,36 @@ Separator {SpaceTab}|{Comment}|{LineCont} {SpaceTab} ; \n.* _iState=LOOKUP; yyless( 1 ); ++iLine; if( ! _iQuiet ) printf( "\rline: %i", iLine ); return '\n'; -;\n _iState=LOOKUP; ++iLine; if( ! _iQuiet ) printf( "\rline: %i", iLine ); - +%{ +/* ************************************************************************ */ +%} +; BEGIN LINECONT_; +{Separator}*\n { + yy_lex_count_lf(); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + if( ! _iQuiet ) printf( "\rline: %i", iLine ); +printf( "\nlineCont"); + _iState=LINECONT_; + } +{Separator}*("("|")") { + GenError( ERR_INCOMPLETE_STMT, yytext, NULL ); + } +{Separator}*. { + yy_lex_count_lf(); + if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; +printf( "\nLineCont"); + unput( yytext[ yyleng-1 ] ); + if( _iOpenBracket == 0 && (_iState==SEPARATOR || _iState==IDENTIFIER) && i_INDEX_STATE==0 ) + { + _iState=LOOKUP; + return '\n'; + } + else + _iState=LINECONT_; + } +%{ +/* ************************************************************************ */ +%} "begin"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? return BEGINSEQ; %{ /* ************************************************************************ */ @@ -282,6 +312,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} /* Clipper does not like break[] at all */ GenError( ERR_SYNTAX, yytext, NULL ); } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*[^_a-zA-Z\[] { /* there is no identifier after "break" */ yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -310,7 +341,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} %{ /* ************************************************************************ */ %} -"case" { BEGIN CASE_; } +"case" BEGIN CASE_; {Separator}*[\:\=\|\$\%\*\,\/\]\)\}\^] { /* there is an operator after "case" */ yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -334,6 +365,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} unput( yytext[ yyleng-2 ] ); return IDENTIFIER; } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*(\n|.) { /* not operator */ yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -387,6 +419,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} return IDENTIFIER; } } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*(.|\n) { /* end of line or any operator */ yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -454,6 +487,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} unput( yytext[ yyleng-1 ] ); return IDENTIFIER; } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*(\n|.) { /* not operator */ yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -529,6 +563,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} return IDENTIFIER; } } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*. { /* any character (not identifier) after EXIT */ yy_lex_count_lf(); unput( yytext[ yyleng-1 ] ); @@ -559,6 +594,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} return IDENTIFIER; } } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*[^_a-zA-Z] { yy_lex_count_lf(); if( yytext[ yyleng-1 ] == '\n' ) @@ -591,6 +627,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} return IDENTIFIER; } } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*[^_a-zA-Z] { yy_lex_count_lf(); if( yytext[ yyleng-1 ] == '\n' ) @@ -633,6 +670,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} unput( yytext[ yyleng-1 ] ); return IDENTIFIER; } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*[^_a-zA-Z] { /* there is no identifier after "FOR" */ yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -654,6 +692,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} _iState=FUNCTION; return FUNCTION; } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*[^_a-zA-Z] { /* Clipper needs FUNCTION in one context only */ GenError( ERR_SYNTAX, ((yytext[ yyleng-1 ]=='\n')?"FUNCTION":yytext), NULL ); } @@ -679,6 +718,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} _iState=IIF; return IIF; } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*[^\(] { GenError( ERR_SYNTAX, ((yytext[ yyleng-1 ]=='\n')?"IIF":yytext), NULL ); } @@ -713,6 +753,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} {Separator}*("++"|"--")/[\n] { GenError( ERR_SYNTAX2, yytext, "IF" ); } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*. { yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -749,6 +790,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} {Separator}*[0-9] { GenError( ERR_SYNTAX, yytext, NULL ); } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*. { yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -768,6 +810,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} _iState =INCLUDE; return INCLUDE; } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*[^\"] { yy_lex_count_lf(); if( yytext[ yyleng-1 ] == '\n' ) @@ -798,6 +841,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} return IDENTIFIER; } } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*[^fFpP] { /* any character (not identifier) after EXIT */ yy_lex_count_lf(); if( yytext[ yyleng-1 ] == '\n' ) @@ -828,6 +872,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} return IDENTIFIER; } } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*[^a-zA-Z] { /* any character (not identifier) after LOCAL */ yy_lex_count_lf(); if( yytext[ yyleng-1 ] == '\n' ) @@ -879,8 +924,9 @@ Separator {SpaceTab}|{Comment}|{LineCont} "next" BEGIN NEXT_; {Separator}*[\n\;] { /* at the end of line */ if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; + if( yytext[ yyleng-1 ] == '\n' ) + --iLine; unput( yytext[ yyleng-1 ] ); - --iLine; if( _iState == LOOKUP ) { /* it is first item in the line */ if( _wForCounter == 0 ) @@ -892,6 +938,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} { /* there is another item in line already */ unput( yytext[ yyleng-1 ] ); yylval.string = strdup( "NEXT" ); + _iState =IDENTIFIER; return IDENTIFIER; } } @@ -998,6 +1045,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} unput( yytext[ yyleng-2 ] ); return IDENTIFIER; } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*. { /* identifiers and literals */ yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -1047,6 +1095,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} /* Clipper does not like with[] at all */ GenError( ERR_SYNTAX, yytext, NULL ); } +{Separator}*;.*\n yy_lex_count_lf(); /* ignore any text after ';' */ {Separator}*. { yy_lex_count_lf(); if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0; @@ -1066,7 +1115,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} %{ /* ************************************************************************ */ %} -"#" _iState =NE1; return NE1; +"#" _iState =OPERATOR; return NE1; "=" _iState =OPERATOR; return yytext[ 0 ]; "+" _iState =OPERATOR; return yytext[ 0 ]; "-" _iState =OPERATOR; return yytext[ 0 ]; @@ -1074,28 +1123,30 @@ Separator {SpaceTab}|{Comment}|{LineCont} [\/] _iState =OPERATOR; return yytext[ 0 ]; "%" _iState =OPERATOR; return yytext[ 0 ]; "$" _iState =OPERATOR; return yytext[ 0 ]; -"<>"|"!=" _iState =NE2; return NE2; -":=" _iState =INASSIGN; return INASSIGN; -"==" _iState =EQ; return EQ; -"++" _iState =INC; return INC; -"--" _iState =DEC; return DEC; -"->" _iState =ALIAS; return ALIAS; -"<=" _iState =LE; return LE; -">=" _iState =GE; return GE; -"+=" _iState =PLUSEQ; return PLUSEQ; -"-=" _iState =MINUSEQ; return MINUSEQ; -"*=" _iState =MULTEQ; return MULTEQ; -"/=" _iState =DIVEQ; return DIVEQ; -"^=" _iState =EXPEQ; return EXPEQ; -"%=" _iState =MODEQ; return MODEQ; -"**"|"^" _iState =POWER; return POWER; -"."[t|y]"." return TRUEVALUE; -"."[f|n]"." return FALSEVALUE; -".and." return AND; -".or." return OR; -"!"|".not." return NOT; +"<>"|"!=" _iState =OPERATOR; return NE2; +":=" _iState =OPERATOR; return INASSIGN; +"==" _iState =OPERATOR; return EQ; +"++" _iState =OPERATOR; return INC; +"--" _iState =OPERATOR; return DEC; +"->" _iState =OPERATOR; return ALIAS; +"<=" _iState =OPERATOR; return LE; +">=" _iState =OPERATOR; return GE; +"+=" _iState =OPERATOR; return PLUSEQ; +"-=" _iState =OPERATOR; return MINUSEQ; +"*=" _iState =OPERATOR; return MULTEQ; +"/=" _iState =OPERATOR; return DIVEQ; +"^=" _iState =OPERATOR; return EXPEQ; +"%=" _iState =OPERATOR; return MODEQ; +"**"|"^" _iState =OPERATOR; return POWER; +"."[t|y]"." _iState =SEPARATOR; return TRUEVALUE; +"."[f|n]"." _iState =SEPARATOR; return FALSEVALUE; +".and." _iState =OPERATOR; return AND; +".or." _iState =OPERATOR; return OR; +"!"|".not." _iState =OPERATOR; return NOT; "::" unput( ':' ); unput( 'f' ); unput( 'l' ); unput( 'e' ); unput( 'S' ); -[,\;\{\}\|\#\&\:\<\>\[\]\(\)\@] _iState =OPERATOR; return yytext[ 0 ]; +[,\{\}\|\#\&\:\<\>\[\]\@] _iState =OPERATOR; return yytext[ 0 ]; +[\(] ++_iOpenBracket; _iState =SEPARATOR; return yytext[ 0 ]; +[\)] --_iOpenBracket; _iState =SEPARATOR; return yytext[ 0 ]; {InvalidNumber} GenError( ERR_NUMERIC_FORMAT, NULL, NULL ); @@ -1202,12 +1253,13 @@ Separator {SpaceTab}|{Comment}|{LineCont} } unput( '[' ); - +/* yyleng = 1; yytext[1] = 0; yylval.string = strdup( ")" ); - +*/ _iState = OPERATOR; + --_iOpenBracket; return ')'; } @@ -1222,17 +1274,15 @@ Separator {SpaceTab}|{Comment}|{LineCont} iIndexSets--; unput( '[' ); - +/* yyleng = 1; yytext[1] = 0; yylval.string = strdup( "]" ); - +*/ _iState = OPERATOR; return ']'; } -{LineCont} ++iLine; - {Identifier} { PDEFINE pDef = FindDef( yytext ); char * szText; int c; diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 7dafd3c297..0a69996eab 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -1069,7 +1069,6 @@ int harbour_main( int argc, char * argv[] ) char szFileName[ _POSIX_PATH_MAX ]; /* filename to parse */ char *szOutPath =""; FILENAME *pFileName =NULL; - PDECLARED_VAR pVarDef, pRelease; if( argc > 1 ) { @@ -3509,7 +3508,6 @@ void CodeBlockEnd() GenPCode1( HIBYTE(wPos) ); pFree =pVar; pVar =pVar->pNext; - OurFree( pFree->szName ); OurFree( pFree ); } @@ -3524,7 +3522,6 @@ void CodeBlockEnd() /* free used variables */ pFree =pVar; pVar =pVar->pNext; - OurFree( pFree->szName ); OurFree( pFree ); } OurFree( pCodeblock ); diff --git a/harbour/tests/broken/linecont.prg b/harbour/tests/broken/linecont.prg new file mode 100644 index 0000000000..7617d3e0c9 --- /dev/null +++ b/harbour/tests/broken/linecont.prg @@ -0,0 +1,75 @@ +//NOTEST +FUNCTION MAIN() +LOCAL a, b + + TEST1() ; TEST2() + ABS( 4 ) + + TEST3() + + TEST4() ; TEST5() + TEST6() + + TEST7 ; + () +// TEST7 ; () //In Clipper: Incomplete statement or unbalanced delimiters + + TEST8( ; + ) +// TEST8( ; ) //In Clipper: Incomplete statement or... + + TEST9( a ; +) +// TEST9( a ; ) //In Clipper: Incomplete statement or... + + TEST10( a, ; +) +// TEST10( a, ; ) //In Clipper: Incomplete statement or... + + TEST11( a, b ; //////////test +) + + a ; +:=b + + a :=; +b + + a ; += ; +b + + a ; ++= ; +b + + TEST12( a := ; +b ; +) + + a :=b[ 1 ; +] + a :=b[ 1 ; ] + + a :=b[ ; +1 , 2 ; +] + a :=b[ ; 1, 2 ; ] + + a :=TEST13()[ 1 ] + a :=TEST13()[ ; + 1 ] + + a :=b[ ; +1; +,; +2; +][ ; + 1 ] + + a :=TEST1(); TEST2() + + a :=TEST1()+ ; TEST2() + +RETURN nil +