Makefile.am (SUBDIRS): Move intl to be built before compat.
[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  * Enscript 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 3 of the License, or
15  * (at your option) any later version.
16  *
17  * Enscript 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 Enscript.  If not, see <http://www.gnu.org/licenses/>.
24  */
25
26 /*
27  * $Id: gram.y,v 1.1.1.1 2003/03/05 07:25:52 mtr Exp $
28  */
29
30 #include "defs.h"
31 %}
32
33 %union
34 {
35   List *lst;
36   Node *node;
37   Cons *cons;
38   Stmt *stmt;
39   Expr *expr;
40 }
41
42 %token <node> tSYMBOL tREGEXP tSTRING tINTEGER tREAL
43 %token tSUB tSTATE tSTART tSTARTRULES tNAMERULES tBEGIN tEND tRETURN tIF tELSE
44 %token tLOCAL tWHILE tFOR tEXTENDS
45
46 %right '=' tADDASSIGN tSUBASSIGN tMULASSIGN tDIVASSIGN
47 %right '?' ':'
48 %left tOR
49 %left tAND
50 %left tEQ tNE
51 %left '<' '>' tGE tLE
52 %left '+' '-'
53 %left '*' tDIV
54 %right '!' tPLUSPLUS tMINUSMINUS
55 %left '[' ']'
56
57 %type <lst> regexp_sym_list symbol_list rest_symbol_list staterules
58 %type <lst> stmt_list expr_list rest_expr_list locals locals_rest
59 %type <stmt> stmt
60 %type <expr> expr cond_expr
61 %type <cons> staterule local_def
62
63 %%
64
65 file    : /* empty */
66         | file toplevel
67         ;
68
69 toplevel : tSTART '{' stmt_list '}'     { start_stmts = $3; }
70         | tSTARTRULES '{' regexp_sym_list '}'
71                                         { startrules = $3; }
72         | tNAMERULES '{' regexp_sym_list '}'
73                                         { namerules = $3; }
74         | tSTATE tSYMBOL '{' staterules '}'
75                                         { define_state ($2, NULL, $4); }
76         | tSTATE tSYMBOL tEXTENDS tSYMBOL '{' staterules '}'
77                                         { define_state ($2, $4, $6); }
78         | stmt                          { list_append (global_stmts, $1); }
79         ;
80
81 regexp_sym_list : /* empty */           { $$ = list (); }
82         | regexp_sym_list tREGEXP tSYMBOL ';'
83                                         { list_append ($1, cons ($2, $3)); }
84         ;
85
86 staterules : /* empty */                { $$ = list (); }
87         | staterules staterule          { list_append ($1, $2); }
88
89 staterule : tBEGIN '{' stmt_list '}'    { $$ = cons (RULE_BEGIN, $3); }
90         | tEND '{' stmt_list '}'        { $$ = cons (RULE_END, $3); }
91         | tREGEXP '{' stmt_list '}'     { $$ = cons ($1, $3); }
92         | tSYMBOL '{' stmt_list '}'     { $$ = cons ($1, $3); }
93         ;
94
95 symbol_list : /* empty */               { $$ = list (); }
96         | rest_symbol_list              { $$ = $1; }
97         ;
98
99 rest_symbol_list : tSYMBOL              { $$ = list (); list_append ($$, $1); }
100         | rest_symbol_list ',' tSYMBOL  { list_append ($1, $3); }
101         ;
102
103 locals  : /* empty */                   { $$ = list (); }
104         | tLOCAL locals_rest ';'        { $$ = $2; }
105         ;
106
107 locals_rest : local_def                 { $$ = list (); list_append ($$, $1); }
108         | locals_rest ',' local_def     { list_append ($1, $3); }
109         ;
110
111 local_def : tSYMBOL                     { $$ = cons ($1, NULL); }
112         | tSYMBOL '=' expr              { $$ = cons ($1, $3); }
113         ;
114
115 stmt_list : /* empty */                 { $$ = list (); }
116         | stmt_list stmt                { list_append ($1, $2); }
117         ;
118
119 stmt    : tRETURN ';'                   { $$ = mk_stmt (sRETURN, NULL, NULL,
120                                                         NULL, NULL); }
121         | tRETURN expr ';'              { $$ = mk_stmt (sRETURN, $2, NULL,
122                                                         NULL, NULL); }
123         | tSUB tSYMBOL '(' symbol_list ')' '{' locals stmt_list '}'
124                                         { $$ = mk_stmt (sDEFSUB, $2,
125                                                         cons (cons ($4, $7),
126                                                               $8),
127                                                         NULL, NULL); }
128         | '{' stmt_list '}'             { $$ = mk_stmt (sBLOCK, $2, NULL,
129                                                         NULL, NULL); }
130         | tIF '(' expr ')' stmt         { $$ = mk_stmt (sIF, $3, $5, NULL,
131                                                         NULL); }
132         | tIF '(' expr ')' stmt tELSE stmt
133                                         { $$ = mk_stmt (sIF, $3, $5, $7,
134                                                         NULL); }
135         | tWHILE '(' expr ')' stmt      { $$ = mk_stmt (sWHILE, $3, $5,
136                                                         NULL, NULL); }
137         | tFOR '(' cond_expr ';' expr ';' cond_expr ')' stmt
138                                         { $$ = mk_stmt (sFOR, $3, $5, $7,
139                                                         $9); }
140         | expr ';'                      { $$ = mk_stmt (sEXPR, $1, NULL,
141                                                         NULL, NULL); }
142         ;
143
144 expr    : tSTRING                       { $$ = mk_expr (eSTRING, $1, NULL,
145                                                         NULL); }
146         | tREGEXP                       { $$ = mk_expr (eREGEXP, $1, NULL,
147                                                         NULL); }
148         | tINTEGER                      { $$ = mk_expr (eINTEGER, $1, NULL,
149                                                         NULL); }
150         | tREAL                         { $$ = mk_expr (eREAL, $1, NULL,
151                                                         NULL); }
152         | tSYMBOL                       { $$ = mk_expr (eSYMBOL, $1, NULL,
153                                                         NULL); }
154         | '!' expr                      { $$ = mk_expr (eNOT, $2, NULL,
155                                                         NULL); }
156         | expr tAND expr                { $$ = mk_expr (eAND, $1, $3, NULL); }
157         | expr tOR expr                 { $$ = mk_expr (eOR, $1, $3, NULL); }
158         | tSYMBOL '(' expr_list ')'     { $$ = mk_expr (eFCALL, $1, $3,
159                                                         NULL); }
160         | tSYMBOL '=' expr              { $$ = mk_expr (eASSIGN, $1, $3,
161                                                         NULL); }
162         | tSYMBOL tADDASSIGN expr       { $$ = mk_expr (eADDASSIGN, $1, $3,
163                                                         NULL); }
164         | tSYMBOL tSUBASSIGN expr       { $$ = mk_expr (eSUBASSIGN, $1, $3,
165                                                         NULL); }
166         | tSYMBOL tMULASSIGN expr       { $$ = mk_expr (eMULASSIGN, $1, $3,
167                                                         NULL); }
168         | tSYMBOL tDIVASSIGN expr       { $$ = mk_expr (eDIVASSIGN, $1, $3,
169                                                         NULL); }
170         | tSYMBOL tPLUSPLUS             { $$ = mk_expr (ePOSTFIXADD, $1, NULL,
171                                                         NULL); }
172         | tSYMBOL tMINUSMINUS           { $$ = mk_expr (ePOSTFIXSUB, $1, NULL,
173                                                         NULL); }
174         | tPLUSPLUS tSYMBOL             { $$ = mk_expr (ePREFIXADD, $2, NULL,
175                                                         NULL); }
176         | tMINUSMINUS tSYMBOL           { $$ = mk_expr (ePREFIXSUB, $2, NULL,
177                                                         NULL); }
178         | expr '[' expr ']' '=' expr    { $$ = mk_expr (eARRAYASSIGN, $1, $3,
179                                                         $6); }
180         | '(' expr ')'                  { $$ = $2; }
181         | expr '[' expr ']'             { $$ = mk_expr (eARRAYREF, $1, $3,
182                                                         NULL); }
183         | expr '?' expr ':' expr        { $$ = mk_expr (eQUESTCOLON, $1, $3,
184                                                         $5); }
185         | expr '*' expr                 { $$ = mk_expr (eMULT, $1, $3, NULL); }
186         | expr tDIV expr                { $$ = mk_expr (eDIV, $1, $3, NULL); }
187         | expr '+' expr                 { $$ = mk_expr (ePLUS, $1, $3, NULL); }
188         | expr '-' expr                 { $$ = mk_expr (eMINUS, $1, $3,
189                                                         NULL); }
190         | expr '<' expr                 { $$ = mk_expr (eLT, $1, $3, NULL); }
191         | expr '>' expr                 { $$ = mk_expr (eGT, $1, $3, NULL); }
192         | expr tEQ expr                 { $$ = mk_expr (eEQ, $1, $3, NULL); }
193         | expr tNE expr                 { $$ = mk_expr (eNE, $1, $3, NULL); }
194         | expr tGE expr                 { $$ = mk_expr (eGE, $1, $3, NULL); }
195         | expr tLE expr                 { $$ = mk_expr (eLE, $1, $3, NULL); }
196         ;
197
198 cond_expr : /* empty */                 { $$ = NULL; }
199         | expr                          { $$ = $1; }
200         ;
201
202 expr_list : /* empty */                 { $$ = list (); }
203         | rest_expr_list                { $$ = $1; }
204         ;
205
206 rest_expr_list: expr                    { $$ = list (); list_append ($$, $1); }
207         | rest_expr_list ',' expr       { list_append ($1, $3); }
208         ;
209
210 %%
211
212 void
213 yyerror (msg)
214      char *msg;
215 {
216   fprintf (stderr, "%s:%d: %s\n", yyin_name, linenum, msg);
217 }