home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume07 / occam.yac < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  38.4 KB

  1. From decwrl!henry.jpl.nasa.gov!elroy.jpl.nasa.gov!ames!lll-winken!uunet!allbery Sat Aug 12 15:58:51 PDT 1989
  2. Article 1026 of comp.sources.misc:
  3. Path: decwrl!henry.jpl.nasa.gov!elroy.jpl.nasa.gov!ames!lll-winken!uunet!allbery
  4. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5. Newsgroups: comp.sources.misc
  6. Subject: v07i125: OCCAM - yacc specification with lexer
  7. Keywords: occam yacc lex
  8. Message-ID: <63333@uunet.UU.NET>
  9. Date: 12 Aug 89 00:11:51 GMT
  10. Sender: allbery@uunet.UU.NET
  11. Reply-To: pjmp@hrc63.uucp (Peter Polkinghorne)
  12. Organization: GEC Hirst Research Centre, Wembley, England. (uk.co.gec-rl-hrc)
  13. Lines: 2033
  14. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  15.  
  16. Posting-number: Volume 7, Issue 125
  17. Submitted-by: pjmp@hrc63.uucp (Peter Polkinghorne)
  18. Archive-name: occam.yacc
  19.  
  20. [Which leaves me only one question:  what is OCCAM?  It looks like some kind of
  21. realtime control language (for MIDI?).  ++bsa]
  22.  
  23. Here is a simple OCCAM yacc specification with lexer. OCCAM & OCCAM2 are
  24. handled. Hope this is the right newsgroup. [It is.  ++bsa]  It is not perfect!
  25.  
  26. ---- Cut Here and unpack ----
  27. #!/bin/sh
  28. # shar:    Shell Archiver  (v1.22)
  29. #
  30. #    Run the following text with /bin/sh to create:
  31. #      README
  32. #      Makefile
  33. #      occam.y
  34. #      occamlex.c
  35. #      occam2.y
  36. #      occam2lex.c
  37. #      test1
  38. #      test2
  39. #      test3
  40. #      test4
  41. #
  42. if test -f README; then echo "File README exists"; else
  43. echo "x - extracting README (Text)"
  44. sed 's/^X//' << 'SHAR_EOF' > README &&
  45. X
  46. XThese are two Occam recognisers, defined with yacc & handcrafted lexers.
  47. XThe Occam recogniser was developed as a lex & yacc learning exercise.
  48. XThe one for Occam is unambiguous. The one for Occam2 is ambiguous and requires
  49. Xwork to tidy up the syntax. This is mainly because the Occam2 definition is a
  50. Xrather unsuited for yacc, as defined by the Occam2 Language definition by David
  51. XMay.
  52. X
  53. XThe most original part of this is the lex routines which deal with Occam's
  54. Xindentation features. These recognisers are offered because periodically
  55. XI see people on the net asking for an Occam lex & yacc definition.
  56. X
  57. XTo build a compiler from this requires a LOT more work. I hope someone
  58. Xfinds this useful, however I do not intend to maintain it. Hence I am
  59. Xplacing this in the public domain.
  60. X
  61. XFiles supplied:
  62. X
  63. XREADME        - this file!
  64. XMakefile    - simple UNIX makefile
  65. X
  66. Xoccam.y        - Occam yacc specification
  67. Xoccamlex.c    - Occam lexer
  68. X
  69. Xoccam2.y    - Occam2 yacc specification
  70. Xoccam2lex.c    - Occam2 lexer
  71. X
  72. Xtest1        )
  73. Xtest2        )- set of Occam test files for occam.
  74. Xtest3        )
  75. Xtest4        )
  76. X
  77. XHave fun!
  78. X
  79. XPeter Polkinghorne ( pjmp@uk.co.gec-rl-hrc or ...!mcvax!ukc!hrc63!pjmp )
  80. XGEC Hirst Research Centre, East Lane, Wembley, Middlesex, UK
  81. X
  82. SHAR_EOF
  83. chmod 0666 README || echo "restore of README fails"
  84. set `wc -c README`;Sum=$1
  85. if test "$Sum" != "1197"
  86. then echo original size 1197, current size $Sum;fi
  87. fi
  88. if test -f Makefile; then echo "File Makefile exists"; else
  89. echo "x - extracting Makefile (Text)"
  90. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  91. X#
  92. X#    Makefile for occam recogniser - pjmp @ hrc 22/7/86
  93. X#
  94. X
  95. X#
  96. X# This work is in the public domain.
  97. X# It was written by Peter Polkinghorne in 1986 & 1989 at
  98. X# GEC Hirst Research Centre, Wembley, England.
  99. X# No liability is accepted or warranty given by the Author,
  100. X# still less my employers.
  101. X#
  102. X
  103. X# sys V like flags
  104. X#CFLAGS=-g -O
  105. X#YFLAGS=-vdt
  106. X
  107. X# BSD like flags
  108. XCFLAGS=-O
  109. XYFLAGS=-dv
  110. X
  111. Xall:        occam occam2
  112. X
  113. Xoccam:        occam.o occamlex.o
  114. X        cc $(CFLAGS) occam.o occamlex.o -o occam
  115. X
  116. Xoccam.c:        occam.y
  117. X        yacc $(YFLAGS) occam.y
  118. X        mv y.tab.h lex.h
  119. X        mv y.tab.c occam.c
  120. X
  121. Xoccam2:        occam2.o occam2lex.o
  122. X        cc $(CFLAGS) occam2.o occam2lex.o -o occam2
  123. X
  124. Xoccam2.c:       occam2.y
  125. X        yacc $(YFLAGS) occam2.y
  126. X        mv y.tab.h lex2.h
  127. X        mv y.tab.c occam2.c
  128. X
  129. Xclean:
  130. X    rm -f *.o occam2.c occam.c lex2.h lex.h y.output
  131. X
  132. Xshar:        README Makefile occam.y occamlex.c occam2.y occam2lex.c test1 test2 test3 test4
  133. X        shar2 -v -s -x -c README Makefile occam.y occamlex.c occam2.y occam2lex.c test1 test2 test3 test4 > shar
  134. SHAR_EOF
  135. chmod 0666 Makefile || echo "restore of Makefile fails"
  136. set `wc -c Makefile`;Sum=$1
  137. if test "$Sum" != "981"
  138. then echo original size 981, current size $Sum;fi
  139. fi
  140. if test -f occam.y; then echo "File occam.y exists"; else
  141. echo "x - extracting occam.y (Text)"
  142. sed 's/^X//' << 'SHAR_EOF' > occam.y &&
  143. X/* 
  144. X *
  145. X *        OCCAM yacc specification
  146. X *
  147. X *        Peter Polkinghorne - GEC Research
  148. X *
  149. X */
  150. X
  151. X/*
  152. X * This work is in the public domain.
  153. X * It was written by Peter Polkinghorne in 1986 & 1989 at
  154. X * GEC Hirst Research Centre, Wembley, England.
  155. X * No liability is accepted or warranty given by the Author,
  156. X * still less my employers.
  157. X */
  158. X
  159. X/* revision history
  160. X    0.0    initial attempt                pjmp    22/7/86
  161. X    0.1    add in COMMA so that yylex can cope with
  162. X        comma differentiation for PROC decls    pjmp    4/8/86
  163. X    0.2    add in main - since BSD does not have -ly
  164. X                            pjmp    8/3/89
  165. X
  166. Xend revisions */
  167. X
  168. X%token        VAR    CHAN    ANY    WAIT    SKIP    ID    EOL
  169. X%token        VALUE    BYTE    DEF    PROC    NOT    NUMBER    BOOL
  170. X%token        NOW    TABLE    BOOLOP    SHIFTOP    COMPOP    CHCON    STR
  171. X%token        LOGOP    SEQ    ALT    IF    PAR    WHILE    FOR
  172. X%token        BEG    END    COMMA
  173. X
  174. X%start        program
  175. X
  176. X%%
  177. X
  178. Xprogram        :    sep process
  179. X        |    process
  180. X        ;
  181. X
  182. Xprocess        :    primitive sep
  183. X        |    ID sep
  184. X        |    ID '(' explist ')' sep
  185. X        |    construct
  186. X        |    declaration ':' sep process
  187. X        |    error sep
  188. X            {
  189. X                yyerrok;
  190. X            }
  191. X        ;
  192. X
  193. Xprimitive    :    assignment
  194. X        |    input
  195. X        |    output
  196. X        |    wait
  197. X        |    skip
  198. X        ;
  199. X
  200. X
  201. Xconstruct    :    SEQ sep BEG proclist END
  202. X        |    SEQ replic sep BEG process END
  203. X        |    SEQ sep
  204. X        |    PAR sep BEG proclist END
  205. X        |    PAR replic sep BEG process END
  206. X        |    PAR sep
  207. X        |    IF sep BEG condlist END
  208. X        |    IF replic sep BEG cond END
  209. X        |    IF sep
  210. X        |    ALT sep BEG guardplist END
  211. X        |    ALT replic sep BEG guardp END
  212. X        |    ALT sep
  213. X        |    WHILE expr sep BEG process END
  214. X        ;
  215. X
  216. Xsep        :    EOL
  217. X        |    sep EOL
  218. X        ;
  219. X
  220. Xproclist    :    process
  221. X        |    proclist process
  222. X        ;
  223. X
  224. Xcondlist    :    cond
  225. X        |    condlist cond
  226. X        ;
  227. X
  228. Xguardplist    :    guardp
  229. X        |    guardplist guardp
  230. X        ;
  231. X
  232. X
  233. Xreplic        :    ID '=' '[' expr FOR expr ']'
  234. X        ;
  235. X
  236. Xcond        :    expr sep BEG process END
  237. X        |    IF sep
  238. X        |    IF sep BEG condlist END
  239. X        |    IF replic sep BEG cond END
  240. X        ;
  241. X
  242. Xguardp        :    guard sep BEG process END
  243. X        |    ALT sep
  244. X        |    ALT sep BEG guardplist END
  245. X        |    ALT replic sep BEG guardp END
  246. X        ;
  247. X
  248. Xguard        :    expr '&' input
  249. X        |    input
  250. X        |    expr '&' wait
  251. X        |    wait
  252. X        |    expr '&' SKIP
  253. X        |    SKIP
  254. X        ;
  255. X
  256. Xdeclaration    :    VAR varlist
  257. X        |    CHAN chanlist
  258. X        |    DEF deflist
  259. X        |    PROC ID '=' sep BEG process END 
  260. X        |    PROC ID formparms '=' sep BEG process END
  261. X        ;
  262. X
  263. Xassignment    :    var ':' '=' expr
  264. X        ;
  265. X
  266. Xinput        :    chan '?' inlist
  267. X        |    chan '?' ANY
  268. X        ;
  269. X
  270. Xoutput        :    chan '!' outlist
  271. X        |    chan '!' ANY
  272. X        ;
  273. X
  274. Xwait        :    WAIT expr
  275. X        ;
  276. X
  277. Xskip        :    SKIP
  278. X        ;
  279. X
  280. Xinlist        :    var
  281. X        |    inlist ';' var
  282. X        ;
  283. X
  284. Xoutlist        :    expr
  285. X        |    outlist ';' expr
  286. X        ;
  287. X
  288. Xexplist        :    expr
  289. X        |    explist ',' expr
  290. X        ;
  291. X
  292. Xvarlist        :    var
  293. X        |    varlist ',' var
  294. X        ;
  295. X
  296. Xchanlist    :    chan
  297. X        |    chanlist ',' chan
  298. X        ;
  299. X
  300. Xdeflist        :    def
  301. X        |    deflist ',' def
  302. X        ;
  303. X
  304. Xformparms    :    '(' fparmlist ')'
  305. X        ;
  306. X
  307. Xfparmlist    :    fparm
  308. X        |    fparmlist COMMA fparm
  309. X        ;
  310. X
  311. Xvar        :    ID
  312. X        |    ID subscript
  313. X        ;
  314. X
  315. Xchan        :    ID
  316. X        |    ID '[' expr ']'
  317. X        ;
  318. X
  319. Xdef        :    ID '=' expr
  320. X        |    ID '=' veccon
  321. X        ;
  322. X
  323. Xsubscript    :    '[' expr ']'
  324. X        |    '[' BYTE expr ']'
  325. X        ;
  326. X
  327. X
  328. Xfparm        :    VAR plist
  329. X        |    CHAN plist
  330. X        |    VALUE plist
  331. X        ;
  332. X
  333. Xplist        :    parm
  334. X        |    plist ',' parm
  335. X        ;
  336. X
  337. Xparm        :    ID
  338. X        |    ID '[' ']'
  339. X        ;
  340. X
  341. Xexpr        :    monop element
  342. X        |    element op element
  343. X        |    ellist
  344. X        ;
  345. X
  346. Xellist        :    element
  347. X        |    ellist assop element
  348. X        ;
  349. X
  350. Xmonop        :    '-'
  351. X        |    NOT
  352. X        ;
  353. X
  354. Xelement        :    NUMBER
  355. X        |    BOOL
  356. X        |    NOW
  357. X        |    CHCON
  358. X        |    '(' expr ')'
  359. X        |    item
  360. X        ;
  361. X
  362. Xop        :    arop
  363. X        |    COMPOP
  364. X        |    '='
  365. X        |    SHIFTOP
  366. X        ;
  367. X
  368. Xassop        :    '+'
  369. X        |    '*'
  370. X        |    LOGOP
  371. X        |    BOOLOP
  372. X        ;
  373. X
  374. Xarop        :    '-'
  375. X        |    '/'
  376. X        |    '\\'
  377. X        ;
  378. X
  379. Xitem        :    ID
  380. X        |    ID subscript
  381. X        |    veccon subscript
  382. X        ;
  383. X
  384. Xveccon        :    str
  385. X        |    TABLE '[' BYTE tlist ']'
  386. X        |    TABLE '[' tlist ']'
  387. X        ;
  388. X
  389. X
  390. Xstr        :    STR
  391. X        |    str sep STR
  392. X        ;
  393. X
  394. Xtlist        :    expr
  395. X        |    tlist ',' expr
  396. X        ;
  397. X
  398. X%%
  399. X
  400. X#include <stdio.h>
  401. X
  402. Xvoid main()
  403. X{
  404. X
  405. X    exit( yyparse() );
  406. X
  407. X}/*main*/
  408. X
  409. Xyyerror( str )
  410. Xchar     *str;
  411. X/* our slightly more informative error routine */
  412. X{
  413. X
  414. Xextern int    yylineno;
  415. Xextern char    yytext[];
  416. X
  417. X    fprintf( stderr, "ERROR <%s> near <%s> on line %d\n",
  418. X            str, yytext, yylineno );
  419. X
  420. X}/*yyerror*/
  421. X
  422. X/*end occam.y*/
  423. SHAR_EOF
  424. chmod 0666 occam.y || echo "restore of occam.y fails"
  425. set `wc -c occam.y`;Sum=$1
  426. if test "$Sum" != "3693"
  427. then echo original size 3693, current size $Sum;fi
  428. fi
  429. if test -f occamlex.c; then echo "File occamlex.c exists"; else
  430. echo "x - extracting occamlex.c (Text)"
  431. sed 's/^X//' << 'SHAR_EOF' > occamlex.c &&
  432. X/*
  433. X *    OCCAM lexical analysis routine
  434. X *
  435. X *    pjmp    HRC    31/7/86
  436. X *
  437. X */
  438. X
  439. X/*
  440. X * This work is in the public domain.
  441. X * It was written by Peter Polkinghorne in 1986 & 1989 at
  442. X * GEC Hirst Research Centre, Wembley, England.
  443. X * No liability is accepted or warranty given by the Author,
  444. X * still less my employers.
  445. X */
  446. X
  447. X/* revision history
  448. X
  449. X    0.0    first release                    pjmp    31/7/86
  450. X    0.1    make yylex more rational - common exit        pjmp    1/8/86
  451. X    0.2    add in comma differentiation - for proc decl    pjmp    4/8/86
  452. X
  453. Xend revisions */
  454. X
  455. X#include <stdio.h>
  456. X#include <ctype.h>
  457. X#include "lex.h"
  458. X
  459. X#define    MAXLINE    256
  460. X
  461. X#define    TRUE    1
  462. X#define    FALSE    0
  463. X
  464. X/************************************************************************/
  465. X/* reserved word list - ordered for binary chomp */
  466. X
  467. Xstatic struct reserv { char * word; int tok, len; } rlist[] = {
  468. X        "AFTER",    COMPOP,    5,
  469. X        "ALT",        ALT,    3,
  470. X        "AND",        BOOLOP,    3,
  471. X        "ANY",        ANY,    3,
  472. X        "BYTE",        BYTE,    4,
  473. X        "CHAN",        CHAN,    4,
  474. X        "DEF",        DEF,    3,
  475. X        "FALSE",    BOOL,    5,
  476. X        "FOR",        FOR,    3,
  477. X        "IF",        IF,    2,
  478. X        "NOT",        NOT,    3,
  479. X        "NOW",        NOW,    3,
  480. X        "OR",        BOOLOP,    2,
  481. X        "PAR",        PAR,    3,
  482. X        "PROC",        PROC,    4,
  483. X        "SEQ",        SEQ,    3,
  484. X        "SKIP",        SKIP,    4,
  485. X        "TABLE",    TABLE,    5,
  486. X        "TRUE",        BOOL,    5,
  487. X        "VALUE",    VALUE,    5,
  488. X        "VAR",        VAR,    3,
  489. X        "WAIT",        WAIT,    4,
  490. X        "WHILE",    WHILE,    5,
  491. X        0,        0,    0
  492. X
  493. X    };
  494. X
  495. X/************************************************************************/
  496. X
  497. Xstatic    char    line[MAXLINE];    /* where we store the input, line as a time */
  498. X
  499. Xchar    yytext[MAXLINE];    /* where we store text associated with token */
  500. X
  501. Xint    yylineno=1,        /* line number of input */
  502. X    yylen;            /* amount of text stored */
  503. X
  504. Xstatic    int    llen,        /* how much in line */
  505. X        curind,        /* current indentation */
  506. X        indent=0;    /* this lines indent */
  507. X        ldebug = TRUE,    /* set to TRUE for debug */
  508. X        index;        /* where we are in the line */
  509. X
  510. X/* state we are in: either start - get new input, decide what next
  511. X            ind - processing indentation
  512. X            rest - processing some occam stmt
  513. X            eof - tidy up processing
  514. X*/
  515. X
  516. Xstatic    enum    lexstate { Start, Ind, Rest, Eof } state = Start;
  517. X
  518. X/************************************************************************/
  519. X
  520. Xyylex()
  521. X/* this function returns the next token (defined by lex.h), a character
  522. Xvalue or 0 for end of input. The tokens are defined by standard input
  523. X*/
  524. X{
  525. X    int    tok = -1,    /* token to return - init to impossible value */
  526. X        sind = index;    /* start of input being processed */
  527. X
  528. X/* go round and round until token to return */
  529. X    while ( tok < 0  ) {
  530. X
  531. X/* decide by state */
  532. X    switch (state) {
  533. X
  534. X        case Start: {
  535. X/*grab some more line */
  536. X            if ( fgets( line, MAXLINE-1, stdin ) == NULL ) {
  537. X                state = Eof;
  538. X                break;
  539. X
  540. X            } else if ( (llen=strlen(line)) >= MAXLINE-1 ) {
  541. X                fprintf( stderr,
  542. X                    "line <%s> longer than %d\n",
  543. X                    line, MAXLINE-1 );
  544. X                exit( 1 );
  545. X            }/*if*/
  546. X
  547. X            index = 0;
  548. X            sind = 0;
  549. X            indent = 0;
  550. X
  551. X
  552. X/* if blank line OR has just comment skip, otherwise got to appropriate state */
  553. X
  554. X            if ( m_nulline() ) {
  555. X                /* do nowt */
  556. X
  557. X            } else if ( line[0]==' ' && line[1]==' ' ) {
  558. X                state = Ind;
  559. X
  560. X            } else {
  561. X                state = Rest;
  562. X
  563. X            }/*if*/
  564. X
  565. X        break;}/*Start*/
  566. X
  567. X        case Ind: {
  568. X/* work out indentation */
  569. X            if ( line[index]==' ' && line[index+1]==' ' ) {
  570. X                indent++;
  571. X                index+=2;
  572. X                sind+=2;
  573. X            } else {
  574. X                state = Rest;
  575. X            
  576. X            }/*if*/
  577. X    
  578. X        break;}/*Ind*/
  579. X
  580. X        case Rest: {
  581. X/* do we have some indentation to adjust for ... */
  582. X            if ( curind > indent ) {
  583. X                curind--;
  584. X                tok = END;
  585. X                break;
  586. X
  587. X            } else if ( curind < indent ) {
  588. X                curind++;
  589. X                tok = BEG;
  590. X                break;
  591. X
  592. X            }/*if*/
  593. X
  594. X/* process ch as appropriate */
  595. X            switch ( line[index] ) {
  596. X
  597. X/* space ignored */
  598. X                case ' ': {
  599. X                    sind++;
  600. X                    index++;
  601. X                break;}
  602. X
  603. X/* eol change state again */
  604. X                case '\n': {
  605. X                    yylineno++;
  606. X                    index++;
  607. X                    state = Start;
  608. X                    tok = EOL;
  609. X                break;}
  610. X
  611. X/* - a comment perhaps OR just itself */
  612. X                case '-': {
  613. X                    if ( line[index+1] == '-' ) {
  614. X                        index = llen+1;
  615. X                        state = Start;
  616. X                        tok = EOL;
  617. X
  618. X                    } else {
  619. X                        tok = line[index++];
  620. X
  621. X                    }/*if*/
  622. X                break;}
  623. X
  624. X                case '<': {
  625. X                    if ( line[index+1] == '<' ) {
  626. X                        index+=2;
  627. X                        tok = SHIFTOP;
  628. X
  629. X                    } else {
  630. X                        if ( line[index+1] == '=' ||
  631. X                            line[index+1] == '>' ) {
  632. X                            index++;
  633. X                        }/*if*/
  634. X                        index++;
  635. X                        tok = COMPOP;
  636. X                    }/*if*/
  637. X                break;}
  638. X
  639. X                case '>': {
  640. X                    if ( line[index+1] == '>' ) {
  641. X                        index+=2;
  642. X                        tok = SHIFTOP;
  643. X
  644. X                    } else if ( line[index+1] == '<' ) {
  645. X                        index+=2;
  646. X                        tok = LOGOP;
  647. X
  648. X                    } else {
  649. X                        if ( line[index+1] == '=' ) {
  650. X                            index++;
  651. X                        }/*if*/
  652. X                        index++;
  653. X                        tok = COMPOP;
  654. X                    }/*if*/
  655. X
  656. X                break;}
  657. X
  658. X                case '/': {
  659. X                    if ( line[index+1] == '\\' ) {
  660. X                        index+=2;
  661. X                        tok = LOGOP;
  662. X
  663. X                    } else {
  664. X                        tok = line[index++];
  665. X
  666. X                    }/*if*/
  667. X                break;}
  668. X
  669. X                case '\\': {
  670. X                    if ( line[index+1] == '/' ) {
  671. X                        index+=2;
  672. X                        tok = LOGOP;
  673. X
  674. X                    } else {
  675. X                        tok = line[index++];
  676. X
  677. X                    }/*if*/
  678. X                break;}
  679. X
  680. X                case '#': {
  681. X                    if ( isxdigit( line[index+1] ) ) {
  682. X/* gobble up hex digits */
  683. X                        index++;
  684. X                        while ( isxdigit(line[index]) ){
  685. X                            index++;
  686. X                        }/*while*/
  687. X
  688. X                        tok = NUMBER;
  689. X
  690. X                    } else {
  691. X                        tok = line[index++];
  692. X
  693. X                    }/*if*/
  694. X
  695. X                break;}
  696. X
  697. X                case '\'': {
  698. X                    if ( line[index+1] != '*'
  699. X                         && line[index+2] == '\'' ) {
  700. X
  701. X                        index+=3;
  702. X                        tok = CHCON;
  703. X
  704. X                    } else if ( line[index+1] == '*'
  705. X                         && line[index+2] != '#' 
  706. X                         && line[index+3] == '\'' ) {
  707. X
  708. X                        index+=4;
  709. X                        tok = CHCON;
  710. X
  711. X                    } else if ( line[index+1] == '*'
  712. X                         && line[index+2] == '#' 
  713. X                         && isxdigit( line[index+3] )
  714. X                         && isxdigit( line[index+4] )
  715. X                         && line[index+5] == '\'' ) {
  716. X
  717. X                        index+=6;
  718. X                        tok = CHCON;
  719. X
  720. X                    } else {
  721. X                        tok = line[index++];
  722. X
  723. X                    }/*if*/
  724. X
  725. X                break;}
  726. X
  727. X
  728. X                case '"': {
  729. X                    int    lindex=index+1;
  730. X
  731. X                    while ( line[lindex] != '"'
  732. X                         && lindex <= llen ) {
  733. X                        lindex++;
  734. X                    }/*while*/
  735. X
  736. X                    if ( line[lindex] == '"' ) {
  737. X                        index = lindex+1;
  738. X                        tok = STR;
  739. X
  740. X                    } else {
  741. X                        tok = line[index++];
  742. X
  743. X                    }/*if*/
  744. X
  745. X                break;}
  746. X
  747. X/* do extra look ahead that yacc can not do for CHAN | VAR | VALUE */
  748. X                case ',': {
  749. X                    int    lindex=index+1;
  750. X
  751. X                    while ( line[lindex] == ' ' ) {
  752. X                        lindex++;
  753. X                    }/*while*/
  754. X
  755. X                    if ( strncmp(&line[lindex], "CHAN", 4)
  756. X                         == 0
  757. X                       || strncmp(&line[lindex], "VAR", 3)
  758. X                         == 0
  759. X                       || strncmp(&line[lindex], "VALUE", 5)
  760. X                         == 0 ) {
  761. X
  762. X                        index++;
  763. X                        tok = COMMA;
  764. X
  765. X                    } else {
  766. X                        tok = line[index++];
  767. X
  768. X                    }/*if*/
  769. X
  770. X                break;}
  771. X
  772. X/* oh well pass back to yacc & let it cope  - if not digit or alpha */
  773. X                default: {
  774. X                    if ( isdigit( line[index] ) ) {
  775. X/* gobble up digits */
  776. X                        index++;
  777. X                        while ( isdigit(line[index]) ){
  778. X                            index++;
  779. X                        }/*while*/
  780. X
  781. X                        tok = NUMBER;
  782. X                        break;
  783. X
  784. X                    } else if ( isalpha( line[index] ) ) {
  785. X                        int    i, wlen = 1;
  786. X                        index++;
  787. X/* gobble up associated chs */
  788. X                        while ( isalpha( line[index] )
  789. X                            || isdigit( line[index])
  790. X                            || line[index] == '.' ){
  791. X                            wlen++;
  792. X                            index++;
  793. X                        }/*while*/
  794. X
  795. X/* now check against reserved word list */
  796. X                        for ( i=0;
  797. X                             rlist[i].word != NULL;
  798. X                            i++ ) {
  799. X
  800. X                            if ( rlist[i].len
  801. X                                != wlen ) {
  802. X                                continue;
  803. X                            }/*if*/
  804. X
  805. X                            if ( strncmp(
  806. X                              &line[index-wlen],
  807. X                              rlist[i].word,
  808. X                              wlen ) == 0 ) {
  809. X
  810. X                             tok = rlist[i].tok;
  811. X                             break;
  812. X                            }/*if*/
  813. X                        }/*for*/
  814. X
  815. X/* not a reserved word */
  816. X                        if ( tok < 0 ) {
  817. X                            tok = ID;
  818. X                        }/*if*/
  819. X                        break;
  820. X
  821. X                    }/*if*/
  822. X
  823. X                    tok = line[index++];
  824. X
  825. X                break;}/*default*/
  826. X
  827. X            }/*switch*/
  828. X
  829. X        break;}/*Rest*/
  830. X
  831. X        case Eof: {
  832. X/* do we have some indentation to adjust for ... */
  833. X            if ( curind > 0 ) {
  834. X                curind--;
  835. X                tok = END;
  836. X            } else {
  837. X                tok = 0;
  838. X            }/*if*/
  839. X
  840. X
  841. X        break;}/*Eof*/
  842. X
  843. X
  844. X    }/*switch*/
  845. X
  846. X    }/*while*/
  847. X
  848. X/* return whats required after setting yytext etc */
  849. X    if ( index > sind ) {
  850. X        int    i;
  851. X        yylen = index - sind;
  852. X
  853. X        for ( i = 0; i < yylen; i++ ) {
  854. X            yytext[i] = line[sind+i];
  855. X        }/*for*/
  856. X
  857. X        yytext[yylen] = '\0';
  858. X
  859. X    } else {
  860. X        yylen = 0;
  861. X        yytext[0] = '\0';
  862. X
  863. X    }/*if*/
  864. X
  865. X/* debug report */
  866. X    if ( ldebug ) {
  867. X        fprintf( stderr, "yylex: token %d <%s>\n", tok, yytext );
  868. X    }/*if*/
  869. X
  870. X    return( tok );
  871. X
  872. X}/*yylex*/
  873. X
  874. X/*************************************************************************/
  875. X
  876. Xm_nulline()
  877. X/* return true if a null line */
  878. X{
  879. X
  880. X    int    lindex=index;    /* local index */
  881. X
  882. X/* tramp thru spaces */
  883. X    while ( line[lindex] == ' ' ) {
  884. X        lindex++;
  885. X    }/*while*/
  886. X
  887. X/* any comment ? */
  888. X    if ( line[lindex] == '-' && line[lindex+1] == '-' ) {
  889. X        yylineno++;
  890. X        return( TRUE );
  891. X
  892. X/* or we got to the end of the line */
  893. X    } else if ( line[lindex]== '\n' ) {
  894. X        yylineno++;
  895. X        return( TRUE );
  896. X
  897. X    }/*if*/
  898. X
  899. X    return( FALSE );
  900. X
  901. X}/*m_nulline*/
  902. X
  903. X/* end occamlex.c */
  904. SHAR_EOF
  905. chmod 0666 occamlex.c || echo "restore of occamlex.c fails"
  906. set `wc -c occamlex.c`;Sum=$1
  907. if test "$Sum" != "8622"
  908. then echo original size 8622, current size $Sum;fi
  909. fi
  910. if test -f occam2.y; then echo "File occam2.y exists"; else
  911. echo "x - extracting occam2.y (Text)"
  912. sed 's/^X//' << 'SHAR_EOF' > occam2.y &&
  913. X/* 
  914. X *
  915. X *        OCCAM2 yacc specification
  916. X *
  917. X *        Peter Polkinghorne - GEC Research
  918. X *
  919. X */
  920. X
  921. X/*
  922. X * This work is in the public domain.
  923. X * It was written by Peter Polkinghorne in 1986 & 1989 at
  924. X * GEC Hirst Research Centre, Wembley, England.
  925. X * No liability is accepted or warranty given by the Author,
  926. X * still less my employers.
  927. X */
  928. X
  929. X/* revision history
  930. X    0.0    initial attempt                pjmp    9/3/89
  931. X
  932. Xend revisions */
  933. X
  934. X%token        VAR    CHAN    ANY    SKIP    ID    EOL
  935. X%token        VALUE    BYTE    DEF    PROC    NOT    NUMBER    BOOL
  936. X%token        NOW    TABLE    BOOLOP    SHIFTOP    COMPOP    CHCON    STR
  937. X%token        LOGOP    SEQ    ALT    IF    PAR    WHILE    FOR
  938. X%token        OF    SIZE    TRUNC    ROUND    MOSTNEG    MOSTPOS    RNUMBER
  939. X%token        STOP    CASE    ELSE    IS    VAL    FROM    PROTOCOL
  940. X%token        INT    INT16    INT32    INT64    REAL    REAL32    REAL64
  941. X%token        PLACE    AT    PLACED    PROCESSOR    FUNCTION
  942. X%token        AFTER    RETYPES    VALOF    RESULT    PORT    PRI
  943. X%token        BEG    END    TO    TIMER
  944. X
  945. X%start        program
  946. X
  947. X%%
  948. X
  949. Xprogram        :    sep process
  950. X        |    process
  951. X        ;
  952. X
  953. Xprocess        :    action sep
  954. X        |    SKIP sep
  955. X        |    STOP sep
  956. X        |    CASE selector sep
  957. X        |    CASE selector sep BEG selectlist END
  958. X        |    construct
  959. X        |    instance
  960. X        |    specification sep process
  961. X        |    caseinput
  962. X        |    allocation sep process
  963. X        |    error sep
  964. X            {
  965. X                yyerrok;
  966. X            }
  967. X        ;
  968. X
  969. Xaction        :    assignment
  970. X        |    input
  971. X        |    output
  972. X        ;
  973. X
  974. Xallocation    :    PLACE ID AT expr ':'
  975. X        ;
  976. X
  977. Xselectlist    :    select
  978. X        |    selectlist select
  979. X        ;
  980. X
  981. Xselect        :    expr sep BEG process END
  982. X        |    ELSE sep BEG process END
  983. X        ;
  984. X
  985. Xselector    :    expr
  986. X        ;
  987. X
  988. Xconstruct    :    sequence
  989. X        |    parallel
  990. X        |    conditional
  991. X        |    alternation
  992. X        |    loop
  993. X        ;
  994. X
  995. Xinstance    :    ID '(' actualist ')' sep
  996. X        |    ID '(' ')' sep
  997. X        ;
  998. X
  999. Xactualist    :    actual
  1000. X        |    actualist comma actual
  1001. X        ;
  1002. X
  1003. Xactual        :    element
  1004. X        |    expr
  1005. X        ;
  1006. X
  1007. Xsequence    :    SEQ sep BEG proclist END
  1008. X        |    SEQ replic sep BEG process END
  1009. X        |    SEQ sep
  1010. X        ;
  1011. X
  1012. Xparallel    :    PAR sep BEG proclist END
  1013. X        |    PAR replic sep BEG process END
  1014. X        |    PAR sep
  1015. X        |    PRI PAR sep BEG proclist END
  1016. X        |    PRI PAR replic sep BEG process END
  1017. X        |    PRI PAR sep
  1018. X        |    PLACED PAR sep BEG placelist END
  1019. X        |    PLACED PAR replic sep BEG placement END
  1020. X        |    PLACED PAR sep
  1021. X        ;
  1022. X
  1023. Xconditional    :    IF sep BEG choicelist END
  1024. X        |    IF replic sep BEG choice END
  1025. X        |    IF sep
  1026. X        ;
  1027. X
  1028. Xalternation    :    ALT sep BEG alternativelist END
  1029. X        |    ALT replic sep BEG alternative END
  1030. X        |    ALT sep
  1031. X        |    PRI ALT sep BEG alternativelist END
  1032. X        |    PRI ALT replic sep BEG alternative END
  1033. X        |    PRI ALT sep
  1034. X        ;
  1035. X
  1036. Xloop        :    WHILE expr sep BEG process END
  1037. X        ;
  1038. X
  1039. Xsep        :    EOL
  1040. X        |    sep EOL
  1041. X        ;
  1042. X
  1043. Xcomma        :    ',' EOL
  1044. X        |    ','
  1045. X        ;
  1046. X
  1047. Xsemicolon    :    ';' EOL
  1048. X        |    ';'
  1049. X        ;
  1050. X
  1051. Xproclist    :    process
  1052. X        |    proclist process
  1053. X        ;
  1054. X
  1055. Xchoicelist    :    choice
  1056. X        |    choicelist choice
  1057. X        ;
  1058. X
  1059. Xplacelist    :    placement
  1060. X        |    placelist placement
  1061. X        ;
  1062. X
  1063. Xalternativelist    :    alternative
  1064. X        |    alternativelist alternative
  1065. X        ;
  1066. X
  1067. X
  1068. Xreplic        :    ID '=' base FOR count
  1069. X        ;
  1070. X
  1071. Xbase        :    expr
  1072. X        ;
  1073. X
  1074. Xcount        :    expr
  1075. X        ;
  1076. X
  1077. Xchoice        :    boolean sep BEG process END
  1078. X        |    specification sep choice
  1079. X        |    conditional
  1080. X        ;
  1081. X
  1082. Xplacement    :    PROCESSOR expr sep BEG process END
  1083. X        ;
  1084. X
  1085. Xalternative    :    guard sep BEG process END
  1086. X        |    specification sep alternative
  1087. X        |    alternation
  1088. X        ;
  1089. X
  1090. Xguard        :    boolean '&' input
  1091. X        |    input
  1092. X        |    boolean '&' SKIP
  1093. X        ;
  1094. X
  1095. Xspecification    :    declaration
  1096. X        |    abbreviation
  1097. X        |    definition
  1098. X        ;
  1099. X
  1100. Xdeclaration    :    type namelist ':'
  1101. X        ;
  1102. X
  1103. Xnamelist    :    ID
  1104. X        |    namelist comma ID
  1105. X        ;
  1106. X
  1107. Xabbreviation    :    specifier ID IS element ':'
  1108. X        |    VAL specifier ID IS element ':'
  1109. X        |    ID IS element ':'
  1110. X        |    VAL ID IS element ':'
  1111. X        ;
  1112. X
  1113. Xspecifier    :    primtype
  1114. X        |    '['']' specifier
  1115. X        |    '[' expr ']' specifier
  1116. X        ;
  1117. X
  1118. Xdefinition    :    PROTOCOL ID IS simpleproto ':'
  1119. X        |    PROTOCOL ID IS seqproto ':'
  1120. X        |    PROTOCOL ID sep BEG CASE sep END ':'
  1121. X        |    PROTOCOL ID sep BEG CASE sep BEG tagprotolist END END ':'
  1122. X        |    PROC ID '(' fparmlist ')' sep BEG process END ':'
  1123. X        |    PROC ID '(' ')' sep BEG process END ':'
  1124. X        |    typelist FUNCTION ID '(' fparmlist ')' sep BEG valof END ':'
  1125. X        |    typelist FUNCTION ID '(' ')' sep BEG valof END ':'
  1126. X        |    typelist FUNCTION ID '(' fparmlist ')' IS explist ':'
  1127. X        |    typelist FUNCTION ID '(' ')' IS explist ':'
  1128. X        |    specifier ID RETYPES element ':'
  1129. X        |    VAL specifier ID RETYPES expr ':'
  1130. X        ;
  1131. X
  1132. Xsimpleproto    :    type
  1133. X        |    type ':' ':' '[' ']' type
  1134. X        ;
  1135. X
  1136. Xseqproto    :    simpleproto
  1137. X        |    seqproto semicolon simpleproto
  1138. X        ;
  1139. X
  1140. Xtagprotolist    :    tagproto
  1141. X        |    tagprotolist sep tagproto
  1142. X        ;
  1143. X
  1144. Xtagproto    :    tag
  1145. X        |    tag semicolon protocol
  1146. X        ;
  1147. X
  1148. Xtag        :    ID
  1149. X        ;
  1150. X
  1151. Xprotocol    :    ANY
  1152. X        |    ID
  1153. X        |    simpleproto
  1154. X        ;
  1155. X
  1156. Xassignment    :    varlist ':' '=' explist
  1157. X        ;
  1158. X
  1159. Xinput        :    chan '?' inlist
  1160. X        |    chan '?' CASE taggedlist
  1161. X        |    port '?' var
  1162. X        |    timer '?' var
  1163. X        |    timer '?' AFTER expr
  1164. X        ;
  1165. X
  1166. Xcaseinput    :    chan '?' CASE sep
  1167. X        |    chan '?' CASE sep BEG variantlist END
  1168. X        ;
  1169. X
  1170. Xtaggedlist    :    tag
  1171. X        |    tag semicolon inlist
  1172. X        ;
  1173. X
  1174. Xvariantlist    :    variant
  1175. X        |    variantlist sep variant
  1176. X        ;
  1177. X
  1178. Xvariant        :    taggedlist sep BEG process END
  1179. X        |    specification sep variant
  1180. X        ;
  1181. X
  1182. Xoutput        :    chan '!' outlist
  1183. X        |    chan '!' tag
  1184. X        |    chan '!' tag semicolon outlist
  1185. X        |    port '!' element
  1186. X        |    port '!' expr
  1187. X        ;
  1188. X
  1189. Xinlist        :    var
  1190. X        |    var ':' ':' var
  1191. X        |    inlist semicolon var
  1192. X        ;
  1193. X
  1194. Xoutlist        :    expr
  1195. X        |    expr ':' ':' expr
  1196. X        |    outlist semicolon expr
  1197. X        ;
  1198. X
  1199. Xexplist        :    expr
  1200. X        |    explist comma expr
  1201. X        |    '(' valof sep ')'
  1202. X        |    ID '(' explist ')'
  1203. X        |    ID '(' ')'
  1204. X        ;
  1205. X
  1206. Xvarlist        :    var
  1207. X        |    varlist comma var
  1208. X        ;
  1209. X
  1210. Xtypelist    :    type
  1211. X        |    typelist comma type
  1212. X        ;
  1213. X
  1214. Xfparmlist    :    fparm
  1215. X        |    fparmlist comma fparm
  1216. X        ;
  1217. X
  1218. Xfparm        :    specifier ID
  1219. X        |    VAL specifier ID
  1220. X        ;
  1221. X
  1222. Xvar        :    element
  1223. X        ;
  1224. X
  1225. Xtimer        :    element
  1226. X        ;
  1227. X
  1228. Xchan        :    element
  1229. X        ;
  1230. X
  1231. Xport        :    element
  1232. X        ;
  1233. X
  1234. Xelement        :    ID
  1235. X        |    element '[' subscript ']'
  1236. X        |    '[' element FROM subscript TO subscript ']'
  1237. X        ;
  1238. X
  1239. Xsubscript    :    expr
  1240. X        ;
  1241. X
  1242. Xexpr        :    monop operand
  1243. X        |    operand dyop operand
  1244. X        |    monop sep operand
  1245. X        |    operand dyop sep operand
  1246. X        |    operand
  1247. X        |    conversion
  1248. X        |    MOSTPOS type
  1249. X        |    MOSTNEG type
  1250. X        ;
  1251. X
  1252. Xoperand        :    element
  1253. X        |    literal
  1254. X        |    '(' expr ')'
  1255. X        |    '[' explist ']'
  1256. X        |    '(' valof sep ')'
  1257. X        |    ID '(' explist ')'
  1258. X        |    ID '(' ')'
  1259. X        ;
  1260. X
  1261. Xconversion    :    type operand
  1262. X        |    type ROUND operand
  1263. X        |    type TRUNC operand
  1264. X        ;
  1265. X
  1266. Xmonop        :    '-'
  1267. X        |    NOT
  1268. X        |    SIZE
  1269. X        |    '~'
  1270. X        ;
  1271. X
  1272. Xliteral        :    NUMBER
  1273. X        |    BOOL
  1274. X        |    RNUMBER
  1275. X        |    CHCON
  1276. X        |    STR
  1277. X        |    NUMBER '(' type ')'
  1278. X        |    RNUMBER '(' type ')'
  1279. X        |    CHCON '(' type ')'
  1280. X        ;
  1281. X
  1282. Xdyop        :    COMPOP
  1283. X        |    '='
  1284. X        |    SHIFTOP
  1285. X        |    '+'
  1286. X        |    '*'
  1287. X        |    LOGOP
  1288. X        |    BOOLOP
  1289. X        |    '-'
  1290. X        |    '/'
  1291. X        |    '\\'
  1292. X        ;
  1293. X
  1294. Xvalof        :    VALOF sep BEG process RESULT explist sep END
  1295. X        |    specification sep valof
  1296. X        ;
  1297. X
  1298. Xtype        :    primtype
  1299. X        |    arrtype
  1300. X        ;
  1301. X
  1302. Xprimtype    :    CHAN OF protocol
  1303. X        |    PORT OF type
  1304. X        |    TIMER
  1305. X        |    BOOL
  1306. X        |    BYTE
  1307. X        |    INT
  1308. X        |    INT16
  1309. X        |    INT32
  1310. X        |    INT64
  1311. X        |    REAL32
  1312. X        |    REAL64
  1313. X        ;
  1314. X
  1315. Xarrtype        :    '[' expr ']' type
  1316. X        ;
  1317. X
  1318. Xboolean        :    expr
  1319. X        ;
  1320. X
  1321. X%%
  1322. X
  1323. X#include <stdio.h>
  1324. X
  1325. Xvoid main()
  1326. X{
  1327. X
  1328. X    exit( yyparse() );
  1329. X
  1330. X}/*main*/
  1331. X
  1332. Xyyerror( str )
  1333. Xchar     *str;
  1334. X/* our slightly more informative error routine */
  1335. X{
  1336. X
  1337. Xextern int    yylineno;
  1338. Xextern char    yytext[];
  1339. X
  1340. X    fprintf( stderr, "ERROR <%s> near <%s> on line %d\n",
  1341. X            str, yytext, yylineno );
  1342. X
  1343. X}/*yyerror*/
  1344. X
  1345. X/*end occam.y*/
  1346. SHAR_EOF
  1347. chmod 0666 occam2.y || echo "restore of occam2.y fails"
  1348. set `wc -c occam2.y`;Sum=$1
  1349. if test "$Sum" != "6613"
  1350. then echo original size 6613, current size $Sum;fi
  1351. fi
  1352. if test -f occam2lex.c; then echo "File occam2lex.c exists"; else
  1353. echo "x - extracting occam2lex.c (Text)"
  1354. sed 's/^X//' << 'SHAR_EOF' > occam2lex.c &&
  1355. X/*
  1356. X *    OCCAM2 lexical analysis routine
  1357. X *
  1358. X *    pjmp    HRC    9/3/89
  1359. X *
  1360. X */
  1361. X
  1362. X/*
  1363. X * This work is in the public domain.
  1364. X * It was written by Peter Polkinghorne in 1986 & 1989 at
  1365. X * GEC Hirst Research Centre, Wembley, England.
  1366. X * No liability is accepted or warranty given by the Author,
  1367. X * still less my employers.
  1368. X */
  1369. X
  1370. X/* revision history
  1371. X
  1372. X    0.0    first release                    pjmp    9/3/89
  1373. X
  1374. Xend revisions */
  1375. X
  1376. X#include <stdio.h>
  1377. X#include <ctype.h>
  1378. X#include "lex2.h"
  1379. X
  1380. X#define    MAXLINE    256
  1381. X
  1382. X#define    TRUE    1
  1383. X#define    FALSE    0
  1384. X
  1385. X/************************************************************************/
  1386. X/* reserved word list - ordered for binary chomp */
  1387. X
  1388. Xstatic struct reserv { char * word; int tok, len; } rlist[] = {
  1389. X        "AFTER",    AFTER,    5,
  1390. X        "ALT",        ALT,    3,
  1391. X        "AND",        BOOLOP,    3,
  1392. X        "ANY",        ANY,    3,
  1393. X        "AT",        AT,    2,
  1394. X        "BYTE",        BYTE,    4,
  1395. X        "CASE",        CASE,    4,
  1396. X        "CHAN",        CHAN,    4,
  1397. X        "DEF",        DEF,    3,
  1398. X        "ELSE",        ELSE,    4,
  1399. X        "FALSE",    BOOL,    5,
  1400. X        "FOR",        FOR,    3,
  1401. X        "FROM",        FROM,    4,
  1402. X        "FUNCTION",    FUNCTION,    8,
  1403. X        "IF",        IF,    2,
  1404. X        "INT",        INT,    3,
  1405. X        "INT16",    INT16,    5,
  1406. X        "INT32",    INT32,    5,
  1407. X        "INT64",    INT64,    5,
  1408. X        "IS",        IS,    2,
  1409. X        "MOSTNEG",    MOSTNEG,7,
  1410. X        "MOSTPOS",    MOSTPOS,7,
  1411. X        "NOT",        NOT,    3,
  1412. X        "NOW",        NOW,    3,
  1413. X        "OR",        BOOLOP,    2,
  1414. X        "OF",        OF,    2,
  1415. X        "PAR",        PAR,    3,
  1416. X        "PLACE",    PLACE,    5,
  1417. X        "PLACED",    PLACED,    6,
  1418. X        "PORT",        PORT,    4,
  1419. X        "PRI",        PRI,    3,
  1420. X        "PROC",        PROC,    4,
  1421. X        "PROCESSOR",    PROCESSOR,    9,
  1422. X        "PROTOCOL",    PROTOCOL,    8,
  1423. X        "ROUND",    ROUND,    5,
  1424. X        "REAL",        REAL,    4,
  1425. X        "REAL32",    REAL32,    6,
  1426. X        "REAL64",    REAL64,    6,
  1427. X        "RESULT",    RESULT,    6,
  1428. X        "RETYPES",    RETYPES,    7,
  1429. X        "SEQ",        SEQ,    3,
  1430. X        "SIZE",        SIZE,    4,
  1431. X        "SKIP",        SKIP,    4,
  1432. X        "STOP",        STOP,    4,
  1433. X        "TABLE",    TABLE,    5,
  1434. X        "TIMER",    TIMER,    5,
  1435. X        "TO",        TO,    2,
  1436. X        "TRUE",        BOOL,    4,
  1437. X        "TRUNC",    TRUNC,    5,
  1438. X        "VALUE",    VALUE,    5,
  1439. X        "VAL",        VAL,    3,
  1440. X        "VALOF",    VALOF,    5,
  1441. X        "VAR",        VAR,    3,
  1442. X        "WHILE",    WHILE,    5,
  1443. X        0,        0,    0
  1444. X
  1445. X    };
  1446. X
  1447. X/************************************************************************/
  1448. X
  1449. Xstatic    char    line[MAXLINE];    /* where we store the input, line as a time */
  1450. X
  1451. Xchar    yytext[MAXLINE];    /* where we store text associated with token */
  1452. X
  1453. Xint    yylineno=1,        /* line number of input */
  1454. X    yylen;            /* amount of text stored */
  1455. X
  1456. Xstatic    int    llen,        /* how much in line */
  1457. X        curind,        /* current indentation */
  1458. X        indent=0;    /* this lines indent */
  1459. X        ldebug = TRUE,    /* set to TRUE for debug */
  1460. X        index;        /* where we are in the line */
  1461. X
  1462. X/* state we are in: either start - get new input, decide what next
  1463. X            ind - processing indentation
  1464. X            rest - processing some occam stmt
  1465. X            eof - tidy up processing
  1466. X*/
  1467. X
  1468. Xstatic    enum    lexstate { Start, Ind, Rest, Eof } state = Start;
  1469. X
  1470. X/************************************************************************/
  1471. X
  1472. Xyylex()
  1473. X/* this function returns the next token (defined by lex.h), a character
  1474. Xvalue or 0 for end of input. The tokens are defined by standard input
  1475. X*/
  1476. X{
  1477. X    int    tok = -1,    /* token to return - init to impossible value */
  1478. X        sind = index;    /* start of input being processed */
  1479. X
  1480. X/* go round and round until token to return */
  1481. X    while ( tok < 0  ) {
  1482. X
  1483. X/* decide by state */
  1484. X    switch (state) {
  1485. X
  1486. X        case Start: {
  1487. X/*grab some more line */
  1488. X            if ( fgets( line, MAXLINE-1, stdin ) == NULL ) {
  1489. X                state = Eof;
  1490. X                break;
  1491. X
  1492. X            } else if ( (llen=strlen(line)) >= MAXLINE-1 ) {
  1493. X                fprintf( stderr,
  1494. X                    "line <%s> longer than %d\n",
  1495. X                    line, MAXLINE-1 );
  1496. X                exit( 1 );
  1497. X            }/*if*/
  1498. X
  1499. X            index = 0;
  1500. X            sind = 0;
  1501. X            indent = 0;
  1502. X
  1503. X
  1504. X/* if blank line OR has just comment skip, otherwise got to appropriate state */
  1505. X
  1506. X            if ( m_nulline() ) {
  1507. X                /* do nowt */
  1508. X
  1509. X            } else if ( line[0]==' ' && line[1]==' ' ) {
  1510. X                state = Ind;
  1511. X
  1512. X            } else {
  1513. X                state = Rest;
  1514. X
  1515. X            }/*if*/
  1516. X
  1517. X        break;}/*Start*/
  1518. X
  1519. X        case Ind: {
  1520. X/* work out indentation */
  1521. X            if ( line[index]==' ' && line[index+1]==' ' ) {
  1522. X                indent++;
  1523. X                index+=2;
  1524. X                sind+=2;
  1525. X            } else {
  1526. X                state = Rest;
  1527. X            
  1528. X            }/*if*/
  1529. X    
  1530. X        break;}/*Ind*/
  1531. X
  1532. X        case Rest: {
  1533. X/* do we have some indentation to adjust for ... */
  1534. X            if ( curind > indent ) {
  1535. X                curind--;
  1536. X                tok = END;
  1537. X                break;
  1538. X
  1539. X            } else if ( curind < indent ) {
  1540. X                curind++;
  1541. X                tok = BEG;
  1542. X                break;
  1543. X
  1544. X            }/*if*/
  1545. X
  1546. X/* process ch as appropriate */
  1547. X            switch ( line[index] ) {
  1548. X
  1549. X/* space ignored */
  1550. X                case ' ': {
  1551. X                    sind++;
  1552. X                    index++;
  1553. X                break;}
  1554. X
  1555. X/* eol change state again */
  1556. X                case '\n': {
  1557. X                    yylineno++;
  1558. X                    index++;
  1559. X                    state = Start;
  1560. X                    tok = EOL;
  1561. X                break;}
  1562. X
  1563. X/* - a comment perhaps OR just itself */
  1564. X                case '-': {
  1565. X                    if ( line[index+1] == '-' ) {
  1566. X                        index = llen+1;
  1567. X                        state = Start;
  1568. X                        tok = EOL;
  1569. X
  1570. X                    } else {
  1571. X                        tok = line[index++];
  1572. X
  1573. X                    }/*if*/
  1574. X                break;}
  1575. X
  1576. X                case '<': {
  1577. X                    if ( line[index+1] == '<' ) {
  1578. X                        index+=2;
  1579. X                        tok = SHIFTOP;
  1580. X
  1581. X                    } else {
  1582. X                        if ( line[index+1] == '=' ||
  1583. X                            line[index+1] == '>' ) {
  1584. X                            index++;
  1585. X                        }/*if*/
  1586. X                        index++;
  1587. X                        tok = COMPOP;
  1588. X                    }/*if*/
  1589. X                break;}
  1590. X
  1591. X                case '>': {
  1592. X                    if ( line[index+1] == '>' ) {
  1593. X                        index+=2;
  1594. X                        tok = SHIFTOP;
  1595. X
  1596. X                    } else if ( line[index+1] == '<' ) {
  1597. X                        index+=2;
  1598. X                        tok = LOGOP;
  1599. X
  1600. X                    } else {
  1601. X                        if ( line[index+1] == '=' ) {
  1602. X                            index++;
  1603. X                        }/*if*/
  1604. X                        index++;
  1605. X                        tok = COMPOP;
  1606. X                    }/*if*/
  1607. X
  1608. X                break;}
  1609. X
  1610. X                case '/': {
  1611. X                    if ( line[index+1] == '\\' ) {
  1612. X                        index+=2;
  1613. X                        tok = LOGOP;
  1614. X
  1615. X                    } else {
  1616. X                        tok = line[index++];
  1617. X
  1618. X                    }/*if*/
  1619. X                break;}
  1620. X
  1621. X                case '\\': {
  1622. X                    if ( line[index+1] == '/' ) {
  1623. X                        index+=2;
  1624. X                        tok = LOGOP;
  1625. X
  1626. X                    } else {
  1627. X                        tok = line[index++];
  1628. X
  1629. X                    }/*if*/
  1630. X                break;}
  1631. X
  1632. X                case '#': {
  1633. X                    if ( isxdigit( line[index+1] ) ) {
  1634. X/* gobble up hex digits */
  1635. X                        index++;
  1636. X                        while ( isxdigit(line[index]) ){
  1637. X                            index++;
  1638. X                        }/*while*/
  1639. X
  1640. X                        tok = NUMBER;
  1641. X
  1642. X                    } else {
  1643. X                        tok = line[index++];
  1644. X
  1645. X                    }/*if*/
  1646. X
  1647. X                break;}
  1648. X
  1649. X                case '\'': {
  1650. X                    if ( line[index+1] != '*'
  1651. X                         && line[index+2] == '\'' ) {
  1652. X
  1653. X                        index+=3;
  1654. X                        tok = CHCON;
  1655. X
  1656. X                    } else if ( line[index+1] == '*'
  1657. X                         && line[index+2] != '#' 
  1658. X                         && line[index+3] == '\'' ) {
  1659. X
  1660. X                        index+=4;
  1661. X                        tok = CHCON;
  1662. X
  1663. X                    } else if ( line[index+1] == '*'
  1664. X                         && line[index+2] == '#' 
  1665. X                         && isxdigit( line[index+3] )
  1666. X                         && isxdigit( line[index+4] )
  1667. X                         && line[index+5] == '\'' ) {
  1668. X
  1669. X                        index+=6;
  1670. X                        tok = CHCON;
  1671. X
  1672. X                    } else {
  1673. X                        tok = line[index++];
  1674. X
  1675. X                    }/*if*/
  1676. X
  1677. X                break;}
  1678. X
  1679. X
  1680. X                case '"': {
  1681. X                    int    lindex=index+1;
  1682. X
  1683. X                    while ( line[lindex] != '"'
  1684. X                         && lindex <= llen ) {
  1685. X                        lindex++;
  1686. X                    }/*while*/
  1687. X
  1688. X                    if ( line[lindex] == '"' ) {
  1689. X                        index = lindex+1;
  1690. X                        tok = STR;
  1691. X
  1692. X                    } else {
  1693. X                        tok = line[index++];
  1694. X
  1695. X                    }/*if*/
  1696. X
  1697. X                break;}
  1698. X
  1699. X/* oh well pass back to yacc & let it cope  - if not digit or alpha */
  1700. X                default: {
  1701. X                    if ( isdigit( line[index] ) ) {
  1702. X/* gobble up digits */
  1703. X                        index++;
  1704. X                        while ( isdigit(line[index]) ){
  1705. X                            index++;
  1706. X                        }/*while*/
  1707. X
  1708. X                        tok = NUMBER;
  1709. X                        break;
  1710. X
  1711. X                    } else if ( isalpha( line[index] ) ) {
  1712. X                        int    i, wlen = 1;
  1713. X                        index++;
  1714. X/* gobble up associated chs */
  1715. X                        while ( isalpha( line[index] )
  1716. X                            || isdigit( line[index])
  1717. X                            || line[index] == '.' ){
  1718. X                            wlen++;
  1719. X                            index++;
  1720. X                        }/*while*/
  1721. X
  1722. X/* now check against reserved word list */
  1723. X                        for ( i=0;
  1724. X                             rlist[i].word != NULL;
  1725. X                            i++ ) {
  1726. X
  1727. X                            if ( rlist[i].len
  1728. X                                != wlen ) {
  1729. X                                continue;
  1730. X                            }/*if*/
  1731. X
  1732. X                            if ( strncmp(
  1733. X                              &line[index-wlen],
  1734. X                              rlist[i].word,
  1735. X                              wlen ) == 0 ) {
  1736. X
  1737. X                             tok = rlist[i].tok;
  1738. X                             break;
  1739. X                            }/*if*/
  1740. X                        }/*for*/
  1741. X
  1742. X/* not a reserved word */
  1743. X                        if ( tok < 0 ) {
  1744. X                            tok = ID;
  1745. X                        }/*if*/
  1746. X                        break;
  1747. X
  1748. X                    }/*if*/
  1749. X
  1750. X                    tok = line[index++];
  1751. X
  1752. X                break;}/*default*/
  1753. X
  1754. X            }/*switch*/
  1755. X
  1756. X        break;}/*Rest*/
  1757. X
  1758. X        case Eof: {
  1759. X/* do we have some indentation to adjust for ... */
  1760. X            if ( curind > 0 ) {
  1761. X                curind--;
  1762. X                tok = END;
  1763. X            } else {
  1764. X                tok = 0;
  1765. X            }/*if*/
  1766. X
  1767. X
  1768. X        break;}/*Eof*/
  1769. X
  1770. X
  1771. X    }/*switch*/
  1772. X
  1773. X    }/*while*/
  1774. X
  1775. X/* return whats required after setting yytext etc */
  1776. X    if ( index > sind ) {
  1777. X        int    i;
  1778. X        yylen = index - sind;
  1779. X
  1780. X        for ( i = 0; i < yylen; i++ ) {
  1781. X            yytext[i] = line[sind+i];
  1782. X        }/*for*/
  1783. X
  1784. X        yytext[yylen] = '\0';
  1785. X
  1786. X    } else {
  1787. X        yylen = 0;
  1788. X        yytext[0] = '\0';
  1789. X
  1790. X    }/*if*/
  1791. X
  1792. X/* debug report */
  1793. X    if ( ldebug ) {
  1794. X        fprintf( stderr, "yylex: token %d <%s>\n", tok, yytext );
  1795. X    }/*if*/
  1796. X
  1797. X    return( tok );
  1798. X
  1799. X}/*yylex*/
  1800. X
  1801. X/*************************************************************************/
  1802. X
  1803. Xm_nulline()
  1804. X/* return true if a null line */
  1805. X{
  1806. X
  1807. X    int    lindex=index;    /* local index */
  1808. X
  1809. X/* tramp thru spaces */
  1810. X    while ( line[lindex] == ' ' ) {
  1811. X        lindex++;
  1812. X    }/*while*/
  1813. X
  1814. X/* any comment ? */
  1815. X    if ( line[lindex] == '-' && line[lindex+1] == '-' ) {
  1816. X        yylineno++;
  1817. X        return( TRUE );
  1818. X
  1819. X/* or we got to the end of the line */
  1820. X    } else if ( line[lindex]== '\n' ) {
  1821. X        yylineno++;
  1822. X        return( TRUE );
  1823. X
  1824. X    }/*if*/
  1825. X
  1826. X    return( FALSE );
  1827. X
  1828. X}/*m_nulline*/
  1829. X
  1830. X/* end occam2lex.c */
  1831. SHAR_EOF
  1832. chmod 0666 occam2lex.c || echo "restore of occam2lex.c fails"
  1833. set `wc -c occam2lex.c`;Sum=$1
  1834. if test "$Sum" != "8696"
  1835. then echo original size 8696, current size $Sum;fi
  1836. fi
  1837. if test -f test1; then echo "File test1 exists"; else
  1838. echo "x - extracting test1 (Text)"
  1839. sed 's/^X//' << 'SHAR_EOF' > test1 &&
  1840. XSEQ
  1841. X  fred:=0
  1842. SHAR_EOF
  1843. chmod 0666 test1 || echo "restore of test1 fails"
  1844. set `wc -c test1`;Sum=$1
  1845. if test "$Sum" != "14"
  1846. then echo original size 14, current size $Sum;fi
  1847. fi
  1848. if test -f test2; then echo "File test2 exists"; else
  1849. echo "x - extracting test2 (Text)"
  1850. sed 's/^X//' << 'SHAR_EOF' > test2 &&
  1851. XVAR volume:
  1852. XSEQ
  1853. X  volume:=0
  1854. X  WHILE TRUE
  1855. X    ALT
  1856. X      louder?ANY
  1857. X         SEQ
  1858. X           volume:=volume+1
  1859. X           amplifier!volume
  1860. X      softer?ANY
  1861. X         SEQ
  1862. X           volume:=volume-1
  1863. X           amplifier!volume
  1864. SHAR_EOF
  1865. chmod 0666 test2 || echo "restore of test2 fails"
  1866. set `wc -c test2`;Sum=$1
  1867. if test "$Sum" != "221"
  1868. then echo original size 221, current size $Sum;fi
  1869. fi
  1870. if test -f test3; then echo "File test3 exists"; else
  1871. echo "x - extracting test3 (Text)"
  1872. sed 's/^X//' << 'SHAR_EOF' > test3 &&
  1873. X  -- this is a comprehensive exercise of occam syntax
  1874. X        -- pjmp @ hrc 31/7/86
  1875. XVAR fred, joe[BYTE - #fAf], bill[ (20>>2)/\#0F]:
  1876. XVAR heinz:
  1877. XCHAN mary,jane[TRUE]:
  1878. XCHAN sue:
  1879. XDEF one =1, alphabet="abcdefghijklmnopq"
  1880. X"rstuvwxyz":
  1881. XDEF Tablet   = TABLE [ BYTE 0 ]:
  1882. X
  1883. XPROC time =
  1884. X  mary!NOW
  1885. X:
  1886. X
  1887. XPROC relay ( CHAN from, to, VAR via ) =
  1888. X  SEQ
  1889. X    from?via
  1890. X    to!via
  1891. X:
  1892. X
  1893. XPROC zilch ( VALUE t[] ) =
  1894. X  SKIP
  1895. X:
  1896. X
  1897. XWHILE NOT FALSE
  1898. X
  1899. X  SEQ
  1900. X    time
  1901. X    bill[0]   := TABLE [ 2, 3, 5, 7, 11, 13, 17, 19, 23] [fred]
  1902. X    WAIT NOW AFTER bill[joe[BYTE 0]]
  1903. X
  1904. X    VAR cats, dogs:
  1905. X    CHAN raining[ one ]:
  1906. X    PAR WHICH = [ 0 FOR one ]
  1907. X      relay( raining[ cats AND dogs], jane[WHICH], alphabet[WHICH] )
  1908. X
  1909. X    zilch( "abc"[2] )
  1910. X
  1911. X    SEQ
  1912. X
  1913. X    mary!ANY
  1914. X
  1915. X    CHAN jane:
  1916. X    jane?ANY
  1917. X
  1918. X    PAR
  1919. X
  1920. X    VAR john,tarzan:
  1921. X    CHAN janet,jane:
  1922. X    PAR
  1923. X      janet?john;john
  1924. X      jane!tarzan; tarzan
  1925. X
  1926. X    IF
  1927. X      'a' << #2
  1928. X        IF
  1929. X
  1930. X      IF
  1931. X        '**' >> ( 1 OR 2 )
  1932. X          IF fred = [ 0 FOR '*#FF' ]
  1933. X            fred <> ( alphabet[ fred >< bill[ fred /\ bill [ fred \/ fred ]]] )
  1934. X              joe := (fred>0) AND (fred<100) AND (fred>='a') AND (fred<='-')
  1935. X
  1936. X    VAR then:
  1937. X    ALT fred = [ 1+1+1 FOR 2*2*(2-1)+(4\2)*(2/2) ]
  1938. X      ALT
  1939. X        ALT
  1940. X        SKIP
  1941. X          SKIP
  1942. X        fred = 3 & SKIP
  1943. X          SKIP
  1944. X        fred >3 & WAIT NOW
  1945. X          SKIP
  1946. X        WAIT NOW AFTER then
  1947. X          SKIP
  1948. X        fred < 20 & mary?ANY
  1949. X          then := NOW
  1950. X        jane[fred]?then
  1951. X          then := then + 4
  1952. SHAR_EOF
  1953. chmod 0666 test3 || echo "restore of test3 fails"
  1954. set `wc -c test3`;Sum=$1
  1955. if test "$Sum" != "1469"
  1956. then echo original size 1469, current size $Sum;fi
  1957. fi
  1958. if test -f test4; then echo "File test4 exists"; else
  1959. echo "x - extracting test4 (Text)"
  1960. sed 's/^X//' << 'SHAR_EOF' > test4 &&
  1961. X
  1962. X  -- this is another comprehensive exercise of occam syntax
  1963. X        -- pjmp @ hrc 31/7/86
  1964. XVAR fred, joe[BYTE - #fAf], bill[ (20>>2)/\#0F]:
  1965. XVAR heinz:
  1966. XCHAN mary,jane[TRUE]:
  1967. XCHAN sue:
  1968. XDEF one =1, alphabet="abcdefghijklmnopq"
  1969. X"rstuvwxyz":
  1970. XDEF Tablet   = TABLE [ BYTE 0 ]:
  1971. X
  1972. XPROC time =
  1973. X  mary!NOW
  1974. X:
  1975. X
  1976. XPROC relay ( CHAN from, to, VAR via ) =
  1977. X  SEQ
  1978. X    from?via
  1979. X    to!via
  1980. X:
  1981. X
  1982. XPROC zilch ( VALUE t[] ) =
  1983. X  SKIP
  1984. X:
  1985. X
  1986. XWHILE NOT FALSE
  1987. X
  1988. X  SEQ
  1989. X    time
  1990. X    bill[0]   := TABLE [ 2, 3, 5, 7, 11, 13, 17, 19, 23] [fred]
  1991. X    WAIT NOW AFTER bill[joe[BYTE 0]]
  1992. X
  1993. X    VAR cats, dogs:
  1994. X    CHAN raining[ one ]:
  1995. X    PAR WHICH = [ 0 FOR one ]
  1996. X      relay( raining[ cats AND dogs], jane[WHICH], alphabet[WHICH] )
  1997. X
  1998. X    zilch( "abc"[2] )
  1999. X
  2000. X    SEQ fred = [ 0 FOR 3 ]
  2001. X
  2002. X    mary!ANY
  2003. X
  2004. X    CHAN jane:
  2005. X    jane?ANY
  2006. X
  2007. X    PAR
  2008. X
  2009. X    VAR john,tarzan:
  2010. X    CHAN janet,jane:
  2011. X    PAR
  2012. X      janet?john;john
  2013. X      jane!tarzan; tarzan
  2014. X
  2015. X    IF
  2016. X      'a' << #2
  2017. X        IF
  2018. X
  2019. X      IF
  2020. X        '**' >> ( 1 OR 2 )
  2021. X          IF fred = [ 0 FOR '*#FF' ]
  2022. X            fred <> ( alphabet[ fred >< bill[ fred /\ bill [ fred \/ fred ]]] )
  2023. X              joe := (fred>0) AND (fred<100) AND (fred>='a') AND (fred<='-')
  2024. X
  2025. X    VAR then:
  2026. X    ALT fred = [ 1+1+1 FOR 2*2*(2-1)+(4\2)*(2/2) ]
  2027. X      ALT
  2028. X        ALT
  2029. X        SKIP
  2030. X          SKIP
  2031. X        fred = 3 & SKIP
  2032. X          SKIP
  2033. X        fred >3 & WAIT NOW
  2034. X          SKIP
  2035. X        WAIT NOW AFTER then
  2036. X          SKIP
  2037. X        fred < 20 & mary?ANY
  2038. X          then := NOW
  2039. X        jane[fred]?then
  2040. X          then := then + 4
  2041. SHAR_EOF
  2042. chmod 0666 test4 || echo "restore of test4 fails"
  2043. set `wc -c test4`;Sum=$1
  2044. if test "$Sum" != "1495"
  2045. then echo original size 1495, current size $Sum;fi
  2046. fi
  2047. exit 0
  2048.  
  2049.  
  2050.