segment: Improve segmentation when DEFINE command has early terminator.
[pspp] / tests / language / lexer / segment.at
1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
3 dnl
4 dnl This program is free software: you can redistribute it and/or modify
5 dnl it under the terms of the GNU General Public License as published by
6 dnl the Free Software Foundation, either version 3 of the License, or
7 dnl (at your option) any later version.
8 dnl
9 dnl This program is distributed in the hope that it will be useful,
10 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 dnl GNU General Public License for more details.
13 dnl
14 dnl You should have received a copy of the GNU General Public License
15 dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 dnl
17 AT_BANNER([syntax segmentation])
18 m4_define([PSPP_CHECK_SEGMENT],
19   [for strip in "" "-s"; do
20      case $strip in # (
21         '') sed 's/^-//' < expout-base > expout ;; # (
22         -s) sed '/^-/d' < expout-base > expout ;;
23      esac
24      AT_CHECK([segment-test $1 $strip input], [0], [expout])
25      AT_CHECK([segment-test -1 $strip $1 input], [0], [expout])
26      AT_CHECK([segment-test -0 $strip $1 input])
27      AT_CHECK([segment-test -01 $strip $1 input])
28    done])
29 \f
30 AT_SETUP([identifiers])
31 AT_KEYWORDS([segment])
32 AT_DATA([input], [dnl
33 a ab abc abcd !abcd
34 A AB ABC ABCD !ABCD
35 aB aBC aBcD !aBcD
36 $x $y $z !$z
37 grève@<00A0>@Ângstrom@<00A0>@poté
38 #a #b #c ## #d !#d
39 @efg @ @@. @#@ !@ @&t@
40 ## # #12345 #.#
41 f@#_.#6
42 GhIjK
43 .x 1y _z
44 ])
45 AT_DATA([expout-base], [dnl
46 identifier      a    space
47 identifier      ab    space
48 identifier      abc    space
49 identifier      abcd    space
50 macro_id        !abcd
51 newline         \n (later)
52
53 identifier      A    space
54 identifier      AB    space
55 identifier      ABC    space
56 identifier      ABCD    space
57 macro_id        !ABCD
58 newline         \n (later)
59
60 identifier      aB    space
61 identifier      aBC    space
62 identifier      aBcD    space
63 macro_id        !aBcD
64 newline         \n (later)
65
66 identifier      $x    space
67 identifier      $y    space
68 identifier      $z    space
69 macro_id        !$z
70 newline         \n (later)
71
72 identifier      grève
73 spaces          <U+00A0>
74 identifier      Ângstrom
75 spaces          <U+00A0>
76 identifier      poté
77 newline         \n (later)
78
79 identifier      #a    space
80 identifier      #b    space
81 identifier      #c    space
82 identifier      ##    space
83 identifier      #d    space
84 macro_id        !#d
85 newline         \n (later)
86
87 identifier      @efg    space
88 identifier      @    space
89 identifier      @@.    space
90 identifier      @#@    space
91 macro_id        !@    space
92 newline         \n (later)
93
94 identifier      ##    space
95 identifier      #    space
96 identifier      #12345    space
97 identifier      #.#
98 newline         \n (later)
99
100 identifier      f@#\_.#6
101 newline         \n (later)
102
103 identifier      GhIjK
104 newline         \n (later)
105
106 start_command   .
107 identifier      x    space
108 number          1
109 identifier      y    space
110 punct           \_
111 identifier      z
112 -newline         \n (later)
113 -
114 end
115 ])
116 PSPP_CHECK_SEGMENT([-i])
117 AT_CLEANUP
118 \f
119 AT_SETUP([identifiers that end in '.'])
120 AT_KEYWORDS([segment])
121 AT_DATA([input], [dnl
122 abcd. abcd.
123 ABCD. ABCD.
124 aBcD. aBcD. @&t@
125 $y. $z. あいうえお.
126 #c. #d..
127 @@. @@....
128 #.#.
129 #abcd.
130 .
131 . @&t@
132 LMNOP. @&t@
133 QRSTUV./* end of line comment */
134 qrstuv. /* end of line comment */
135 QrStUv./* end of line comment */ @&t@
136 wxyz./* unterminated end of line comment
137 WXYZ. /* unterminated end of line comment
138 WxYz./* unterminated end of line comment @&t@
139 ])
140 AT_DATA([expout-base], [dnl
141 identifier      abcd.    space
142 identifier      abcd
143 end_command     .
144 newline         \n (first)
145
146 identifier      ABCD.    space
147 identifier      ABCD
148 end_command     .
149 newline         \n (first)
150
151 identifier      aBcD.    space
152 identifier      aBcD
153 end_command     .    space
154 newline         \n (first)
155
156 identifier      $y.    space
157 identifier      $z.    space
158 identifier      あいうえお
159 end_command     .
160 newline         \n (first)
161
162 identifier      #c.    space
163 identifier      #d.
164 end_command     .
165 newline         \n (first)
166
167 identifier      @@.    space
168 identifier      @@...
169 end_command     .
170 newline         \n (first)
171
172 identifier      #.#
173 end_command     .
174 newline         \n (first)
175
176 identifier      #abcd
177 end_command     .
178 newline         \n (first)
179
180 start_command   .
181 newline         \n (first)
182
183 start_command   .    space
184 newline         \n (first)
185
186 identifier      LMNOP
187 end_command     .    space
188 newline         \n (first)
189
190 identifier      QRSTUV
191 end_command     .
192 comment         /*_end_of_line_comment_*/
193 newline         \n (first)
194
195 identifier      qrstuv
196 end_command     .    space
197 comment         /*_end_of_line_comment_*/
198 newline         \n (first)
199
200 identifier      QrStUv
201 end_command     .
202 comment         /*_end_of_line_comment_*/    space
203 newline         \n (first)
204
205 identifier      wxyz
206 end_command     .
207 comment         /*_unterminated_end_of_line_comment
208 newline         \n (first)
209
210 identifier      WXYZ
211 end_command     .    space
212 comment         /*_unterminated_end_of_line_comment
213 newline         \n (first)
214
215 identifier      WxYz
216 end_command     .
217 comment         /*_unterminated_end_of_line_comment_
218 -newline         \n (first)
219 -
220 end
221 ])
222 PSPP_CHECK_SEGMENT([-i])
223 AT_CLEANUP
224 \f
225 AT_SETUP([reserved words])
226 AT_KEYWORDS([segment])
227 AT_DATA([input], [dnl
228 and or not eq ge gt le lt ne all by to with
229 AND OR NOT EQ GE GT LE LT NE ALL BY TO WITH
230 andx orx notx eqx gex gtx lex ltx nex allx byx tox withx
231 and. with.
232 ])
233 AT_DATA([expout-base], [dnl
234 reserved_word   and    space
235 reserved_word   or    space
236 reserved_word   not    space
237 reserved_word   eq    space
238 reserved_word   ge    space
239 reserved_word   gt    space
240 reserved_word   le    space
241 reserved_word   lt    space
242 reserved_word   ne    space
243 reserved_word   all    space
244 reserved_word   by    space
245 reserved_word   to    space
246 reserved_word   with
247 newline         \n (later)
248
249 reserved_word   AND    space
250 reserved_word   OR    space
251 reserved_word   NOT    space
252 reserved_word   EQ    space
253 reserved_word   GE    space
254 reserved_word   GT    space
255 reserved_word   LE    space
256 reserved_word   LT    space
257 reserved_word   NE    space
258 reserved_word   ALL    space
259 reserved_word   BY    space
260 reserved_word   TO    space
261 reserved_word   WITH
262 newline         \n (later)
263
264 identifier      andx    space
265 identifier      orx    space
266 identifier      notx    space
267 identifier      eqx    space
268 identifier      gex    space
269 identifier      gtx    space
270 identifier      lex    space
271 identifier      ltx    space
272 identifier      nex    space
273 identifier      allx    space
274 identifier      byx    space
275 identifier      tox    space
276 identifier      withx
277 newline         \n (later)
278
279 identifier      and.    space
280 reserved_word   with
281 end_command     .
282 -newline         \n (first)
283 -
284 end
285 ])
286 PSPP_CHECK_SEGMENT([-i])
287 AT_CLEANUP
288 \f
289 AT_SETUP([punctuation])
290 AT_KEYWORDS([segment])
291 AT_DATA([input], [dnl
292 ~ & | = >= > <= < ~= <> ( ) , - + * / [[ ]] **
293 ~&|=>=><=<~=<>(),-+*/[[]]**
294 % : ; ? _ ` { } ~
295 ])
296 AT_DATA([expout-base], [dnl
297 punct           ~    space
298 punct           &    space
299 punct           |    space
300 punct           =    space
301 punct           >=    space
302 punct           >    space
303 punct           <=    space
304 punct           <    space
305 punct           ~=    space
306 punct           <>    space
307 punct           (    space
308 punct           )    space
309 punct           ,    space
310 punct           -    space
311 punct           +    space
312 punct           *    space
313 punct           /    space
314 punct           [[    space
315 punct           ]]    space
316 punct           **
317 newline         \n (later)
318
319 punct           ~
320 punct           &
321 punct           |
322 punct           =
323 punct           >=
324 punct           >
325 punct           <=
326 punct           <
327 punct           ~=
328 punct           <>
329 punct           (
330 punct           )
331 punct           ,
332 punct           -
333 punct           +
334 punct           *
335 punct           /
336 punct           [[
337 punct           ]]
338 punct           **
339 newline         \n (later)
340
341 punct           %    space
342 punct           :    space
343 punct           ;    space
344 punct           ?    space
345 punct           \_    space
346 punct           `    space
347 punct           {    space
348 punct           }    space
349 punct           ~
350 -newline         \n (later)
351 -
352 end
353 ])
354 PSPP_CHECK_SEGMENT([-i])
355 AT_CLEANUP
356 \f
357 AT_SETUP([numbers])
358 AT_KEYWORDS([segment])
359 AT_DATA([input], [dnl
360 0 1 01 001. 1.
361 123. /* comment 1 */ /* comment 2 */
362 .1 0.1 00.1 00.10
363 5e1 6E-1 7e+1 6E+01 6e-03
364 .3E1 .4e-1 .5E+1 .6e+01 .7E-03
365 1.23e1 45.6E-1 78.9e+1 99.9E+01 11.2e-03
366 . 1e e1 1e+ 1e- 1.
367 ])
368 AT_DATA([expout-base], [dnl
369 number          0    space
370 number          1    space
371 number          01    space
372 number          001.    space
373 number          1
374 end_command     .
375 newline         \n (first)
376
377 number          123
378 end_command     .    space
379 comment         /*_comment_1_*/    space
380 comment         /*_comment_2_*/
381 newline         \n (first)
382
383 start_command   .
384 number          1    space
385 number          0.1    space
386 number          00.1    space
387 number          00.10
388 newline         \n (later)
389
390 number          5e1    space
391 number          6E-1    space
392 number          7e+1    space
393 number          6E+01    space
394 number          6e-03
395 newline         \n (later)
396
397 start_command   .
398 number          3E1    space
399 number          .4e-1    space
400 number          .5E+1    space
401 number          .6e+01    space
402 number          .7E-03
403 newline         \n (later)
404
405 number          1.23e1    space
406 number          45.6E-1    space
407 number          78.9e+1    space
408 number          99.9E+01    space
409 number          11.2e-03
410 newline         \n (later)
411
412 start_command   .    space
413 expected_exponent 1e    space
414 identifier      e1    space
415 expected_exponent 1e+    space
416 expected_exponent 1e-    space
417 number          1
418 end_command     .
419 -newline         \n (first)
420 -
421 end
422 ])
423 PSPP_CHECK_SEGMENT([-i])
424 AT_CLEANUP
425 \f
426 AT_SETUP([strings])
427 AT_KEYWORDS([segment])
428 AT_DATA([input], [dnl
429 'x' "y" 'abc'
430 'Don''t' "Can't" 'Won''t'
431 """quoted""" '"quoted"'
432 '' ""
433 'missing end quote
434 "missing double quote
435 x"4142" X'5152'
436 u'fffd' U"041"
437 + new command
438 + /* comment */ 'string continuation'
439 + /* also a punctuator on blank line
440 - 'new command'
441 ])
442 AT_DATA([expout-base], [dnl
443 quoted_string   'x'    space
444 quoted_string   "y"    space
445 quoted_string   'abc'
446 newline         \n (later)
447
448 quoted_string   'Don''t'    space
449 quoted_string   "Can't"    space
450 quoted_string   'Won''t'
451 newline         \n (later)
452
453 quoted_string   """quoted"""    space
454 quoted_string   '"quoted"'
455 newline         \n (later)
456
457 quoted_string   ''    space
458 quoted_string   ""
459 newline         \n (later)
460
461 expected_quote  'missing_end_quote
462 newline         \n (later)
463
464 expected_quote  "missing_double_quote
465 newline         \n (later)
466
467 hex_string      x"4142"    space
468 hex_string      X'5152'
469 newline         \n (later)
470
471 unicode_string  u'fffd'    space
472 unicode_string  U"041"
473 newline         \n (later)
474
475 start_command   +    space
476 identifier      new    space
477 identifier      command
478 newline         \n (later)
479
480 punct           +    space
481 comment         /*_comment_*/    space
482 quoted_string   'string_continuation'
483 newline         \n (later)
484
485 punct           +    space
486 comment         /*_also_a_punctuator_on_blank_line
487 newline         \n (later)
488
489 start_command   -    space
490 quoted_string   'new_command'
491 -newline         \n (later)
492 -
493 end
494 ])
495 PSPP_CHECK_SEGMENT([-i])
496 AT_CLEANUP
497 \f
498 AT_SETUP([@%:@! construct])
499 AT_KEYWORDS([segment])
500 AT_DATA([input], [dnl
501 #! /usr/bin/pspp
502 title my title.
503 #! /usr/bin/pspp
504 ])
505 AT_DATA([expout-base], [dnl
506 shbang          #!_/usr/bin/pspp
507 newline         \n (first)
508
509 identifier      title    space
510 unquoted_string my_title
511 end_command     .
512 newline         \n (first)
513
514 identifier      #
515 macro_id        !    space
516 punct           /
517 identifier      usr
518 punct           /
519 identifier      bin
520 punct           /
521 identifier      pspp
522 -newline         \n (later)
523 -
524 end
525 ])
526 PSPP_CHECK_SEGMENT([-i])
527 AT_CLEANUP
528 \f
529 AT_SETUP([* and COMMENT commands])
530 AT_KEYWORDS([segment])
531 AT_DATA([input], [dnl
532 * Comment commands "don't
533 have to contain valid tokens.
534
535 ** Check ambiguity with ** token.
536 ****************.
537
538 comment keyword works too.
539 COMM also.
540 com is ambiguous with COMPUTE.
541
542    * Comment need not start at left margin.
543
544 * Comment ends with blank line
545
546 next command.
547
548 ])
549 AT_DATA([expout-base], [dnl
550 comment_command *_Comment_commands_"don't
551 newline         \n (COMMENT)
552
553 comment_command have_to_contain_valid_tokens
554 end_command     .
555 newline         \n (first)
556
557 separate_commands
558 newline         \n (first)
559
560 comment_command **_Check_ambiguity_with_**_token
561 end_command     .
562 newline         \n (first)
563
564 comment_command ****************
565 end_command     .
566 newline         \n (first)
567
568 separate_commands
569 newline         \n (first)
570
571 comment_command comment_keyword_works_too
572 end_command     .
573 newline         \n (first)
574
575 comment_command COMM_also
576 end_command     .
577 newline         \n (first)
578
579 identifier      com    space
580 identifier      is    space
581 identifier      ambiguous    space
582 reserved_word   with    space
583 identifier      COMPUTE
584 end_command     .
585 newline         \n (first)
586
587 separate_commands
588 newline         \n (first)
589
590 spaces          ___
591 comment_command *_Comment_need_not_start_at_left_margin
592 end_command     .
593 newline         \n (first)
594
595 separate_commands
596 newline         \n (first)
597
598 comment_command *_Comment_ends_with_blank_line
599 newline         \n (COMMENT)
600
601 separate_commands
602 newline         \n (first)
603
604 identifier      next    space
605 identifier      command
606 end_command     .
607 newline         \n (first)
608
609 -separate_commands
610 -newline         \n (first)
611 -
612 end
613 ])
614 PSPP_CHECK_SEGMENT([-i])
615 AT_CLEANUP
616 \f
617 AT_SETUP([DOCUMENT command])
618 AT_KEYWORDS([segment])
619 AT_DATA([input], [dnl
620 DOCUMENT one line.
621 DOC more
622     than
623         one
624             line.
625 docu
626 first.paragraph
627 isn't parsed as tokens
628
629 second paragraph.
630 ])
631 AT_DATA([expout-base], [dnl
632 start_document
633 document        DOCUMENT_one_line.
634 end_command
635 separate_commands
636 newline         \n (first)
637
638 start_document
639 document        DOC_more
640 newline         \n (DOCUMENT)
641
642 document        ____than
643 newline         \n (DOCUMENT)
644
645 document        ________one
646 newline         \n (DOCUMENT)
647
648 document        ____________line.
649 end_command
650 separate_commands
651 newline         \n (first)
652
653 start_document
654 document        docu
655 newline         \n (DOCUMENT)
656
657 document        first.paragraph
658 newline         \n (DOCUMENT)
659
660 document        isn't_parsed_as_tokens
661 newline         \n (DOCUMENT)
662
663 document
664 newline         \n (DOCUMENT)
665
666 document        second_paragraph.
667 -end_command
668 -separate_commands
669 -newline         \n (first)
670 -
671 end
672 ])
673 PSPP_CHECK_SEGMENT([-i])
674 AT_CLEANUP
675 \f
676 AT_SETUP([TITLE, SUBTITLE, FILE LABEL commands])
677 AT_KEYWORDS([segment])
678 AT_DATA([input], [dnl
679 title/**/'Quoted string title'.
680 tit /*
681 "Quoted string on second line".
682 sub "Quoted string subtitle"
683  .
684
685 TITL /* Not a */ quoted string title.
686 SUBT Not a quoted string /* subtitle
687
688 FIL label isn't quoted.
689 FILE
690   lab 'is quoted'.
691 FILE /*
692 /**/  lab not quoted here either
693
694 ])
695 AT_DATA([expout-base], [dnl
696 identifier      title
697 comment         /**/
698 quoted_string   'Quoted_string_title'
699 end_command     .
700 newline         \n (first)
701
702 identifier      tit    space
703 comment         /*
704 newline         \n (later)
705
706 quoted_string   "Quoted_string_on_second_line"
707 end_command     .
708 newline         \n (first)
709
710 identifier      sub    space
711 quoted_string   "Quoted_string_subtitle"
712 newline         \n (later)
713     space
714 end_command     .
715 newline         \n (first)
716
717 separate_commands
718 newline         \n (first)
719
720 identifier      TITL    space
721 unquoted_string /*_Not_a_*/_quoted_string_title
722 end_command     .
723 newline         \n (first)
724
725 identifier      SUBT    space
726 unquoted_string Not_a_quoted_string_/*_subtitle
727 newline         \n (later)
728
729 separate_commands
730 newline         \n (first)
731
732 identifier      FIL    space
733 identifier      label    space
734 unquoted_string isn't_quoted
735 end_command     .
736 newline         \n (first)
737
738 identifier      FILE
739 newline         \n (later)
740
741 spaces          __
742 identifier      lab    space
743 quoted_string   'is_quoted'
744 end_command     .
745 newline         \n (first)
746
747 identifier      FILE    space
748 comment         /*
749 newline         \n (later)
750
751 comment         /**/
752 spaces          __
753 identifier      lab    space
754 unquoted_string not_quoted_here_either
755 newline         \n (later)
756
757 -separate_commands
758 -newline         \n (first)
759 -
760 end
761 ])
762 PSPP_CHECK_SEGMENT([-i])
763 AT_CLEANUP
764 \f
765 AT_SETUP([BEGIN DATA command])
766 AT_KEYWORDS([segment])
767 AT_DATA([input], [dnl
768 begin data.
769 end data.
770
771 begin data. /*
772 123
773 xxx
774 end data.
775
776 BEG /**/ DAT /*
777 5 6 7 /* x
778
779 end  data
780 end data
781 .
782
783 begin
784  data.
785 data
786 end data.
787
788 begin data "xxx".
789 begin data 123.
790 not data
791 ])
792 AT_DATA([expout-base], [dnl
793 identifier      begin    space
794 identifier      data
795 end_command     .
796 newline         \n (data)
797
798 identifier      end    space
799 identifier      data
800 end_command     .
801 newline         \n (first)
802
803 separate_commands
804 newline         \n (first)
805
806 identifier      begin    space
807 identifier      data
808 end_command     .    space
809 comment         /*
810 newline         \n (data)
811
812 inline_data     123
813 newline         \n (data)
814
815 inline_data     xxx
816 newline         \n (data)
817
818 identifier      end    space
819 identifier      data
820 end_command     .
821 newline         \n (first)
822
823 separate_commands
824 newline         \n (first)
825
826 identifier      BEG    space
827 comment         /**/    space
828 identifier      DAT    space
829 comment         /*
830 newline         \n (data)
831
832 inline_data     5_6_7_/*_x
833 newline         \n (data)
834
835 inline_data
836 newline         \n (data)
837
838 inline_data     end__data
839 newline         \n (data)
840
841 identifier      end    space
842 identifier      data
843 newline         \n (later)
844
845 start_command   .
846 newline         \n (first)
847
848 separate_commands
849 newline         \n (first)
850
851 identifier      begin
852 newline         \n (later)
853     space
854 identifier      data
855 end_command     .
856 newline         \n (data)
857
858 inline_data     data
859 newline         \n (data)
860
861 identifier      end    space
862 identifier      data
863 end_command     .
864 newline         \n (first)
865
866 separate_commands
867 newline         \n (first)
868
869 identifier      begin    space
870 identifier      data    space
871 quoted_string   "xxx"
872 end_command     .
873 newline         \n (first)
874
875 identifier      begin    space
876 identifier      data    space
877 number          123
878 end_command     .
879 newline         \n (first)
880
881 reserved_word   not    space
882 identifier      data
883 -newline         \n (later)
884 -
885 end
886 ])
887 PSPP_CHECK_SEGMENT([-i])
888 AT_CLEANUP
889 \f
890 AT_SETUP([DO REPEAT command])
891 AT_KEYWORDS([segment])
892 AT_DATA([input], [dnl
893 do repeat x=a b c
894           y=d e f.
895   do repeat a=1 thru 5.
896 another command.
897 second command
898 + third command.
899 end /* x */ /* y */ repeat print.
900 end
901  repeat.
902 do
903   repeat #a=1.
904   inner command.
905 end repeat.
906 ])
907 AT_DATA([expout-base], [dnl
908 identifier      do    space
909 identifier      repeat    space
910 identifier      x
911 punct           =
912 identifier      a    space
913 identifier      b    space
914 identifier      c
915 newline         \n (later)
916
917 spaces          __________
918 identifier      y
919 punct           =
920 identifier      d    space
921 identifier      e    space
922 identifier      f
923 end_command     .
924 newline         \n (DO REPEAT)
925
926 do_repeat_command __do_repeat_a=1_thru_5.
927 newline         \n (DO REPEAT)
928
929 do_repeat_command another_command.
930 newline         \n (DO REPEAT)
931
932 do_repeat_command second_command
933 newline         \n (DO REPEAT)
934
935 do_repeat_command +_third_command.
936 newline         \n (DO REPEAT)
937
938 do_repeat_command end_/*_x_*/_/*_y_*/_repeat_print.
939 newline         \n (DO REPEAT)
940
941 identifier      end
942 newline         \n (later)
943     space
944 identifier      repeat
945 end_command     .
946 newline         \n (first)
947
948 identifier      do
949 newline         \n (later)
950
951 spaces          __
952 identifier      repeat    space
953 identifier      #a
954 punct           =
955 number          1
956 end_command     .
957 newline         \n (DO REPEAT)
958
959 do_repeat_command __inner_command.
960 newline         \n (DO REPEAT)
961
962 identifier      end    space
963 identifier      repeat
964 end_command     .
965 -newline         \n (first)
966 -
967 end
968 ])
969 PSPP_CHECK_SEGMENT([-i])
970 AT_CLEANUP
971 \f
972 AT_SETUP([DO REPEAT command in batch mode])
973 AT_KEYWORDS([segment])
974 AT_DATA([input], [dnl
975 do repeat x=a b c
976           y=d e f
977 do repeat a=1 thru 5
978 another command
979 second command
980 + third command
981 end /* x */ /* y */ repeat print
982 end
983  repeat
984 do
985   repeat #a=1
986
987   inner command
988 end repeat
989 ])
990 AT_DATA([expout-base], [dnl
991 identifier      do    space
992 identifier      repeat    space
993 identifier      x
994 punct           =
995 identifier      a    space
996 identifier      b    space
997 identifier      c
998 newline         \n (later)
999
1000 spaces          __________
1001 identifier      y
1002 punct           =
1003 identifier      d    space
1004 identifier      e    space
1005 identifier      f
1006 newline         \n (later)
1007
1008 start_command
1009 do_repeat_command do_repeat_a=1_thru_5
1010 newline         \n (DO REPEAT)
1011
1012 do_repeat_command another_command
1013 newline         \n (DO REPEAT)
1014
1015 do_repeat_command second_command
1016 newline         \n (DO REPEAT)
1017
1018 do_repeat_command +_third_command
1019 newline         \n (DO REPEAT)
1020
1021 do_repeat_command end_/*_x_*/_/*_y_*/_repeat_print
1022 newline         \n (DO REPEAT)
1023
1024 identifier      end
1025 newline         \n (later)
1026     space
1027 identifier      repeat
1028 newline         \n (later)
1029
1030 start_command
1031 identifier      do
1032 newline         \n (later)
1033
1034 spaces          __
1035 identifier      repeat    space
1036 identifier      #a
1037 punct           =
1038 number          1
1039 newline         \n (later)
1040
1041 separate_commands
1042 newline         \n (DO REPEAT)
1043
1044 do_repeat_command __inner_command
1045 newline         \n (DO REPEAT)
1046
1047 identifier      end    space
1048 identifier      repeat
1049 -newline         \n (later)
1050 -
1051 end
1052 ])
1053 PSPP_CHECK_SEGMENT([-b])
1054 AT_CLEANUP
1055 \f
1056 AT_SETUP([DEFINE command - simple])
1057 AT_KEYWORDS([segment])
1058 AT_DATA([input], [dnl
1059 define !macro1()
1060 var1 var2 var3
1061 !enddefine.
1062 ])
1063 AT_DATA([expout-base], [dnl
1064 identifier      define    space
1065 macro_id        !macro1
1066 punct           (
1067 punct           )
1068 newline         \n (DEFINE)
1069
1070 macro_body      var1_var2_var3
1071 newline         \n (DEFINE)
1072
1073 macro_id        !enddefine
1074 end_command     .
1075 -newline         \n (first)
1076 -
1077 end
1078 ])
1079 PSPP_CHECK_SEGMENT([-i])
1080 AT_CLEANUP
1081 \f
1082 AT_SETUP([DEFINE command - empty])
1083 AT_KEYWORDS([segment])
1084 AT_DATA([input], [dnl
1085 define !macro1()
1086 !enddefine.
1087 ])
1088 AT_DATA([expout-base], [dnl
1089 identifier      define    space
1090 macro_id        !macro1
1091 punct           (
1092 punct           )
1093 newline         \n (DEFINE)
1094
1095 macro_id        !enddefine
1096 end_command     .
1097 -newline         \n (first)
1098 -
1099 end
1100 ])
1101 PSPP_CHECK_SEGMENT([-i])
1102 AT_CLEANUP
1103 \f
1104 AT_SETUP([DEFINE command - arguments])
1105 AT_KEYWORDS([segment])
1106 AT_DATA([input], [dnl
1107 define !macro1(a(), b(), c())
1108 !enddefine.
1109 ])
1110 AT_DATA([expout-base], [dnl
1111 identifier      define    space
1112 macro_id        !macro1
1113 punct           (
1114 identifier      a
1115 punct           (
1116 punct           )
1117 punct           ,    space
1118 identifier      b
1119 punct           (
1120 punct           )
1121 punct           ,    space
1122 identifier      c
1123 punct           (
1124 punct           )
1125 punct           )
1126 newline         \n (DEFINE)
1127
1128 macro_id        !enddefine
1129 end_command     .
1130 -newline         \n (first)
1131 -
1132 end
1133 ])
1134 PSPP_CHECK_SEGMENT([-i])
1135 AT_CLEANUP
1136 \f
1137 AT_SETUP([DEFINE command - multiline arguments])
1138 AT_KEYWORDS([segment])
1139 AT_DATA([input], [dnl
1140 define !macro1(
1141   a(), b(
1142   ),
1143   c()
1144 )
1145 !enddefine.
1146 ])
1147 AT_DATA([expout-base], [dnl
1148 identifier      define    space
1149 macro_id        !macro1
1150 punct           (
1151 newline         \n (later)
1152
1153 spaces          __
1154 identifier      a
1155 punct           (
1156 punct           )
1157 punct           ,    space
1158 identifier      b
1159 punct           (
1160 newline         \n (later)
1161
1162 spaces          __
1163 punct           )
1164 punct           ,
1165 newline         \n (later)
1166
1167 spaces          __
1168 identifier      c
1169 punct           (
1170 punct           )
1171 newline         \n (later)
1172
1173 punct           )
1174 newline         \n (DEFINE)
1175
1176 macro_id        !enddefine
1177 end_command     .
1178 -newline         \n (first)
1179 -
1180 end
1181 ])
1182 PSPP_CHECK_SEGMENT([-i])
1183 AT_CLEANUP
1184 \f
1185 AT_SETUP([DEFINE command - arguments start on second line])
1186 AT_KEYWORDS([segment])
1187 AT_DATA([input], [dnl
1188 define !macro1
1189 (x,y,z
1190 )
1191 content 1
1192 content 2
1193 !enddefine.
1194 ])
1195 AT_DATA([expout-base], [dnl
1196 identifier      define    space
1197 macro_id        !macro1
1198 newline         \n (later)
1199
1200 punct           (
1201 identifier      x
1202 punct           ,
1203 identifier      y
1204 punct           ,
1205 identifier      z
1206 newline         \n (later)
1207
1208 punct           )
1209 newline         \n (DEFINE)
1210
1211 macro_body      content_1
1212 newline         \n (DEFINE)
1213
1214 macro_body      content_2
1215 newline         \n (DEFINE)
1216
1217 macro_id        !enddefine
1218 end_command     .
1219 -newline         \n (first)
1220 -
1221 end
1222 ])
1223 PSPP_CHECK_SEGMENT([-i])
1224 AT_CLEANUP
1225 \f
1226 AT_SETUP([DEFINE command - early end of command 1])
1227 AT_KEYWORDS([segment])
1228 AT_DATA([input], [dnl
1229 define !macro1.
1230 data list /x 1.
1231 ])
1232 AT_DATA([expout-base], [dnl
1233 identifier      define    space
1234 macro_id        !macro1
1235 end_command     .
1236 newline         \n (first)
1237
1238 identifier      data    space
1239 identifier      list    space
1240 punct           /
1241 identifier      x    space
1242 number          1
1243 end_command     .
1244 -newline         \n (first)
1245 -
1246 end
1247 ])
1248 PSPP_CHECK_SEGMENT([-i])
1249 AT_CLEANUP
1250 \f
1251 AT_SETUP([DEFINE command - early end of command 2])
1252 AT_KEYWORDS([segment])
1253 AT_DATA([input], [dnl
1254 define !macro1
1255 x.
1256 data list /x 1.
1257 ])
1258 AT_DATA([expout-base], [dnl
1259 identifier      define    space
1260 macro_id        !macro1
1261 newline         \n (later)
1262
1263 identifier      x
1264 end_command     .
1265 newline         \n (first)
1266
1267 identifier      data    space
1268 identifier      list    space
1269 punct           /
1270 identifier      x    space
1271 number          1
1272 end_command     .
1273 -newline         \n (first)
1274 -
1275 end
1276 ])
1277 PSPP_CHECK_SEGMENT([-i])
1278 AT_CLEANUP
1279 \f
1280 AT_SETUP([DEFINE command - early end of command 3])
1281 AT_KEYWORDS([segment])
1282 AT_DATA([input], [dnl
1283 define !macro1(.
1284 x.
1285 data list /x 1.
1286 ])
1287 AT_DATA([expout-base], [dnl
1288 identifier      define    space
1289 macro_id        !macro1
1290 punct           (
1291 end_command     .
1292 newline         \n (first)
1293
1294 identifier      x
1295 end_command     .
1296 newline         \n (first)
1297
1298 identifier      data    space
1299 identifier      list    space
1300 punct           /
1301 identifier      x    space
1302 number          1
1303 end_command     .
1304 -newline         \n (first)
1305 -
1306 end
1307 ])
1308 PSPP_CHECK_SEGMENT([-i])
1309 AT_CLEANUP
1310 \f
1311 AT_SETUP([DEFINE command - early end of command 4])
1312 AT_KEYWORDS([segment])
1313 AT_DATA([input], [dnl
1314 dnl Notice the command terminator at the end of the DEFINE command,
1315 dnl which should not be there and ends it early.
1316 define !macro1.
1317 data list /x 1.
1318 ])
1319 AT_DATA([expout-base], [dnl
1320 identifier      define    space
1321 macro_id        !macro1
1322 end_command     .
1323 newline         \n (first)
1324
1325 identifier      data    space
1326 identifier      list    space
1327 punct           /
1328 identifier      x    space
1329 number          1
1330 end_command     .
1331 -newline         \n (first)
1332 -
1333 end
1334 ])
1335 PSPP_CHECK_SEGMENT([-i])
1336 AT_CLEANUP
1337 \f
1338 AT_SETUP([DEFINE command - missing !ENDDEFINE])
1339 AT_KEYWORDS([segment])
1340 AT_DATA([input], [dnl
1341 define !macro1()
1342 content line 1
1343 content line 2
1344 ])
1345 AT_DATA([expout-base], [dnl
1346 identifier      define    space
1347 macro_id        !macro1
1348 punct           (
1349 punct           )
1350 newline         \n (DEFINE)
1351
1352 macro_body      content_line_1
1353 newline         \n (DEFINE)
1354
1355 macro_body      content_line_2
1356 -newline         \n (DEFINE)
1357 -
1358 end
1359 ])
1360 PSPP_CHECK_SEGMENT([-i])
1361 AT_CLEANUP
1362 \f
1363 AT_SETUP([batch mode])
1364 AT_KEYWORDS([segment])
1365 AT_DATA([input], [dnl
1366 first command
1367      another line of first command
1368 +  second command
1369 third command
1370
1371 fourth command.
1372    fifth command.
1373 ])
1374 AT_DATA([expout-base], [dnl
1375 identifier      first    space
1376 identifier      command
1377 newline         \n (later)
1378
1379 spaces          _____
1380 identifier      another    space
1381 identifier      line    space
1382 identifier      of    space
1383 identifier      first    space
1384 identifier      command
1385 newline         \n (later)
1386
1387 start_command   +
1388 spaces          __
1389 identifier      second    space
1390 identifier      command
1391 newline         \n (later)
1392
1393 start_command
1394 identifier      third    space
1395 identifier      command
1396 newline         \n (later)
1397
1398 separate_commands
1399 newline         \n (first)
1400
1401 identifier      fourth    space
1402 identifier      command
1403 end_command     .
1404 newline         \n (first)
1405
1406 spaces          ___
1407 identifier      fifth    space
1408 identifier      command
1409 end_command     .
1410 -newline         \n (first)
1411 -
1412 end
1413 ])
1414 PSPP_CHECK_SEGMENT([-b])
1415 AT_CLEANUP
1416 \f
1417 AT_SETUP([auto mode])
1418 AT_KEYWORDS([segment])
1419 AT_DATA([input], [dnl
1420 command
1421      another line of command
1422 2sls
1423 +  another command
1424 another line of second command
1425 data list /x 1
1426 aggregate.
1427 print eject.
1428 twostep cluster
1429
1430
1431 fourth command.
1432    fifth command.
1433 ])
1434 AT_DATA([expout-base], [dnl
1435 identifier      command
1436 newline         \n (later)
1437
1438 spaces          _____
1439 identifier      another    space
1440 identifier      line    space
1441 identifier      of    space
1442 identifier      command
1443 newline         \n (later)
1444
1445 start_command
1446 number          2
1447 identifier      sls
1448 newline         \n (later)
1449
1450 start_command   +
1451 spaces          __
1452 identifier      another    space
1453 identifier      command
1454 newline         \n (later)
1455
1456 identifier      another    space
1457 identifier      line    space
1458 identifier      of    space
1459 identifier      second    space
1460 identifier      command
1461 newline         \n (later)
1462
1463 start_command
1464 identifier      data    space
1465 identifier      list    space
1466 punct           /
1467 identifier      x    space
1468 number          1
1469 newline         \n (later)
1470
1471 start_command
1472 identifier      aggregate
1473 end_command     .
1474 newline         \n (first)
1475
1476 identifier      print    space
1477 identifier      eject
1478 end_command     .
1479 newline         \n (first)
1480
1481 identifier      twostep    space
1482 identifier      cluster
1483 newline         \n (later)
1484
1485 separate_commands
1486 newline         \n (first)
1487
1488 separate_commands
1489 newline         \n (first)
1490
1491 identifier      fourth    space
1492 identifier      command
1493 end_command     .
1494 newline         \n (first)
1495
1496 spaces          ___
1497 identifier      fifth    space
1498 identifier      command
1499 end_command     .
1500 -newline         \n (first)
1501 -
1502 end
1503 ])
1504 PSPP_CHECK_SEGMENT([-a])
1505 AT_CLEANUP