changeset 18233:af8a70d6885c gui-release

improve command parsing * lex.ll (COMMAND_START): Now exclusive. Make all debug strings match patterns for COMMAND_START patterns. (<COMMAND_START>[\(\[\{]*): Match zero or more, not one or more. (<COMMAND_START>[\)\]\}]*): Likewise. (<COMMAND_START>{S}*): Likewise. (<COMMAND_START>([\.]|[^#% \t\r\n\.\,\;\"\'\(\[\{\}\]\)]*): Likewise. * command.tst: New file.
author Michael C. Grant <mcg@cvxr.com>
date Tue, 07 Jan 2014 13:33:39 -0500
parents 18e50356e5e3
children 0eeab61e07d8
files libinterp/parse-tree/lex.ll test/command.tst
diffstat 2 files changed, 163 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.ll	Tue Jan 07 13:19:54 2014 -0500
+++ b/libinterp/parse-tree/lex.ll	Tue Jan 07 13:33:39 2014 -0500
@@ -43,7 +43,7 @@
 
 }
 
-%s COMMAND_START
+%x COMMAND_START
 %s MATRIX_START
 
 %x INPUT_FILE_START
@@ -325,7 +325,7 @@
 %}
 
 <COMMAND_START>({CCHAR}[^\r\n]*)?{NL} {
-    curr_lexer->lexer_debug ("<COMMAND_START>({CCHAR}[^\\r\\n]*)?{NL}");
+    curr_lexer->lexer_debug ("<COMMAND_START>({CCHAR}[^\\r\\n])?{NL}");
 
     COMMAND_ARG_FINISH;
 
@@ -339,7 +339,7 @@
   }
 
 <COMMAND_START>[\,\;] {
-    curr_lexer->lexer_debug( "<COMMAND_START>[\\,\\;]" );
+    curr_lexer->lexer_debug ("<COMMAND_START>[\\,\\;]");
 
     if (yytext[0] != ',' || curr_lexer->command_arg_paren_count == 0)
       {
@@ -361,7 +361,7 @@
 // be slurped into that argument as well.
 %}
 
-<COMMAND_START>[\(\[\{]+ {
+<COMMAND_START>[\(\[\{]* {
     curr_lexer->lexer_debug ("<COMMAND_START>[\\(\\[\\{]+");
 
     curr_lexer->command_arg_paren_count += yyleng;
@@ -369,7 +369,7 @@
     curr_lexer->current_input_column += yyleng;
   }
 
-<COMMAND_START>[\)\]\}]+ {
+<COMMAND_START>[\)\]\}]* {
    curr_lexer->lexer_debug ("<COMMAND_START>[\\)\\]\\}]+");
 
    curr_lexer->command_arg_paren_count -= yyleng;
@@ -407,8 +407,8 @@
 // incorporated into the argument.
 %}
 
-<COMMAND_START>{S}+ {
-    curr_lexer->lexer_debug ("<COMMAND_START>{S}+");
+<COMMAND_START>{S}* {
+    curr_lexer->lexer_debug ("<COMMAND_START>{S}*");
 
     if (curr_lexer->command_arg_paren_count == 0)
       COMMAND_ARG_FINISH;
@@ -422,8 +422,8 @@
 // Everything else is slurped into the command arguments.
 %}
 
-<COMMAND_START>(\.|[^#% \t\r\n\.\,\;\"\'\(\[\{\}\]\)]+) {
-    curr_lexer->lexer_debug ("<COMMAND_START>(\\.|[^#% \\t\\r\\n\\.\\,\\;\\\"\\'\\(\\[\\{\\}\\]\\)]+)");
+<COMMAND_START>([\.]|[^#% \t\r\n\.\,\;\"\'\(\[\{\}\]\)]*) {
+    curr_lexer->lexer_debug ("<COMMAND_START>([\.]|[^#% \\t\\r\n\\.\\,\\;\\\"\\'\\(\\[\\{\\}\\]\\)]*");
 
     curr_lexer->string_text += yytext;
     curr_lexer->current_input_column += yyleng;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/command.tst	Tue Jan 07 13:33:39 2014 -0500
@@ -0,0 +1,154 @@
+## Don't alter the spacing in the command_test lines.  These are
+## specifically testing for possible differences in things like
+##   A(X) or A( X ) or A (X) or A ( X )
+
+%!function command_test (varargin)
+%!  assignin ('caller', 'cmd_out', ['|', sprintf('%s|', varargin{:})]);
+%!endfunction
+
+%!function gobble_command (varargin)
+%!endfunction
+
+## 0, 1, 2, 3 simple arguments
+%!test
+%! command_test
+%! assert (cmd_out, '|')
+%!test
+%! command_test a
+%! assert (cmd_out, '|a|')
+%!test
+%! command_test aa     b
+%! assert (cmd_out, '|aa|b|')
+%!test
+%! command_test aaa  bb    c
+%! assert (cmd_out, '|aaa|bb|c|')
+
+## continuation
+%!test
+%! command_test a...
+%!  bb ccc
+%! assert (cmd_out, '|a|bb|ccc|')
+%!test
+%! command_test a ...
+%!  bb ccc
+%! assert (cmd_out, '|a|bb|ccc|')
+%!test
+%! command_test aa(...
+%!  bb cc
+%! assert (cmd_out, '|aa(|bb|cc|')
+%!test
+%! command_test aa(   ...
+%!  bb cc
+%! assert (cmd_out, '|aa(   |bb|cc|')
+
+## comments
+%!test
+%! command_test aa bb cc%comment
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test aa bb cc#comment
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test aa bb cc   %comment
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test aa bb cc   #comment
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test aa bb cc(  %comment
+%! assert (cmd_out, '|aa|bb|cc(  |')
+%!test
+%! command_test aa bb cc(  #comment
+%! assert (cmd_out, '|aa|bb|cc(  |')
+
+## semicolons and commas; multiple commands
+%!test
+%! command_test aa bb, gobble_command cc
+%! assert (cmd_out, '|aa|bb|')
+%!test
+%! command_test aa bb ; gobble_command cc
+%! assert (cmd_out, '|aa|bb|')
+%!test
+%! command_test aa bb ; command_test cc dd
+%! assert (cmd_out, '|cc|dd|')
+%!test
+%! command_test aa bb
+%!test
+%! command_test cc dd
+%! assert (cmd_out, '|cc|dd|')
+
+## parenthesis matching
+%!test
+%! command_test aa(bb,cc,dd) ee(ff,gg) hh
+%! assert (cmd_out, '|aa(bb,cc,dd)|ee(ff,gg)|hh|')
+%!test
+%! command_test aa([bb,cc)]
+%! assert (cmd_out, '|aa([bb,cc)]|')
+%!test
+%! command_test aa(,@!$@"bb"'cc'
+%! assert (cmd_out, '|aa(,@!$@"bb"''cc''|')
+%!test
+%! command_test aa(bb,cc,dd)
+%! assert (cmd_out, '|aa(bb,cc,dd)|')
+%!test
+%! command_test aa( bb,cc,dd )
+%! assert (cmd_out, '|aa( bb,cc,dd )|')
+%!test
+%! command_test aa (bb,cc,dd)
+%! assert (cmd_out, '|aa|(bb,cc,dd)|')
+%!test
+%! command_test aa ( bb,cc,dd )
+%! assert (cmd_out, '|aa|( bb,cc,dd )|')
+%!test
+%! command_test aa(bb, cc, dd)
+%! assert (cmd_out, '|aa(bb, cc, dd)|')
+%!test
+%! command_test aa( bb, cc, dd )
+%! assert (cmd_out, '|aa( bb, cc, dd )|')
+%!test
+%! command_test aa (bb, cc, dd)
+%! assert (cmd_out, '|aa|(bb, cc, dd)|')
+%!test
+%! command_test aa ( bb, cc, dd )
+%! assert (cmd_out, '|aa|( bb, cc, dd )|')
+
+## single and double quotes
+%!test
+%! command_test "aa" 'bb' cc
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test "aa"'bb'cc
+%! assert (cmd_out, '|aabbcc|')
+%!test
+%! command_test aa'bb'"cc"
+%! assert (cmd_out, '|aabbcc|')
+%!test
+%! command_test "aa"bb'cc'
+%! assert (cmd_out, '|aabbcc|')
+
+## CVX-inspired
+%!test
+%! command_test Z(n,n) hermitian toeplitz
+%! assert (cmd_out, '|Z(n,n)|hermitian|toeplitz|')
+%!test
+%! command_test X( n, n ) symmetric
+%! assert (cmd_out, '|X( n, n )|symmetric|')
+%!test
+%! command_test xw( nm-1, nv );
+%! assert (cmd_out, '|xw( nm-1, nv )|')
+%!test
+%! command_test x( sx ) y( sx ) z( sx )
+%! assert (cmd_out, '|x( sx )|y( sx )|z( sx )|')
+%!test
+%! command_test coeffs(deg+1) complex;
+%! assert (cmd_out, '|coeffs(deg+1)|complex|')
+%!test
+%! command_test w( 1, npairs * nv ) v( 1, npairs * nv )
+%! assert (cmd_out, '|w( 1, npairs * nv )|v( 1, npairs * nv )|')
+%!test
+%! command_test w(m,1)   % edge weights
+%! assert (cmd_out, '|w(m,1)|')
+%!test
+%! command_test x2( size( x ) )
+%! assert (cmd_out, '|x2( size( x ) )|')
+