expression.g 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /* EXPRESSIONS */
  2. {
  3. #include "debug.h"
  4. #include <assert.h>
  5. #include <em_arith.h>
  6. #include <em_label.h>
  7. #include "LLlex.h"
  8. #include "chk_expr.h"
  9. #include "def.h"
  10. #include "main.h"
  11. #include "node.h"
  12. #include "scope.h"
  13. #include "type.h"
  14. }
  15. Constant(register struct node **pnd;)
  16. {
  17. register struct node **nd = pnd;
  18. } :
  19. %default
  20. [
  21. Sign(nd) { nd = &((*nd)->nd_right); }
  22. ]?
  23. [ %default
  24. UnsignedNumber(nd)
  25. |
  26. ConstantIdentifier(nd)
  27. ]
  28. { (void) ChkConstant(*pnd); }
  29. |
  30. STRING { *pnd = MkLeaf(Value, &dot);
  31. if( ((*pnd)->nd_type = toktype) != char_type )
  32. RomString(*pnd);
  33. }
  34. ;
  35. Sign(register struct node **pnd;):
  36. ['+' | '-'] { *pnd = MkLeaf(Uoper, &dot); }
  37. ;
  38. UnsignedNumber(register struct node **pnd;):
  39. [INTEGER | REAL] { *pnd = MkLeaf(Value, &dot);
  40. if( ((*pnd)->nd_type = toktype) == real_type )
  41. RomReal(*pnd);
  42. }
  43. ;
  44. ConstantIdentifier(register struct node **pnd;):
  45. IDENT { *pnd = MkLeaf(Name, &dot); }
  46. ;
  47. /* ISO section 6.7.1, p. 121 */
  48. Expression(register struct node **pnd;):
  49. SimpleExpression(pnd)
  50. [
  51. /* RelationalOperator substituted inline */
  52. [ '=' | NOTEQUAL | '<' | '>' | LESSEQUAL | GREATEREQUAL | IN ]
  53. { *pnd = MkNode(Boper, *pnd, NULLNODE, &dot); }
  54. SimpleExpression(&((*pnd)->nd_right))
  55. ]?
  56. ;
  57. SimpleExpression(register struct node **pnd;):
  58. /* ISO 6.7.1: The signs and the adding-operators have equal precedence,
  59. and are left-associative.
  60. */
  61. [
  62. Sign(pnd)
  63. Term(&((*pnd)->nd_right))
  64. |
  65. Term(pnd)
  66. ]
  67. [
  68. /* AddingOperator substituted inline */
  69. [ '+' | '-' | OR ]
  70. { *pnd = MkNode(Boper, *pnd, NULLNODE, &dot); }
  71. Term(&((*pnd)->nd_right))
  72. ]*
  73. ;
  74. Term(register struct node **pnd;):
  75. Factor(pnd)
  76. [
  77. /* MultiplyingOperator substituted inline */
  78. [ '*' | '/' | DIV | MOD | AND ]
  79. { *pnd = MkNode(Boper, *pnd, NULLNODE, &dot); }
  80. Factor(&((*pnd)->nd_right))
  81. ]*
  82. ;
  83. Factor(register struct node **pnd;)
  84. {
  85. register struct def *df;
  86. } :
  87. /* This is a changed rule, because the grammar as specified in the
  88. * reference is not LL(1), and this gives conflicts.
  89. */
  90. %prefer /* solve conflicts on IDENT and UnsignedConstant */
  91. IDENT { *pnd = MkLeaf(Name, &dot); }
  92. [
  93. /* ISO section 6.7.3, p. 126
  94. * IDENT is a FunctionIdentifier
  95. */
  96. { *pnd = MkNode(Call, *pnd, NULLNODE, &dot); }
  97. ActualParameterList(&((*pnd)->nd_right))
  98. |
  99. /* IDENT can be a BoundIdentifier or a ConstantIdentifier or
  100. * a FunctionIdentifier (no parameterlist), in which case
  101. * VariableAccessTail is empty.
  102. * It could also be the beginning of a normal VariableAccess
  103. * (most likely).
  104. */
  105. { int class;
  106. df = lookfor(*pnd, CurrVis, 1);
  107. if( df->df_type->tp_fund & T_ROUTINE ) {
  108. /* This part is context-sensitive:
  109. is the occurence of the proc/func name
  110. a call or not ?
  111. */
  112. if( df->df_type == std_type )
  113. class = Call;
  114. else
  115. class = NameOrCall;
  116. *pnd = MkNode(class, *pnd, NULLNODE, &dot);
  117. (*pnd)->nd_symb = '(';
  118. }
  119. }
  120. VariableAccessTail(pnd)
  121. ]
  122. |
  123. UnsignedConstant(pnd)
  124. |
  125. SetConstructor(pnd)
  126. |
  127. '(' { /* dummy node to force ChkVariable */
  128. *pnd = MkLeaf(Uoper, &dot);
  129. }
  130. Expression(&((*pnd)->nd_right))
  131. ')'
  132. |
  133. NOT { *pnd = MkLeaf(Uoper, &dot); }
  134. Factor(&((*pnd)->nd_right))
  135. ;
  136. UnsignedConstant(register struct node **pnd;):
  137. UnsignedNumber(pnd)
  138. |
  139. STRING { *pnd = MkLeaf(Value, &dot);
  140. if( ((*pnd)->nd_type = toktype) != char_type )
  141. RomString(*pnd);
  142. }
  143. |
  144. ConstantIdentifier(pnd)
  145. |
  146. NIL { *pnd = MkLeaf(Value, &dot);
  147. (*pnd)->nd_type = nil_type;
  148. /* to evaluate NIL = NIL */
  149. (*pnd)->nd_INT = 0;
  150. }
  151. ;
  152. SetConstructor(register struct node **pnd;)
  153. {
  154. register struct node *nd;
  155. } :
  156. '[' { dot.tk_symb = SET;
  157. *pnd = nd = MkLeaf(Xset, &dot);
  158. }
  159. [
  160. MemberDesignator(nd)
  161. [ %persistent
  162. { nd = nd->nd_right; }
  163. ',' MemberDesignator(nd)
  164. ]*
  165. ]?
  166. ']'
  167. ;
  168. MemberDesignator(register struct node *nd;)
  169. {
  170. struct node *nd1;
  171. } :
  172. Expression(&nd1)
  173. [ UPTO { nd1 = MkNode(Link, nd1, NULLNODE, &dot); }
  174. Expression(&(nd1->nd_right))
  175. ]?
  176. { nd->nd_right = MkNode(Link, nd1, NULLNODE, &dot);
  177. nd->nd_right->nd_symb = ',';
  178. }
  179. ;
  180. /* ISO section 6.7.2.1, p. 123 */
  181. BooleanExpression(register struct node **pnd;):
  182. Expression(pnd)
  183. { if( ChkExpression(*pnd) &&
  184. (*pnd)->nd_type != bool_type )
  185. node_error(*pnd, "boolean expression expected");
  186. }
  187. ;
  188. ActualParameterList(register struct node **pnd;)
  189. {
  190. register struct node *nd;
  191. } :
  192. '('
  193. /* ActualParameter substituted inline */
  194. Expression(pnd) { *pnd = nd =
  195. MkNode(Link, *pnd, NULLNODE, &dot);
  196. nd->nd_symb = ',';
  197. }
  198. [ %persistent
  199. ',' { nd->nd_right = MkLeaf(Link, &dot);
  200. nd = nd->nd_right;
  201. }
  202. Expression(&(nd->nd_left))
  203. ]*
  204. ')'
  205. ;
  206. /* ISO section 6.5.1, p. 105 */
  207. VariableAccess(register struct node **pnd;):
  208. /* This is a changed rule, because the grammar as specified in the
  209. * reference is not LL(1), and this gives conflicts.
  210. *
  211. * IDENT is an EntireVariable or
  212. * a FieldDesignatorIdentifier (see also 6.8.3.10, p. 132).
  213. */
  214. IDENT { *pnd = MkLeaf(Name, &dot); }
  215. VariableAccessTail(pnd) { (void) ChkVariable(*pnd); }
  216. ;
  217. VariableAccessTail(register struct node **pnd;):
  218. /* This is a new rule because the grammar specified by the standard
  219. * is not exactly LL(1).
  220. */
  221. /* empty */
  222. |
  223. /* PointerVariable or FileVariable
  224. */
  225. '^' { *pnd = MkNode(Arrow, NULLNODE, *pnd, &dot); }
  226. /* At this point the VariableAccess is an IdentifiedVariable
  227. * ISO section 6.5.4, p. 107 (IdentifiedVariable: PointerVariable '^'),
  228. * or
  229. * it is a BufferVariable
  230. * ISO section 6.5.5, p. 107 (BufferVariable: FileVariable '^').
  231. */
  232. VariableAccessTail(pnd)
  233. |
  234. /* ArrayVariable
  235. */
  236. '[' { *pnd = MkNode(Arrsel, *pnd, NULLNODE, &dot); }
  237. /* IndexExpression substituted inline */
  238. Expression(&((*pnd)->nd_right))
  239. [ %persistent
  240. ',' { *pnd = MkNode(Arrsel, *pnd, NULLNODE, &dot);
  241. (*pnd)->nd_symb = '[';
  242. }
  243. Expression(&((*pnd)->nd_right))
  244. ]*
  245. ']'
  246. /* At this point the VariableAccess is an IndexedVariable
  247. * ISO section 6.5.3.2, p. 106
  248. */
  249. VariableAccessTail(pnd)
  250. |
  251. /* RecordVariable
  252. */
  253. '.' { *pnd = MkNode(Link, *pnd, NULLNODE, &dot); }
  254. /* FieldSpecifier & FieldIdentifier substituted inline */
  255. IDENT { (*pnd)->nd_IDF = dot.TOK_IDF; }
  256. /* At this point the VariableAccess is a FieldDesignator
  257. * ISO section 6.5.3.3, p. 107
  258. */
  259. VariableAccessTail(pnd)
  260. ;