123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* $Id$ */
- /* EXPRESSION SYNTAX PARSER */
- {
- #include "arith.h"
- #include "LLlex.h"
- #include "type.h"
- #include "idf.h"
- #include "label.h"
- #include "expr.h"
- #include "code.h"
- #include "noRoption.h"
- extern char options[];
- extern struct expr *intexpr();
- }
- /* 7.1 */
- primary(register struct expr **expp;) :
- IDENTIFIER
- {dot2expr(expp);}
- |
- constant(expp)
- |
- STRING
- {dot2expr(expp);}
- |
- '(' expression(expp) ')'
- {(*expp)->ex_flags |= EX_PARENS;}
- ;
- secundary(register struct expr **expp;) :
- primary(expp)
- [
- index_pack(expp)
- |
- parameter_pack(expp)
- |
- selection(expp)
- ]*
- ;
- index_pack(struct expr **expp;)
- {struct expr *e1;}
- :
- '[' expression(&e1) ']'
- {ch7bin(expp, '[', e1);}
- ;
- parameter_pack(struct expr **expp;)
- {struct expr *e1 = 0;}
- :
- '(' parameter_list(&e1)? ')'
- {ch7bin(expp, '(', e1);}
- ;
- selection(struct expr **expp;)
- {int oper; struct idf *idf;}
- :
- [ '.' | ARROW ]
- {oper = DOT;}
- identifier(&idf)
- {ch7sel(expp, oper, idf);}
- ;
- parameter_list(struct expr **expp;)
- {struct expr *e1 = 0;}
- :
- assignment_expression(expp)
- {any2opnd(expp, PARCOMMA);}
- [ %persistent
- ','
- assignment_expression(&e1)
- {any2opnd(&e1, PARCOMMA);}
- {ch7bin(expp, PARCOMMA, e1);}
- ]*
- ;
- /* 7.2 */
- postfixed(struct expr **expp;)
- {int oper;}
- :
- secundary(expp)
- [
- postop(&oper)
- {ch7incr(expp, oper);}
- |
- empty
- ]
- ;
- %first first_of_type_specifier, type_specifier;
- unary(register struct expr **expp;)
- {struct type *tp; int oper;}
- :
- %if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
- cast(&tp) unary(expp)
- { ch7cast(expp, CAST, tp);
- (*expp)->ex_flags |= EX_CAST;
- }
- |
- postfixed(expp)
- |
- unop(&oper) unary(expp)
- {ch7mon(oper, expp);}
- |
- size_of(expp)
- ;
- size_of(register struct expr **expp;)
- {struct type *tp;}
- :
- SIZEOF
- [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
- cast(&tp)
- {
- *expp = intexpr(size_of_type(tp, "type"), INT);
- (*expp)->ex_flags |= EX_SIZEOF;
- }
- |
- unary(expp)
- {ch7mon(SIZEOF, expp);}
- ]
- ;
- /* 7.3-7.12 */
- /* The set of operators in C is stratified in 15 levels, with level
- N being treated in RM 7.N. In principle each operator is
- assigned a rank, ranging from 1 to 15. Such an expression can
- be parsed by a construct like:
- binary_expression(int maxrank;)
- {int oper;}
- :
- binary_expression(maxrank - 1)
- [%if (rank_of(DOT) <= maxrank)
- binop(&oper)
- binary_expression(rank_of(oper)-1)
- ]?
- ;
- except that some call of 'unary' is necessary, depending on the
- grammar.
-
- This simple view is marred by three complications:
- 1. Level 15 (comma operator) is not allowed in many
- contexts and is different.
- 2. Level 13 (conditional operator) is a ternary operator,
- which does not fit this scheme at all.
- 3. Level 14 (assignment operators) group right-to-left, as
- opposed to 2-12, which group left-to-right (or are
- immaterial).
- 4. The operators in level 14 start with operators in levels
- 2-13 (RM 7.14: The two parts of a compound assignment
- operator are separate tokens.) This causes LL1 problems.
- This forces us to have four rules:
- binary_expression for level 2-12
- conditional_expression for level 13
- assignment_expression for level 14 and
- expression for the most general expression
- */
- binary_expression(int maxrank; struct expr **expp;)
- {int oper; struct expr *e1;}
- :
- unary(expp)
- [%while (rank_of(DOT) <= maxrank && AHEAD != '=')
- /* '?', '=', and ',' are no binops, and the test
- for AHEAD != '=' keeps the other assignment
- operators out
- */
- binop(&oper)
- binary_expression(rank_of(oper)-1, &e1)
- {
- ch7bin(expp, oper, e1);
- }
- ]*
- ;
- /* 7.13 */
- conditional_expression(struct expr **expp;)
- /* There is some unfortunate disagreement about what is allowed
- between the '?' and the ':' of a conditional_expression.
- Although the Ritchie compiler does not even allow
- conditional_expressions there, some other compilers (e.g., VAX)
- accept a full assignment_expression there, and programs
- (like, e.g., emacs) rely on it. So we have little choice.
- */
- {struct expr *e1 = 0, *e2 = 0;}
- :
- /* allow all binary operators */
- binary_expression(rank_of('?') - 1, expp)
- [ '?'
- expression(&e1)
- {
- #ifndef NOROPTION
- check_conditional(e1, '?', "between ? and :");
- #endif
- }
- ':'
- assignment_expression(&e2)
- {
- #ifndef NOROPTION
- check_conditional(e2, '=', "after :");
- #endif
- ch7bin(&e1, ':', e2);
- opnd2test(expp, '?');
- ch7bin(expp, '?', e1);
- }
- ]?
- ;
- /* 7.14 */
- assignment_expression(struct expr **expp;)
- {
- int oper;
- struct expr *e1 = 0;
- }
- :
- conditional_expression(expp)
- [%prefer /* (rank_of(DOT) <= maxrank) for any asgnop */
- asgnop(&oper)
- assignment_expression(&e1)
- {ch7asgn(expp, oper, e1);}
- |
- empty /* LLgen artefact ??? */
- ]
- ;
- /* 7.15 */
- expression(struct expr **expp;)
- {struct expr *e1;}
- :
- assignment_expression(expp)
- [ ','
- assignment_expression(&e1)
- {
- ch7bin(expp, ',', e1);
- }
- ]*
- ;
- unop(int *oper;) :
- ['*' | '&' | '-' | '!' | '~' | PLUSPLUS | MINMIN]
- {*oper = DOT;}
- ;
- postop(int *oper;):
- PLUSPLUS {*oper = POSTINCR;}
- |
- MINMIN {*oper = POSTDECR;}
- ;
- multop:
- '*' | '/' | '%'
- ;
- addop:
- '+' | '-'
- ;
- shiftop:
- LEFT | RIGHT
- ;
- relop:
- '<' | '>' | LESSEQ | GREATEREQ
- ;
- eqop:
- EQUAL | NOTEQUAL
- ;
- arithop:
- multop | addop | shiftop
- |
- '&' | '^' | '|'
- ;
- binop(int *oper;) :
- [ arithop | relop | eqop | AND | OR ]
- {*oper = DOT;}
- ;
- asgnop(register int *oper;):
- '=' {*oper = DOT;}
- |
- '+' '=' {*oper = PLUSAB;}
- |
- '-' '=' {*oper = MINAB;}
- |
- '*' '=' {*oper = TIMESAB;}
- |
- '/' '=' {*oper = DIVAB;}
- |
- '%' '=' {*oper = MODAB;}
- |
- LEFT '=' {*oper = LEFTAB;}
- |
- RIGHT '=' {*oper = RIGHTAB;}
- |
- '&' '=' {*oper = ANDAB;}
- |
- '^' '=' {*oper = XORAB;}
- |
- '|' '=' {*oper = ORAB;}
- ;
- constant(struct expr **expp;) :
- [
- INTEGER
- |
- FLOATING
- ] {dot2expr(expp);}
- ;
- /* 15 */
- constant_expression (struct expr **expp;) :
- assignment_expression(expp)
- {chk_cst_expr(expp);}
- ;
- identifier(struct idf **idfp;) :
- [
- IDENTIFIER
- |
- TYPE_IDENTIFIER
- ]
- {
- *idfp = dot.tk_idf;
- }
- ;
|