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 #.# .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
58 STOP "Bad character U+FFFD in input."
65 AT_SETUP([reserved words])
68 and or not eq ge gt le lt ne all by to with
69 AND OR NOT EQ GE GT LE LT NE ALL BY TO WITH
70 andx orx notx eqx gex gtx lex ltx nex allx byx tox withx
73 AT_DATA([expout-base], [dnl
118 PSPP_CHECK_SCAN([-i])
121 AT_SETUP([punctuation])
123 AT_DATA([input], [dnl
124 ~ & | = >= > <= < ~= <> ( ) , - + * / [[ ]] **
125 ~&|=>=><=<~=<>(),-+*/[[]]**
128 AT_DATA([expout-base], [dnl
180 PSPP_CHECK_SCAN([-i])
183 AT_SETUP([positive numbers])
185 AT_DATA([input], [dnl
187 123. /* comment 1 */ /* comment 2 */
189 5e1 6E-1 7e+1 6E+01 6e-03
190 .3E1 .4e-1 .5E+1 .6e+01 .7E-03
191 1.23e1 45.6E-1 78.9e+1 99.9E+01 11.2e-03
194 AT_DATA([expout-base], [dnl
225 STOP "Missing exponent following `1e'."
227 STOP "Missing exponent following `1e+'."
228 STOP "Missing exponent following `1e-'."
231 PSPP_CHECK_SCAN([-i])
234 AT_SETUP([negative numbers])
236 AT_DATA([input-base], [dnl
238 -123. /* comment 1 */ /* comment 2 */
239 -.1 -0.1 -00.1 -00.10
240 -5e1 -6E-1 -7e+1 -6E+01 -6e-03
241 -.3E1 -.4e-1 -.5E+1 -.6e+01 -.7E-03
242 -1.23e1 -45.6E-1 -78.9e+1 -99.9E+01 -11.2e-03
244 -. -1e -e1 -1e+ -1e- -1.
246 AT_DATA([expout-base0], [dnl
277 STOP "Missing exponent following `-1e'."
280 STOP "Missing exponent following `-1e+'."
281 STOP "Missing exponent following `-1e-'."
288 cp expout-base0 expout-base
289 PSPP_CHECK_SCAN([-i])
291 sed 's/ -/ - /g' < input-base > input
292 sed 's/following `-/following `- /' < expout-base0 > expout-base
293 PSPP_CHECK_SCAN([-i])
298 AT_DATA([input], [dnl
300 'Don''t' "Can't" 'Won''t'
301 """quoted""" '"quoted"'
304 "missing double quote
307 'a' /* abc */ + "b" /*
308 + 'c' +/* */"d"/* */+'e'
310 + /* special case: + in column 0 would ordinarily start a new command
327 "abc"+U"FFFD"+u'3048'+"xyz"
329 AT_DATA([expout-base], [dnl
342 STOP "Unterminated string constant."
343 STOP "Unterminated string constant."
360 PSPP_CHECK_SCAN([-i])
363 AT_SETUP([@%:@! construct])
365 AT_DATA([input], [dnl
369 AT_DATA([expout-base], [dnl
380 PSPP_CHECK_SCAN([-i])
383 AT_SETUP([* and COMMENT commands])
385 AT_DATA([input], [dnl
386 * Comment commands "don't
387 have to contain valid tokens.
389 ** Check ambiguity with ** token.
392 comment keyword works too.
394 com is ambiguous with COMPUTE.
396 * Comment need not start at left margin.
398 * Comment ends with blank line
403 AT_DATA([expout-base], [dnl
427 PSPP_CHECK_SCAN([-i])
430 AT_SETUP([DOCUMENT command])
432 AT_DATA([input], [dnl
440 isn't parsed as tokens
444 AT_DATA([expout-base], [dnl
446 STRING "DOCUMENT one line."
458 STRING "first.paragraph"
459 STRING "isn't parsed as tokens"
461 STRING "second paragraph."
466 PSPP_CHECK_SCAN([-i])
469 AT_SETUP([FILE LABEL commands])
471 AT_DATA([input], [dnl
472 FIL label isn't quoted.
476 /**/ lab not quoted here either
479 AT_DATA([expout-base], [dnl
482 STRING "isn't quoted"
490 STRING "not quoted here either"
494 PSPP_CHECK_SCAN([-i])
497 AT_SETUP([BEGIN DATA command])
499 AT_DATA([input], [dnl
512 AT_DATA([expout-base], [dnl
532 PSPP_CHECK_SCAN([-i])
535 AT_SETUP([DO REPEAT command])
537 AT_DATA([input], [dnl
540 do repeat a=1 thru 5.
544 end /* x */ /* y */ repeat print.
548 AT_DATA([expout-base], [dnl
562 STRING " do repeat a=1 thru 5."
563 STRING "another command."
564 STRING "second command"
565 STRING "+ third command."
566 STRING "end /* x */ /* y */ repeat print."
572 PSPP_CHECK_SCAN([-i])
575 AT_SETUP([DO REPEAT command in batch mode])
577 AT_DATA([input], [dnl
584 end /* x */ /* y */ repeat print
593 AT_DATA([expout-base], [dnl
607 STRING "do repeat a=1 thru 5"
608 STRING "another command"
609 STRING "second command"
610 STRING "+ third command"
611 STRING "end /* x */ /* y */ repeat print"
621 STRING " inner command"
626 PSPP_CHECK_SCAN([-b])
629 AT_SETUP([DEFINE command - simple])
631 AT_DATA([input], [dnl
636 AT_DATA([expout-base], [dnl
641 STRING "var1 var2 var3"
642 MACRO_ID "!enddefine"
646 PSPP_CHECK_SCAN([-i])
649 AT_SETUP([DEFINE command - no newline after parentheses])
651 AT_DATA([input], [dnl
652 define !macro1() var1 var2 var3
655 AT_DATA([expout-base], [dnl
660 STRING " var1 var2 var3"
661 MACRO_ID "!enddefine"
665 PSPP_CHECK_SCAN([-i])
668 AT_SETUP([DEFINE command - no newline before !ENDDEFINE])
669 AT_KEYWORDS([scan ENDDEFINE])
670 AT_DATA([input], [dnl
672 var1 var2 var3!enddefine.
674 AT_DATA([expout-base], [dnl
679 STRING "var1 var2 var3"
680 MACRO_ID "!enddefine"
684 PSPP_CHECK_SCAN([-i])
687 AT_SETUP([DEFINE command - all on one line])
689 AT_DATA([input], [dnl
690 define !macro1()var1 var2 var3!enddefine.
692 AT_DATA([expout-base], [dnl
697 STRING "var1 var2 var3"
698 MACRO_ID "!enddefine"
702 PSPP_CHECK_SCAN([-i])
705 AT_SETUP([DEFINE command - empty])
707 AT_DATA([input], [dnl
711 AT_DATA([expout-base], [dnl
716 MACRO_ID "!enddefine"
720 PSPP_CHECK_SCAN([-i])
723 AT_SETUP([DEFINE command - blank lines])
725 AT_DATA([input], [dnl
731 AT_DATA([expout-base], [dnl
738 MACRO_ID "!enddefine"
742 PSPP_CHECK_SCAN([-i])
745 AT_SETUP([DEFINE command - arguments])
747 AT_DATA([input], [dnl
748 define !macro1(a(), b(), c())
751 AT_DATA([expout-base], [dnl
767 MACRO_ID "!enddefine"
771 PSPP_CHECK_SCAN([-i])
774 AT_SETUP([DEFINE command - multiline arguments])
776 AT_DATA([input], [dnl
784 AT_DATA([expout-base], [dnl
800 MACRO_ID "!enddefine"
804 PSPP_CHECK_SCAN([-i])
807 AT_SETUP([DEFINE command - arguments start on second line])
809 AT_DATA([input], [dnl
817 AT_DATA([expout-base], [dnl
829 MACRO_ID "!enddefine"
833 PSPP_CHECK_SCAN([-i])
836 AT_SETUP([DEFINE command - early end of command 1])
838 AT_DATA([input], [dnl
842 AT_DATA([expout-base], [dnl
854 PSPP_CHECK_SCAN([-i])
857 AT_SETUP([DEFINE command - early end of command 2])
859 AT_DATA([input], [dnl
864 AT_DATA([expout-base], [dnl
877 PSPP_CHECK_SCAN([-i])
880 AT_SETUP([DEFINE command - early end of command 3])
882 AT_DATA([input], [dnl
887 AT_DATA([expout-base], [dnl
902 PSPP_CHECK_SCAN([-i])
905 AT_SETUP([DEFINE command - early end of command 4])
906 AT_KEYWORDS([segment])
907 AT_DATA([input], [dnl
908 dnl Notice the command terminator at the end of the DEFINE command,
909 dnl which should not be there and ends it early.
913 AT_DATA([expout-base], [dnl
925 PSPP_CHECK_SCAN([-i])
928 AT_SETUP([DEFINE command - missing !ENDDEFINE])
930 AT_DATA([input], [dnl
935 AT_DATA([expout-base], [dnl
940 STRING "content line 1"
941 STRING "content line 2"
944 PSPP_CHECK_SCAN([-i])
947 AT_SETUP([batch mode])
949 AT_DATA([input], [dnl
951 another line of first command
958 AT_DATA([expout-base], [dnl
981 PSPP_CHECK_SCAN([-b])