1dnl PSPP - a program for statistical analysis. 2dnl Copyright (C) 2017 Free Software Foundation, Inc. 3dnl 4dnl This program is free software: you can redistribute it and/or modify 5dnl it under the terms of the GNU General Public License as published by 6dnl the Free Software Foundation, either version 3 of the License, or 7dnl (at your option) any later version. 8dnl 9dnl This program is distributed in the hope that it will be useful, 10dnl but WITHOUT ANY WARRANTY; without even the implied warranty of 11dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12dnl GNU General Public License for more details. 13dnl 14dnl You should have received a copy of the GNU General Public License 15dnl along with this program. If not, see <http://www.gnu.org/licenses/>. 16dnl 17AT_BANNER([syntax scanning]) 18m4_define([PSPP_CHECK_SCAN], 19 [sed 's/^-//' < expout-base > expout 20 AT_CHECK([scan-test $1 input], [0], [expout]) 21 22 sed '/^-/d' < expout-base > expout 23 AT_CHECK([scan-test -s $1 input], [0], [expout])]) 24 25AT_SETUP([identifiers]) 26AT_KEYWORDS([scan]) 27AT_DATA([input], [dnl 28a aB i5 $x @efg @@. #.# .x _z. 29abcd. abcd. 30QRSTUV./* end of line comment */ 31QrStUv./* end of line comment */ @&t@ 32WXYZ. /* unterminated end of line comment 33�. /* U+FFFD is not valid in an identifier 34]) 35AT_DATA([expout-base], [dnl 36ID "a" 37SKIP 38ID "aB" 39SKIP 40ID "i5" 41SKIP 42ID "$x" 43SKIP 44ID "@efg" 45SKIP 46ID "@@." 47SKIP 48ID "#.#" 49SKIP 50UNEXPECTED_DOT 51ID "x" 52SKIP 53UNEXPECTED_CHAR 95 54ID "z" 55ENDCMD 56SKIP 57ID "abcd." 58SKIP 59ID "abcd" 60ENDCMD 61SKIP 62ID "QRSTUV" 63ENDCMD 64SKIP 65SKIP 66ID "QrStUv" 67ENDCMD 68SKIP 69SKIP 70SKIP 71ID "WXYZ" 72ENDCMD 73SKIP 74SKIP 75SKIP 76UNEXPECTED_CHAR 65533 77ENDCMD 78SKIP 79SKIP 80-SKIP 81STOP 82]) 83PSPP_CHECK_SCAN([-i]) 84AT_CLEANUP 85 86AT_SETUP([reserved words]) 87AT_KEYWORDS([scan]) 88AT_DATA([input], [dnl 89and or not eq ge gt le lt ne all by to with 90AND OR NOT EQ GE GT LE LT NE ALL BY TO WITH 91andx orx notx eqx gex gtx lex ltx nex allx byx tox withx 92and. with. 93]) 94AT_DATA([expout-base], [dnl 95AND 96SKIP 97OR 98SKIP 99NOT 100SKIP 101EQ 102SKIP 103GE 104SKIP 105GT 106SKIP 107LE 108SKIP 109LT 110SKIP 111NE 112SKIP 113ALL 114SKIP 115BY 116SKIP 117TO 118SKIP 119WITH 120SKIP 121AND 122SKIP 123OR 124SKIP 125NOT 126SKIP 127EQ 128SKIP 129GE 130SKIP 131GT 132SKIP 133LE 134SKIP 135LT 136SKIP 137NE 138SKIP 139ALL 140SKIP 141BY 142SKIP 143TO 144SKIP 145WITH 146SKIP 147ID "andx" 148SKIP 149ID "orx" 150SKIP 151ID "notx" 152SKIP 153ID "eqx" 154SKIP 155ID "gex" 156SKIP 157ID "gtx" 158SKIP 159ID "lex" 160SKIP 161ID "ltx" 162SKIP 163ID "nex" 164SKIP 165ID "allx" 166SKIP 167ID "byx" 168SKIP 169ID "tox" 170SKIP 171ID "withx" 172SKIP 173ID "and." 174SKIP 175WITH 176ENDCMD 177-SKIP 178STOP 179]) 180PSPP_CHECK_SCAN([-i]) 181AT_CLEANUP 182 183AT_SETUP([punctuation]) 184AT_KEYWORDS([scan]) 185AT_DATA([input], [dnl 186~ & | = >= > <= < ~= <> ( ) , - + * / [[ ]] ** 187~&|=>=><=<~=<>(),-+*/[[]]** 188]) 189AT_DATA([expout-base], [dnl 190NOT 191SKIP 192AND 193SKIP 194OR 195SKIP 196EQUALS 197SKIP 198GE 199SKIP 200GT 201SKIP 202LE 203SKIP 204LT 205SKIP 206NE 207SKIP 208NE 209SKIP 210LPAREN 211SKIP 212RPAREN 213SKIP 214COMMA 215SKIP 216DASH 217SKIP 218PLUS 219SKIP 220ASTERISK 221SKIP 222SLASH 223SKIP 224LBRACK 225SKIP 226RBRACK 227SKIP 228EXP 229SKIP 230NOT 231AND 232OR 233EQUALS 234GE 235GT 236LE 237LT 238NE 239NE 240LPAREN 241RPAREN 242COMMA 243DASH 244PLUS 245ASTERISK 246SLASH 247LBRACK 248RBRACK 249EXP 250-SKIP 251STOP 252]) 253PSPP_CHECK_SCAN([-i]) 254AT_CLEANUP 255 256AT_SETUP([numbers]) 257AT_KEYWORDS([scan]) 258AT_DATA([input], [dnl 2590 1 01 001. 1. 260123. /* comment 1 */ /* comment 2 */ 261.1 0.1 00.1 00.10 2625e1 6E-1 7e+1 6E+01 6e-03 263.3E1 .4e-1 .5E+1 .6e+01 .7E-03 2641.23e1 45.6E-1 78.9e+1 99.9E+01 11.2e-03 265. 1e e1 1e+ 1e- 266]) 267AT_DATA([expout-base], [dnl 268POS_NUM 269SKIP 270POS_NUM 1 271SKIP 272POS_NUM 1 273SKIP 274POS_NUM 1 275SKIP 276POS_NUM 1 277ENDCMD 278SKIP 279POS_NUM 123 280ENDCMD 281SKIP 282SKIP 283SKIP 284SKIP 285SKIP 286ENDCMD 287POS_NUM 1 288SKIP 289POS_NUM 0.1 290SKIP 291POS_NUM 0.1 292SKIP 293POS_NUM 0.1 294SKIP 295POS_NUM 50 296SKIP 297POS_NUM 0.6 298SKIP 299POS_NUM 70 300SKIP 301POS_NUM 60 302SKIP 303POS_NUM 0.006 304SKIP 305ENDCMD 306POS_NUM 30 307SKIP 308POS_NUM 0.04 309SKIP 310POS_NUM 5 311SKIP 312POS_NUM 6 313SKIP 314POS_NUM 0.0007 315SKIP 316POS_NUM 12.3 317SKIP 318POS_NUM 4.56 319SKIP 320POS_NUM 789 321SKIP 322POS_NUM 999 323SKIP 324POS_NUM 0.0112 325SKIP 326ENDCMD 327SKIP 328EXPECTED_EXPONENT "1e" 329SKIP 330ID "e1" 331SKIP 332EXPECTED_EXPONENT "1e+" 333SKIP 334EXPECTED_EXPONENT "1e-" 335-SKIP 336STOP 337]) 338PSPP_CHECK_SCAN([-i]) 339AT_CLEANUP 340 341AT_SETUP([strings]) 342AT_KEYWORDS([scan]) 343AT_DATA([input], [dnl 344'x' "y" 'abc' 345'Don''t' "Can't" 'Won''t' 346"""quoted""" '"quoted"' 347'' "" '''' """" 348'missing end quote 349"missing double quote 350'x' + "y" 351+ 'z' + 352'a' /* abc */ + "b" /* 353+ 'c' +/* */"d"/* */+'e' 354'foo' 355+ /* special case: + in column 0 would ordinarily start a new command 356'bar' 357'foo' 358 + 359'bar' 360'foo' 361+ 362 363'bar' 364 365+ 366x"4142"+'5152' 367"4142"+ 368x'5152' 369x"4142" 370+u'304a' 371"�あいうえお" 372"abc"+U"FFFD"+u'3048'+"xyz" 373]) 374AT_DATA([expout-base], [dnl 375STRING "x" 376SKIP 377STRING "y" 378SKIP 379STRING "abc" 380SKIP 381STRING "Don't" 382SKIP 383STRING "Can't" 384SKIP 385STRING "Won't" 386SKIP 387STRING ""quoted"" 388SKIP 389STRING ""quoted"" 390SKIP 391STRING "" 392SKIP 393STRING "" 394SKIP 395STRING "'" 396SKIP 397STRING """ 398SKIP 399EXPECTED_QUOTE 400SKIP 401EXPECTED_QUOTE 402SKIP 403STRING "xyzabcde" 404SKIP 405STRING "foobar" 406SKIP 407STRING "foobar" 408SKIP 409STRING "foo" 410SKIP 411PLUS 412SKIP 413ENDCMD 414SKIP 415STRING "bar" 416SKIP 417ENDCMD 418SKIP 419PLUS 420SKIP 421STRING "AB5152" 422SKIP 423STRING "4142QR" 424SKIP 425STRING "ABお" 426SKIP 427STRING "�あいうえお" 428SKIP 429STRING "abc�えxyz" 430-SKIP 431STOP 432]) 433PSPP_CHECK_SCAN([-i]) 434AT_CLEANUP 435 436AT_SETUP([@%:@! construct]) 437AT_KEYWORDS([scan]) 438AT_DATA([input], [dnl 439#! /usr/bin/pspp 440#! /usr/bin/pspp 441]) 442AT_DATA([expout-base], [dnl 443SKIP 444SKIP 445ID "#" 446UNEXPECTED_CHAR 33 447SKIP 448SLASH 449ID "usr" 450SLASH 451ID "bin" 452SLASH 453ID "pspp" 454-SKIP 455STOP 456]) 457PSPP_CHECK_SCAN([-i]) 458AT_CLEANUP 459 460AT_SETUP([* and COMMENT commands]) 461AT_KEYWORDS([scan]) 462AT_DATA([input], [dnl 463* Comment commands "don't 464have to contain valid tokens. 465 466** Check ambiguity with ** token. 467****************. 468 469comment keyword works too. 470COMM also. 471com is ambiguous with COMPUTE. 472 473 * Comment need not start at left margin. 474 475* Comment ends with blank line 476 477next command. 478 479]) 480AT_DATA([expout-base], [dnl 481SKIP 482SKIP 483SKIP 484ENDCMD 485SKIP 486ENDCMD 487SKIP 488SKIP 489ENDCMD 490SKIP 491SKIP 492ENDCMD 493SKIP 494ENDCMD 495SKIP 496SKIP 497ENDCMD 498SKIP 499SKIP 500ENDCMD 501SKIP 502ID "com" 503SKIP 504ID "is" 505SKIP 506ID "ambiguous" 507SKIP 508WITH 509SKIP 510ID "COMPUTE" 511ENDCMD 512SKIP 513ENDCMD 514SKIP 515SKIP 516SKIP 517ENDCMD 518SKIP 519ENDCMD 520SKIP 521SKIP 522SKIP 523ENDCMD 524SKIP 525ID "next" 526SKIP 527ID "command" 528ENDCMD 529SKIP 530-ENDCMD 531-SKIP 532STOP 533]) 534PSPP_CHECK_SCAN([-i]) 535AT_CLEANUP 536 537AT_SETUP([DOCUMENT command]) 538AT_KEYWORDS([scan]) 539AT_DATA([input], [dnl 540DOCUMENT one line. 541DOC more 542 than 543 one 544 line. 545docu 546first.paragraph 547isn't parsed as tokens 548 549second paragraph. 550]) 551AT_DATA([expout-base], [dnl 552ID "DOCUMENT" 553STRING "DOCUMENT one line." 554ENDCMD 555ENDCMD 556SKIP 557ID "DOCUMENT" 558STRING "DOC more" 559SKIP 560STRING " than" 561SKIP 562STRING " one" 563SKIP 564STRING " line." 565ENDCMD 566ENDCMD 567SKIP 568ID "DOCUMENT" 569STRING "docu" 570SKIP 571STRING "first.paragraph" 572SKIP 573STRING "isn't parsed as tokens" 574SKIP 575STRING "" 576SKIP 577STRING "second paragraph." 578-ENDCMD 579-ENDCMD 580-SKIP 581STOP 582]) 583PSPP_CHECK_SCAN([-i]) 584AT_CLEANUP 585 586AT_SETUP([TITLE, SUBTITLE, FILE LABEL commands]) 587AT_KEYWORDS([scan]) 588AT_DATA([input], [dnl 589title/**/'Quoted string title'. 590tit /* 591"Quoted string on second line". 592sub "Quoted string subtitle" 593 . 594 595TITL /* Not a */ quoted string title. 596SUBT Not a quoted string /* subtitle 597 598FIL label isn't quoted. 599FILE 600 lab 'is quoted'. 601FILE /* 602/**/ lab not quoted here either 603 604]) 605AT_DATA([expout-base], [dnl 606ID "title" 607SKIP 608STRING "Quoted string title" 609ENDCMD 610SKIP 611ID "tit" 612SKIP 613SKIP 614SKIP 615STRING "Quoted string on second line" 616ENDCMD 617SKIP 618ID "sub" 619SKIP 620STRING "Quoted string subtitle" 621SKIP 622SKIP 623ENDCMD 624SKIP 625ENDCMD 626SKIP 627ID "TITL" 628SKIP 629STRING "/* Not a */ quoted string title" 630ENDCMD 631SKIP 632ID "SUBT" 633SKIP 634STRING "Not a quoted string /* subtitle" 635SKIP 636ENDCMD 637SKIP 638ID "FIL" 639SKIP 640ID "label" 641SKIP 642STRING "isn't quoted" 643ENDCMD 644SKIP 645ID "FILE" 646SKIP 647SKIP 648ID "lab" 649SKIP 650STRING "is quoted" 651ENDCMD 652SKIP 653ID "FILE" 654SKIP 655SKIP 656SKIP 657SKIP 658SKIP 659ID "lab" 660SKIP 661STRING "not quoted here either" 662SKIP 663-ENDCMD 664-SKIP 665STOP 666]) 667PSPP_CHECK_SCAN([-i]) 668AT_CLEANUP 669 670AT_SETUP([BEGIN DATA command]) 671AT_KEYWORDS([scan]) 672AT_DATA([input], [dnl 673begin data. 674123 675xxx 676end data. 677 678BEG /**/ DAT /* 6795 6 7 /* x 680 681end data 682end data 683. 684]) 685AT_DATA([expout-base], [dnl 686ID "begin" 687SKIP 688ID "data" 689ENDCMD 690SKIP 691STRING "123" 692SKIP 693STRING "xxx" 694SKIP 695ID "end" 696SKIP 697ID "data" 698ENDCMD 699SKIP 700ENDCMD 701SKIP 702ID "BEG" 703SKIP 704SKIP 705SKIP 706ID "DAT" 707SKIP 708SKIP 709SKIP 710STRING "5 6 7 /* x" 711SKIP 712STRING "" 713SKIP 714STRING "end data" 715SKIP 716ID "end" 717SKIP 718ID "data" 719SKIP 720ENDCMD 721-SKIP 722STOP 723]) 724PSPP_CHECK_SCAN([-i]) 725AT_CLEANUP 726 727AT_SETUP([DO REPEAT command]) 728AT_KEYWORDS([scan]) 729AT_DATA([input], [dnl 730do repeat x=a b c 731 y=d e f. 732 do repeat a=1 thru 5. 733another command. 734second command 735+ third command. 736end /* x */ /* y */ repeat print. 737end 738 repeat. 739]) 740AT_DATA([expout-base], [dnl 741ID "do" 742SKIP 743ID "repeat" 744SKIP 745ID "x" 746EQUALS 747ID "a" 748SKIP 749ID "b" 750SKIP 751ID "c" 752SKIP 753SKIP 754ID "y" 755EQUALS 756ID "d" 757SKIP 758ID "e" 759SKIP 760ID "f" 761ENDCMD 762SKIP 763STRING " do repeat a=1 thru 5." 764SKIP 765STRING "another command." 766SKIP 767STRING "second command" 768SKIP 769STRING "+ third command." 770SKIP 771STRING "end /* x */ /* y */ repeat print." 772SKIP 773ID "end" 774SKIP 775SKIP 776ID "repeat" 777ENDCMD 778-SKIP 779STOP 780]) 781PSPP_CHECK_SCAN([-i]) 782AT_CLEANUP 783 784AT_SETUP([batch mode]) 785AT_KEYWORDS([scan]) 786AT_DATA([input], [dnl 787first command 788 another line of first command 789+ second command 790third command 791 792fourth command. 793 fifth command. 794]) 795AT_DATA([expout-base], [dnl 796ID "first" 797SKIP 798ID "command" 799SKIP 800SKIP 801ID "another" 802SKIP 803ID "line" 804SKIP 805ID "of" 806SKIP 807ID "first" 808SKIP 809ID "command" 810SKIP 811ENDCMD 812SKIP 813ID "second" 814SKIP 815ID "command" 816SKIP 817ENDCMD 818ID "third" 819SKIP 820ID "command" 821SKIP 822ENDCMD 823SKIP 824ID "fourth" 825SKIP 826ID "command" 827ENDCMD 828SKIP 829SKIP 830ID "fifth" 831SKIP 832ID "command" 833ENDCMD 834-SKIP 835STOP 836]) 837PSPP_CHECK_SCAN([-b]) 838AT_CLEANUP 839