1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
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.
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.
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/>.
17 AT_BANNER([syntax scanning])
18 m4_define([PSPP_CHECK_SCAN],
19 [sed 's/^-//' < expout-base > expout
20 AT_CHECK([scan-test $1 input], [0], [expout])
22 sed '/^-/d' < expout-base > expout
23 AT_CHECK([scan-test -s $1 input], [0], [expout])])
25 AT_SETUP([identifiers])
28 a aB i5 $x @efg @@. !abcd !* !*a #.# .x _z.
30 QRSTUV./* end of line comment */
31 QrStUv./* end of line comment */ @&t@
32 WXYZ. /* unterminated end of line comment
33 �. /* U+FFFD is not valid in an identifier
35 AT_DATA([expout-base], [dnl
61 STOP "Bad character U+FFFD in input."
68 AT_SETUP([reserved words])
71 and or not eq ge gt le lt ne all by to with
72 AND OR NOT EQ GE GT LE LT NE ALL BY TO WITH
73 andx orx notx eqx gex gtx lex ltx nex allx byx tox withx
76 AT_DATA([expout-base], [dnl
121 PSPP_CHECK_SCAN([-i])
124 AT_SETUP([punctuation])
126 AT_DATA([input], [dnl
127 ~ & | = >= > <= < ~= <> ( ) , - + * / [[ ]] **
128 ~&|=>=><=<~=<>(),-+*/[[]]**
131 AT_DATA([expout-base], [dnl
183 PSPP_CHECK_SCAN([-i])
186 AT_SETUP([positive numbers])
188 AT_DATA([input], [dnl
190 123. /* comment 1 */ /* comment 2 */
192 5e1 6E-1 7e+1 6E+01 6e-03
193 .3E1 .4e-1 .5E+1 .6e+01 .7E-03
194 1.23e1 45.6E-1 78.9e+1 99.9E+01 11.2e-03
197 AT_DATA([expout-base], [dnl
228 STOP "Missing exponent following `1e'."
230 STOP "Missing exponent following `1e+'."
231 STOP "Missing exponent following `1e-'."
234 PSPP_CHECK_SCAN([-i])
237 AT_SETUP([negative numbers])
239 AT_DATA([input-base], [dnl
241 -123. /* comment 1 */ /* comment 2 */
242 -.1 -0.1 -00.1 -00.10
243 -5e1 -6E-1 -7e+1 -6E+01 -6e-03
244 -.3E1 -.4e-1 -.5E+1 -.6e+01 -.7E-03
245 -1.23e1 -45.6E-1 -78.9e+1 -99.9E+01 -11.2e-03
247 -. -1e -e1 -1e+ -1e- -1.
249 AT_DATA([expout-base0], [dnl
280 STOP "Missing exponent following `-1e'."
283 STOP "Missing exponent following `-1e+'."
284 STOP "Missing exponent following `-1e-'."
291 cp expout-base0 expout-base
292 PSPP_CHECK_SCAN([-i])
294 sed 's/ -/ - /g' < input-base > input
295 sed 's/following `-/following `- /' < expout-base0 > expout-base
296 PSPP_CHECK_SCAN([-i])
301 AT_DATA([input], [dnl
303 'Don''t' "Can't" 'Won''t'
304 """quoted""" '"quoted"'
307 "missing double quote
310 'a' /* abc */ + "b" /*
311 + 'c' +/* */"d"/* */+'e'
313 + /* special case: + in column 0 would ordinarily start a new command
330 "abc"+U"FFFD"+u'3048'+"xyz"
332 AT_DATA([expout-base], [dnl
345 STOP "Unterminated string constant."
346 STOP "Unterminated string constant."
363 PSPP_CHECK_SCAN([-i])
366 AT_SETUP([@%:@! construct])
368 AT_DATA([input], [dnl
372 AT_DATA([expout-base], [dnl
383 PSPP_CHECK_SCAN([-i])
386 AT_SETUP([* and COMMENT commands])
388 AT_DATA([input], [dnl
389 * Comment commands "don't
390 have to contain valid tokens.
392 ** Check ambiguity with ** token.
395 comment keyword works too.
397 com is ambiguous with COMPUTE.
399 * Comment need not start at left margin.
401 * Comment ends with blank line
406 AT_DATA([expout-base], [dnl
430 PSPP_CHECK_SCAN([-i])
433 AT_SETUP([DOCUMENT command])
435 AT_DATA([input], [dnl
443 isn't parsed as tokens
447 AT_DATA([expout-base], [dnl
449 STRING "DOCUMENT one line."
461 STRING "first.paragraph"
462 STRING "isn't parsed as tokens"
464 STRING "second paragraph."
469 PSPP_CHECK_SCAN([-i])
472 AT_SETUP([FILE LABEL commands])
474 AT_DATA([input], [dnl
475 FIL label isn't quoted.
479 /**/ lab not quoted here either
482 AT_DATA([expout-base], [dnl
485 STRING "isn't quoted"
493 STRING "not quoted here either"
497 PSPP_CHECK_SCAN([-i])
500 AT_SETUP([BEGIN DATA command])
502 AT_DATA([input], [dnl
515 AT_DATA([expout-base], [dnl
535 PSPP_CHECK_SCAN([-i])
538 AT_SETUP([DO REPEAT command])
540 AT_DATA([input], [dnl
543 do repeat a=1 thru 5.
547 end /* x */ /* y */ repeat print.
551 AT_DATA([expout-base], [dnl
565 STRING " do repeat a=1 thru 5."
566 STRING "another command."
567 STRING "second command"
568 STRING "+ third command."
569 STRING "end /* x */ /* y */ repeat print."
575 PSPP_CHECK_SCAN([-i])
578 AT_SETUP([DO REPEAT command in batch mode])
580 AT_DATA([input], [dnl
587 end /* x */ /* y */ repeat print
596 AT_DATA([expout-base], [dnl
610 STRING "do repeat a=1 thru 5"
611 STRING "another command"
612 STRING "second command"
613 STRING "+ third command"
614 STRING "end /* x */ /* y */ repeat print"
624 STRING " inner command"
629 PSPP_CHECK_SCAN([-b])
632 AT_SETUP([DEFINE command - simple])
634 AT_DATA([input], [dnl
639 AT_DATA([expout-base], [dnl
644 STRING "var1 var2 var3"
645 MACRO_ID "!enddefine"
649 PSPP_CHECK_SCAN([-i])
652 AT_SETUP([DEFINE command - no newline after parentheses])
654 AT_DATA([input], [dnl
655 define !macro1() var1 var2 var3
658 AT_DATA([expout-base], [dnl
663 STRING " var1 var2 var3"
664 MACRO_ID "!enddefine"
668 PSPP_CHECK_SCAN([-i])
671 AT_SETUP([DEFINE command - no newline before !ENDDEFINE])
672 AT_KEYWORDS([scan ENDDEFINE])
673 AT_DATA([input], [dnl
675 var1 var2 var3!enddefine.
677 AT_DATA([expout-base], [dnl
682 STRING "var1 var2 var3"
683 MACRO_ID "!enddefine"
687 PSPP_CHECK_SCAN([-i])
690 AT_SETUP([DEFINE command - all on one line])
692 AT_DATA([input], [dnl
693 define !macro1()var1 var2 var3!enddefine.
695 AT_DATA([expout-base], [dnl
700 STRING "var1 var2 var3"
701 MACRO_ID "!enddefine"
705 PSPP_CHECK_SCAN([-i])
708 AT_SETUP([DEFINE command - empty])
710 AT_DATA([input], [dnl
714 AT_DATA([expout-base], [dnl
719 MACRO_ID "!enddefine"
723 PSPP_CHECK_SCAN([-i])
726 AT_SETUP([DEFINE command - blank lines])
728 AT_DATA([input], [dnl
734 AT_DATA([expout-base], [dnl
741 MACRO_ID "!enddefine"
745 PSPP_CHECK_SCAN([-i])
748 AT_SETUP([DEFINE command - arguments])
750 AT_DATA([input], [dnl
751 define !macro1(a(), b(), c())
754 AT_DATA([expout-base], [dnl
770 MACRO_ID "!enddefine"
774 PSPP_CHECK_SCAN([-i])
777 AT_SETUP([DEFINE command - multiline arguments])
779 AT_DATA([input], [dnl
787 AT_DATA([expout-base], [dnl
803 MACRO_ID "!enddefine"
807 PSPP_CHECK_SCAN([-i])
810 AT_SETUP([DEFINE command - arguments start on second line])
812 AT_DATA([input], [dnl
820 AT_DATA([expout-base], [dnl
832 MACRO_ID "!enddefine"
836 PSPP_CHECK_SCAN([-i])
839 AT_SETUP([DEFINE command - early end of command 1])
841 AT_DATA([input], [dnl
845 AT_DATA([expout-base], [dnl
857 PSPP_CHECK_SCAN([-i])
860 AT_SETUP([DEFINE command - early end of command 2])
862 AT_DATA([input], [dnl
867 AT_DATA([expout-base], [dnl
880 PSPP_CHECK_SCAN([-i])
883 AT_SETUP([DEFINE command - early end of command 3])
885 AT_DATA([input], [dnl
890 AT_DATA([expout-base], [dnl
905 PSPP_CHECK_SCAN([-i])
908 AT_SETUP([DEFINE command - early end of command 4])
909 AT_KEYWORDS([segment])
910 AT_DATA([input], [dnl
911 dnl Notice the command terminator at the end of the DEFINE command,
912 dnl which should not be there and ends it early.
916 AT_DATA([expout-base], [dnl
928 PSPP_CHECK_SCAN([-i])
931 AT_SETUP([DEFINE command - missing !ENDDEFINE])
933 AT_DATA([input], [dnl
938 AT_DATA([expout-base], [dnl
943 STRING "content line 1"
944 STRING "content line 2"
947 PSPP_CHECK_SCAN([-i])
950 AT_SETUP([batch mode])
952 AT_DATA([input], [dnl
954 another line of first command
961 AT_DATA([expout-base], [dnl
984 PSPP_CHECK_SCAN([-b])