Import GNU Enscript version 1.6.4
[enscript.git] / states / gram.y
1 %{
2 /*                                                              -*- c -*-
3  * Grammar for states.
4  * Copyright (c) 1997-1998 Markku Rossi.
5  *
6  * Author: Markku Rossi <mtr@iki.fi>
7  */
8
9 /*
10  * This file is part of GNU enscript.
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2, or (at your option)
15  * any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; see the file COPYING.  If not, write to
24  * the Free Software Foundation, 59 Temple Place - Suite 330,
25  * Boston, MA 02111-1307, USA.
26  */
27
28 /*
29  * $Id: gram.y,v 1.1.1.1 2003/03/05 07:25:52 mtr Exp $
30  */
31
32 #include "defs.h"
33 %}
34
35 %union
36 {
37   List *lst;
38   Node *node;
39   Cons *cons;
40   Stmt *stmt;
41   Expr *expr;
42 }
43
44 %token <node> tSYMBOL tREGEXP tSTRING tINTEGER tREAL
45 %token tSUB tSTATE tSTART tSTARTRULES tNAMERULES tBEGIN tEND tRETURN tIF tELSE
46 %token tLOCAL tWHILE tFOR tEXTENDS
47
48 %right '=' tADDASSIGN tSUBASSIGN tMULASSIGN tDIVASSIGN
49 %right '?' ':'
50 %left tOR
51 %left tAND
52 %left tEQ tNE
53 %left '<' '>' tGE tLE
54 %left '+' '-'
55 %left '*' tDIV
56 %right '!' tPLUSPLUS tMINUSMINUS
57 %left '[' ']'
58
59 %type <lst> regexp_sym_list symbol_list rest_symbol_list staterules
60 %type <lst> stmt_list expr_list rest_expr_list locals locals_rest
61 %type <stmt> stmt
62 %type <expr> expr cond_expr
63 %type <cons> staterule local_def
64
65 %%
66
67 file    : /* empty */
68         | file toplevel
69         ;
70
71 toplevel : tSTART '{' stmt_list '}'     { start_stmts = $3; }
72         | tSTARTRULES '{' regexp_sym_list '}'
73                                         { startrules = $3; }
74         | tNAMERULES '{' regexp_sym_list '}'
75                                         { namerules = $3; }
76         | tSTATE tSYMBOL '{' staterules '}'
77                                         { define_state ($2, NULL, $4); }
78         | tSTATE tSYMBOL tEXTENDS tSYMBOL '{' staterules '}'
79                                         { define_state ($2, $4, $6); }
80         | stmt                          { list_append (global_stmts, $1); }
81         ;
82
83 regexp_sym_list : /* empty */           { $$ = list (); }
84         | regexp_sym_list tREGEXP tSYMBOL ';'
85                                         { list_append ($1, cons ($2, $3)); }
86         ;
87
88 staterules : /* empty */                { $$ = list (); }
89         | staterules staterule          { list_append ($1, $2); }
90
91 staterule : tBEGIN '{' stmt_list '}'    { $$ = cons (RULE_BEGIN, $3); }
92         | tEND '{' stmt_list '}'        { $$ = cons (RULE_END, $3); }
93         | tREGEXP '{' stmt_list '}'     { $$ = cons ($1, $3); }
94         | tSYMBOL '{' stmt_list '}'     { $$ = cons ($1, $3); }
95         ;
96
97 symbol_list : /* empty */               { $$ = list (); }
98         | rest_symbol_list              { $$ = $1; }
99         ;
100
101 rest_symbol_list : tSYMBOL              { $$ = list (); list_append ($$, $1); }
102         | rest_symbol_list ',' tSYMBOL  { list_append ($1, $3); }
103         ;
104
105 locals  : /* empty */                   { $$ = list (); }
106         | tLOCAL locals_rest ';'        { $$ = $2; }
107         ;
108
109 locals_rest : local_def                 { $$ = list (); list_append ($$, $1); }
110         | locals_rest ',' local_def     { list_append ($1, $3); }
111         ;
112
113 local_def : tSYMBOL                     { $$ = cons ($1, NULL); }
114         | tSYMBOL '=' expr              { $$ = cons ($1, $3); }
115         ;
116
117 stmt_list : /* empty */                 { $$ = list (); }
118         | stmt_list stmt                { list_append ($1, $2); }
119         ;
120
121 stmt    : tRETURN ';'                   { $$ = mk_stmt (sRETURN, NULL, NULL,
122                                                         NULL, NULL); }
123         | tRETURN expr ';'              { $$ = mk_stmt (sRETURN, $2, NULL,
124                                                         NULL, NULL); }
125         | tSUB tSYMBOL '(' symbol_list ')' '{' locals stmt_list '}'
126                                         { $$ = mk_stmt (sDEFSUB, $2,
127                                                         cons (cons ($4, $7),
128                                                               $8),
129                                                         NULL, NULL); }
130         | '{' stmt_list '}'             { $$ = mk_stmt (sBLOCK, $2, NULL,
131                                                         NULL, NULL); }
132         | tIF '(' expr ')' stmt         { $$ = mk_stmt (sIF, $3, $5, NULL,
133                                                         NULL); }
134         | tIF '(' expr ')' stmt tELSE stmt
135                                         { $$ = mk_stmt (sIF, $3, $5, $7,
136                                                         NULL); }
137         | tWHILE '(' expr ')' stmt      { $$ = mk_stmt (sWHILE, $3, $5,
138                                                         NULL, NULL); }
139         | tFOR '(' cond_expr ';' expr ';' cond_expr ')' stmt
140                                         { $$ = mk_stmt (sFOR, $3, $5, $7,
141                                                         $9); }
142         | expr ';'                      { $$ = mk_stmt (sEXPR, $1, NULL,
143                                                         NULL, NULL); }
144         ;
145
146 expr    : tSTRING                       { $$ = mk_expr (eSTRING, $1, NULL,
147                                                         NULL); }
148         | tREGEXP                       { $$ = mk_expr (eREGEXP, $1, NULL,
149                                                         NULL); }
150         | tINTEGER                      { $$ = mk_expr (eINTEGER, $1, NULL,
151                                                         NULL); }
152         | tREAL                         { $$ = mk_expr (eREAL, $1, NULL,
153                                                         NULL); }
154         | tSYMBOL                       { $$ = mk_expr (eSYMBOL, $1, NULL,
155                                                         NULL); }
156         | '!' expr                      { $$ = mk_expr (eNOT, $2, NULL,
157                                                         NULL); }
158         | expr tAND expr                { $$ = mk_expr (eAND, $1, $3, NULL); }
159         | expr tOR expr                 { $$ = mk_expr (eOR, $1, $3, NULL); }
160         | tSYMBOL '(' expr_list ')'     { $$ = mk_expr (eFCALL, $1, $3,
161                                                         NULL); }
162         | tSYMBOL '=' expr              { $$ = mk_expr (eASSIGN, $1, $3,
163                                                         NULL); }
164         | tSYMBOL tADDASSIGN expr       { $$ = mk_expr (eADDASSIGN, $1, $3,
165                                                         NULL); }
166         | tSYMBOL tSUBASSIGN expr       { $$ = mk_expr (eSUBASSIGN, $1, $3,
167                                                         NULL); }
168         | tSYMBOL tMULASSIGN expr       { $$ = mk_expr (eMULASSIGN, $1, $3,
169                                                         NULL); }
170         | tSYMBOL tDIVASSIGN expr       { $$ = mk_expr (eDIVASSIGN, $1, $3,
171                                                         NULL); }
172         | tSYMBOL tPLUSPLUS             { $$ = mk_expr (ePOSTFIXADD, $1, NULL,
173                                                         NULL); }
174         | tSYMBOL tMINUSMINUS           { $$ = mk_expr (ePOSTFIXSUB, $1, NULL,
175                                                         NULL); }
176         | tPLUSPLUS tSYMBOL             { $$ = mk_expr (ePREFIXADD, $2, NULL,
177                                                         NULL); }
178         | tMINUSMINUS tSYMBOL           { $$ = mk_expr (ePREFIXSUB, $2, NULL,
179                                                         NULL); }
180         | expr '[' expr ']' '=' expr    { $$ = mk_expr (eARRAYASSIGN, $1, $3,
181                                                         $6); }
182         | '(' expr ')'                  { $$ = $2; }
183         | expr '[' expr ']'             { $$ = mk_expr (eARRAYREF, $1, $3,
184                                                         NULL); }
185         | expr '?' expr ':' expr        { $$ = mk_expr (eQUESTCOLON, $1, $3,
186                                                         $5); }
187         | expr '*' expr                 { $$ = mk_expr (eMULT, $1, $3, NULL); }
188         | expr tDIV expr                { $$ = mk_expr (eDIV, $1, $3, NULL); }
189         | expr '+' expr                 { $$ = mk_expr (ePLUS, $1, $3, NULL); }
190         | expr '-' expr                 { $$ = mk_expr (eMINUS, $1, $3,
191                                                         NULL); }
192         | expr '<' expr                 { $$ = mk_expr (eLT, $1, $3, NULL); }
193         | expr '>' expr                 { $$ = mk_expr (eGT, $1, $3, NULL); }
194         | expr tEQ expr                 { $$ = mk_expr (eEQ, $1, $3, NULL); }
195         | expr tNE expr                 { $$ = mk_expr (eNE, $1, $3, NULL); }
196         | expr tGE expr                 { $$ = mk_expr (eGE, $1, $3, NULL); }
197         | expr tLE expr                 { $$ = mk_expr (eLE, $1, $3, NULL); }
198         ;
199
200 cond_expr : /* empty */                 { $$ = NULL; }
201         | expr                          { $$ = $1; }
202         ;
203
204 expr_list : /* empty */                 { $$ = list (); }
205         | rest_expr_list                { $$ = $1; }
206         ;
207
208 rest_expr_list: expr                    { $$ = list (); list_append ($$, $1); }
209         | rest_expr_list ',' expr       { list_append ($1, $3); }
210         ;
211
212 %%
213
214 void
215 yyerror (msg)
216      char *msg;
217 {
218   fprintf (stderr, "%s:%d: %s\n", yyin_name, linenum, msg);
219 }