123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- /* EXPRESSIONS */
- {
- #include "debug.h"
- #include <assert.h>
- #include <em_arith.h>
- #include <em_label.h>
- #include "LLlex.h"
- #include "chk_expr.h"
- #include "def.h"
- #include "main.h"
- #include "node.h"
- #include "scope.h"
- #include "type.h"
- }
- Constant(register struct node **pnd;)
- {
- register struct node **nd = pnd;
- } :
- %default
- [
- Sign(nd) { nd = &((*nd)->nd_right); }
- ]?
- [ %default
- UnsignedNumber(nd)
- |
- ConstantIdentifier(nd)
- ]
- { (void) ChkConstant(*pnd); }
- |
- STRING { *pnd = MkLeaf(Value, &dot);
- if( ((*pnd)->nd_type = toktype) != char_type )
- RomString(*pnd);
- }
- ;
- Sign(register struct node **pnd;):
- ['+' | '-'] { *pnd = MkLeaf(Uoper, &dot); }
- ;
- UnsignedNumber(register struct node **pnd;):
- [INTEGER | REAL] { *pnd = MkLeaf(Value, &dot);
- if( ((*pnd)->nd_type = toktype) == real_type )
- RomReal(*pnd);
- }
- ;
- ConstantIdentifier(register struct node **pnd;):
- IDENT { *pnd = MkLeaf(Name, &dot); }
- ;
- /* ISO section 6.7.1, p. 121 */
- Expression(register struct node **pnd;):
- SimpleExpression(pnd)
- [
- /* RelationalOperator substituted inline */
- [ '=' | NOTEQUAL | '<' | '>' | LESSEQUAL | GREATEREQUAL | IN ]
- { *pnd = MkNode(Boper, *pnd, NULLNODE, &dot); }
- SimpleExpression(&((*pnd)->nd_right))
- ]?
- ;
- SimpleExpression(register struct node **pnd;):
- /* ISO 6.7.1: The signs and the adding-operators have equal precedence,
- and are left-associative.
- */
- [
- Sign(pnd)
- Term(&((*pnd)->nd_right))
- |
- Term(pnd)
- ]
- [
- /* AddingOperator substituted inline */
- [ '+' | '-' | OR ]
- { *pnd = MkNode(Boper, *pnd, NULLNODE, &dot); }
- Term(&((*pnd)->nd_right))
- ]*
- ;
- Term(register struct node **pnd;):
- Factor(pnd)
- [
- /* MultiplyingOperator substituted inline */
- [ '*' | '/' | DIV | MOD | AND ]
- { *pnd = MkNode(Boper, *pnd, NULLNODE, &dot); }
- Factor(&((*pnd)->nd_right))
- ]*
- ;
- Factor(register struct node **pnd;)
- {
- register struct def *df;
- } :
- /* This is a changed rule, because the grammar as specified in the
- * reference is not LL(1), and this gives conflicts.
- */
- %prefer /* solve conflicts on IDENT and UnsignedConstant */
- IDENT { *pnd = MkLeaf(Name, &dot); }
- [
- /* ISO section 6.7.3, p. 126
- * IDENT is a FunctionIdentifier
- */
- { *pnd = MkNode(Call, *pnd, NULLNODE, &dot); }
- ActualParameterList(&((*pnd)->nd_right))
- |
- /* IDENT can be a BoundIdentifier or a ConstantIdentifier or
- * a FunctionIdentifier (no parameterlist), in which case
- * VariableAccessTail is empty.
- * It could also be the beginning of a normal VariableAccess
- * (most likely).
- */
- { int class;
- df = lookfor(*pnd, CurrVis, 1);
- if( df->df_type->tp_fund & T_ROUTINE ) {
- /* This part is context-sensitive:
- is the occurence of the proc/func name
- a call or not ?
- */
- if( df->df_type == std_type )
- class = Call;
- else
- class = NameOrCall;
- *pnd = MkNode(class, *pnd, NULLNODE, &dot);
- (*pnd)->nd_symb = '(';
- }
- }
- VariableAccessTail(pnd)
- ]
- |
- UnsignedConstant(pnd)
- |
- SetConstructor(pnd)
- |
- '(' { /* dummy node to force ChkVariable */
- *pnd = MkLeaf(Uoper, &dot);
- }
- Expression(&((*pnd)->nd_right))
- ')'
- |
- NOT { *pnd = MkLeaf(Uoper, &dot); }
- Factor(&((*pnd)->nd_right))
- ;
- UnsignedConstant(register struct node **pnd;):
- UnsignedNumber(pnd)
- |
- STRING { *pnd = MkLeaf(Value, &dot);
- if( ((*pnd)->nd_type = toktype) != char_type )
- RomString(*pnd);
- }
- |
- ConstantIdentifier(pnd)
- |
- NIL { *pnd = MkLeaf(Value, &dot);
- (*pnd)->nd_type = nil_type;
- /* to evaluate NIL = NIL */
- (*pnd)->nd_INT = 0;
- }
- ;
- SetConstructor(register struct node **pnd;)
- {
- register struct node *nd;
- } :
- '[' { dot.tk_symb = SET;
- *pnd = nd = MkLeaf(Xset, &dot);
- }
- [
- MemberDesignator(nd)
- [ %persistent
- { nd = nd->nd_right; }
- ',' MemberDesignator(nd)
- ]*
- ]?
- ']'
- ;
- MemberDesignator(register struct node *nd;)
- {
- struct node *nd1;
- } :
- Expression(&nd1)
- [ UPTO { nd1 = MkNode(Link, nd1, NULLNODE, &dot); }
- Expression(&(nd1->nd_right))
- ]?
- { nd->nd_right = MkNode(Link, nd1, NULLNODE, &dot);
- nd->nd_right->nd_symb = ',';
- }
- ;
- /* ISO section 6.7.2.1, p. 123 */
- BooleanExpression(register struct node **pnd;):
- Expression(pnd)
- { if( ChkExpression(*pnd) &&
- (*pnd)->nd_type != bool_type )
- node_error(*pnd, "boolean expression expected");
- }
- ;
- ActualParameterList(register struct node **pnd;)
- {
- register struct node *nd;
- } :
- '('
- /* ActualParameter substituted inline */
- Expression(pnd) { *pnd = nd =
- MkNode(Link, *pnd, NULLNODE, &dot);
- nd->nd_symb = ',';
- }
- [ %persistent
- ',' { nd->nd_right = MkLeaf(Link, &dot);
- nd = nd->nd_right;
- }
- Expression(&(nd->nd_left))
- ]*
- ')'
- ;
- /* ISO section 6.5.1, p. 105 */
- VariableAccess(register struct node **pnd;):
- /* This is a changed rule, because the grammar as specified in the
- * reference is not LL(1), and this gives conflicts.
- *
- * IDENT is an EntireVariable or
- * a FieldDesignatorIdentifier (see also 6.8.3.10, p. 132).
- */
- IDENT { *pnd = MkLeaf(Name, &dot); }
- VariableAccessTail(pnd) { (void) ChkVariable(*pnd); }
- ;
- VariableAccessTail(register struct node **pnd;):
- /* This is a new rule because the grammar specified by the standard
- * is not exactly LL(1).
- */
- /* empty */
- |
- /* PointerVariable or FileVariable
- */
- '^' { *pnd = MkNode(Arrow, NULLNODE, *pnd, &dot); }
- /* At this point the VariableAccess is an IdentifiedVariable
- * ISO section 6.5.4, p. 107 (IdentifiedVariable: PointerVariable '^'),
- * or
- * it is a BufferVariable
- * ISO section 6.5.5, p. 107 (BufferVariable: FileVariable '^').
- */
- VariableAccessTail(pnd)
- |
- /* ArrayVariable
- */
- '[' { *pnd = MkNode(Arrsel, *pnd, NULLNODE, &dot); }
- /* IndexExpression substituted inline */
- Expression(&((*pnd)->nd_right))
- [ %persistent
- ',' { *pnd = MkNode(Arrsel, *pnd, NULLNODE, &dot);
- (*pnd)->nd_symb = '[';
- }
- Expression(&((*pnd)->nd_right))
- ]*
- ']'
- /* At this point the VariableAccess is an IndexedVariable
- * ISO section 6.5.3.2, p. 106
- */
- VariableAccessTail(pnd)
- |
- /* RecordVariable
- */
- '.' { *pnd = MkNode(Link, *pnd, NULLNODE, &dot); }
- /* FieldSpecifier & FieldIdentifier substituted inline */
- IDENT { (*pnd)->nd_IDF = dot.TOK_IDF; }
- /* At this point the VariableAccess is a FieldDesignator
- * ISO section 6.5.3.3, p. 107
- */
- VariableAccessTail(pnd)
- ;
|