# HG changeset patch # User jwe # Date 788163450 0 # Node ID 641c05eaed013d7b7dba0a13587fb6b24bd92995 # Parent de0df9547e08893329af962d0fde8d283abee68a [project @ 1994-12-23 06:17:30 by jwe] diff -r de0df9547e08 -r 641c05eaed01 src/lex.l --- a/src/lex.l Wed Dec 21 15:56:47 1994 +0000 +++ b/src/lex.l Fri Dec 23 06:17:30 1994 +0000 @@ -112,11 +112,14 @@ static int next_token_is_bin_op (int spc_prev, char *yytext); static int next_token_is_postfix_unary_op (int spc_prev, char *yytext); static char *strip_trailing_whitespace (char *s); -static void eat_whitespace (void); static void handle_number (char *yytext); static int handle_string (char delim, int text_style = 0); -static int handle_close_brace (char *yytext); -static int handle_identifier (char *s, int next_tok_is_eq); +static int handle_close_brace (int spc_gobbled); +static int handle_identifier (char *tok, int spc_gobbled); +static int have_continuation (void); +static int have_ellipsis_continuation (void); +static int eat_whitespace (void); +static int eat_continuation (void); %} @@ -203,7 +206,11 @@ %} {SNL}*\]{S}* { - return handle_close_brace (yytext); + fixup_column_count (yytext); + int c = yytext[yyleng-1]; + int cont_is_spc = eat_continuation (); + int spc_gobbled = (cont_is_spc || c == ' ' || c == '\t'); + return handle_close_brace (spc_gobbled); } %{ @@ -234,11 +241,12 @@ } %{ -// Semicolons are both handled as row seprators in matrix constants. +// Semicolons are handled as row seprators in matrix constants. %} {SNLCMT}*;{SNLCMT}* { fixup_column_count (yytext); + eat_whitespace (); quote_is_transpose = 0; cant_be_identifier = 0; convert_spaces_to_comma = 1; @@ -294,8 +302,6 @@ } \] { - promptflag++; - if (! nesting_level.empty ()) nesting_level.pop (); @@ -373,9 +379,11 @@ static char *tok = 0; delete [] tok; tok = strip_trailing_whitespace (yytext); - int c = yyinput (); - unput (c); - return handle_identifier (tok, (c == '=')); + current_input_column += yyleng; + int c = yytext[yyleng-1]; + int cont_is_spc = eat_continuation (); + int spc_gobbled = (cont_is_spc || c == ' ' || c == '\t'); + return handle_identifier (tok, spc_gobbled); } %{ @@ -534,16 +542,14 @@ ")" { if (! nesting_level.empty ()) - { - nesting_level.pop (); - promptflag++; - } - do_comma_insert_check (); + nesting_level.pop (); + current_input_column++; cant_be_identifier = 1; quote_is_transpose = 1; convert_spaces_to_comma = (! nesting_level.empty () && nesting_level.top () == BRACE); + do_comma_insert_check (); return ')'; } @@ -564,8 +570,11 @@ void do_comma_insert_check (void) { + int spc_gobbled = eat_continuation (); int c = yyinput (); yyunput (c, yytext); + if (spc_gobbled) + yyunput (' ', yytext); do_comma_insert = (braceflag && c == '['); } @@ -1070,11 +1079,7 @@ } if (end_found) - { - if (! defining_func && ! looping) - promptflag++; - return END; - } + return END; return 0; } @@ -1318,9 +1323,13 @@ return retval; } -static void +// Discard whitespace, including comments and continuations. +// Return 1 if whitespace appeared in the input, 0 otherwise. + +static int eat_whitespace (void) { + int retval = 0; int in_comment = 0; int c; while ((c = yyinput ()) != EOF) @@ -1331,9 +1340,11 @@ { case ' ': case '\t': + retval = 1; break; case '\n': + retval = 1; in_comment = 0; current_input_column = 0; break; @@ -1343,6 +1354,28 @@ in_comment = 1; break; + case '.': + if (in_comment) + break; + else + { + if (have_ellipsis_continuation ()) + break; + else + goto done; + } + + case '\\': + if (in_comment) + break; + else + { + if (have_continuation ()) + break; + else + goto done; + } + default: if (in_comment) break; @@ -1353,7 +1386,7 @@ done: yyunput (c, yytext); - return; + return retval; } static void @@ -1383,6 +1416,10 @@ do_comma_insert_check (); } +// We have seen a backslash and need to find out if it should be +// treated as a continuation character. If so, this eats it, up to +// and including the new line character. +// // Match whitespace only, followed by a comment character or newline. // Once a comment character is found, discard all input until newline. // If non-whitespace characters are found before comment @@ -1412,6 +1449,7 @@ case '\n': current_input_column = 0; + promptflag--; return 1; default: @@ -1438,6 +1476,10 @@ return 0; } +// We have seen a `.' and need to see if it is the start of a +// continuation. If so, this eats it, up to and including the new +// line character. + static int have_ellipsis_continuation (void) { @@ -1459,6 +1501,24 @@ return 0; } +// See if we have a continuation line. If so, eat it and the leading +// whitespace on the next line. +// Return 1 if whitespace appeared in the input, 0 otherwise. + +static int +eat_continuation (void) +{ + int retval = 0; + int c = yyinput (); + if ((c == '.' && have_ellipsis_continuation ()) + || (c == '\\' && have_continuation ())) + retval = eat_whitespace (); + else + yyunput (c, yytext); + + return retval; +} + static int handle_string (char delim, int text_style) { @@ -1473,17 +1533,13 @@ if (c == '\\') { - if (have_continuation ()) - promptflag--; - else + if (! have_continuation ()) buf << (char) c; goto next; } else if (c == '.') { - if (have_ellipsis_continuation ()) - promptflag--; - else + if (! have_ellipsis_continuation ()) buf << (char) c; goto next; } @@ -1548,10 +1604,8 @@ } static int -handle_close_brace (char *yytext) +handle_close_brace (int spc_gobbled) { - fixup_column_count (yytext); - if (! nesting_level.empty ()) { nesting_level.pop (); @@ -1559,14 +1613,9 @@ } if (braceflag == 0) - { - if (! defining_func) - promptflag++; - BEGIN 0; - } - + BEGIN 0; + int c1 = yyinput (); - if (c1 == '=') { quote_is_transpose = 0; @@ -1588,11 +1637,9 @@ if (braceflag && user_pref.whitespace_in_literal_matrix != 2) { - int c0 = yytext[yyleng-1]; - int spc_prev = (c0 == ' ' || c0 == '\t'); - int bin_op = next_token_is_bin_op (spc_prev, yytext); + int bin_op = next_token_is_bin_op (spc_gobbled, yytext); int postfix_un_op = next_token_is_postfix_unary_op - (spc_prev, yytext); + (spc_gobbled, yytext); int other_op = match_any (c1, ",;\n]"); @@ -1617,7 +1664,7 @@ // an identifier. Handles keywords. static int -handle_identifier (char *tok, int next_tok_is_eq) +handle_identifier (char *tok, int spc_gobbled) { // It is almost always an error for an identifier to be followed // directly by another identifier. Special cases are handled below. @@ -1642,7 +1689,6 @@ { if (kw_token == STYLE) { - current_input_column += yyleng; quote_is_transpose = 0; convert_spaces_to_comma = 1; return kw_token; @@ -1684,6 +1730,10 @@ doing_set = 1; } + int c = yyinput (); + yyunput (c, yytext); + int next_tok_is_eq = (c == '='); + // Make sure we put the return values of a function in the symbol // table that is local to the function. @@ -1702,7 +1752,6 @@ // (if needed). convert_spaces_to_comma = 1; - current_input_column += yyleng; // If we are defining a function and we have not seen the parameter // list yet and the next token is `=', return a token that represents @@ -1735,11 +1784,9 @@ && ! nesting_level.empty () && nesting_level.top () == BRACE) { - int c0 = yytext[yyleng-1]; - int spc_prev = (c0 == ' ' || c0 == '\t'); - int bin_op = next_token_is_bin_op (spc_prev, yytext); + int bin_op = next_token_is_bin_op (spc_gobbled, yytext); - int postfix_un_op = next_token_is_postfix_unary_op (spc_prev, + int postfix_un_op = next_token_is_postfix_unary_op (spc_gobbled, yytext); int c1 = yyinput (); @@ -1747,7 +1794,7 @@ int other_op = match_any (c1, ".,;\n]"); int index_op = (c1 == '(' && (user_pref.whitespace_in_literal_matrix == 0 - || ! spc_prev)); + || ! spc_gobbled)); if (! (postfix_un_op || bin_op || other_op || index_op)) unput (',');