home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume7 / occam.yacc < prev    next >
Encoding:
Text File  |  1989-08-11  |  38.0 KB  |  2,041 lines

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