

lvalue). Por ejemplo en Kernighan y Ritchie C (KR C)
[11]
la asignación f(2,x) = 4 no es correcta pero si podría 
serlo *f(2,x) = 4.
En KR C las reglas
de producción que definen la parte izquierda de una asignación 
(lvalue) son mas complejas que las de SimpleC, especialmente 
por la presencia de punteros:
| Resumen de la Gramática de Kernighan y Ritchie C (KR C) en Parse::Eyapp | |
| Expresiones | Declaraciones | 
lvalue:
    identifier
  | primary '[' exp ']'
  | lvalue '.' identifier
  | primary '->' identifier
  | '*' exp
  | '(' lvalue ')'
primary:
    identifier
  | constant
  | string
  | (exp)
  | primary '(' exp <*, ','> ')'
  | primary '[' exp ']'
  | lvalue '.' identifier
  | primary '->' identifier
exp:
    primary
  | '*' exp
  | '&' exp
  | lvalue ASGNOP exp 
  ..........................
 | 
fund:
    t? dec '(' pr <* ','> ')' fb
declaration:
   scty * (dec ini) <* ','>
scty:
    scope 
  | t 
scope:
     tdef | ...
t:
    char
  | int
  | double
  | tdef_name    
  ...................
dec:
    identifier
  | '(' dec ')'
  | '*' dec
  | dec '(' ')'
  | dec '[' cexp ? ']'
ini:
    '=' exp
  | '=' '{' exp <* ','> ','? '}'
 | 
ASSIGN pasa
a ser ASSIGNINT o ASSIGNCHAR según sea el tipo de la asignación.
De este modo eliminamos la sobrecarga semántica del nodo y
hacemos explícito en el nodo el tipo de asignación. Poco a poco nos vamos acercando
a niveles mas bajos de programación. 
Sigue el código de comprobación para las asignaciones:
pl@nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/lib/Simple$ \
                         sed -ne '/^assign/,180p' Trans.trg | cat -n
 1  assign: /ASSIGN
 2           |PLUSASSIGN
 3           |MINUSASSIGN
 4           |TIMESASSIGN
 5           |DIVASSIGN
 6           |MODASSIGN
 7          /:asgn($lvalue, $exp)
 8    => {
 9      my $lt =  $lvalue->{t};
10      $exp = char2int($asgn, 1) if $lt == $INT;
11      $exp = int2char($asgn, 1) if $lt == $CHAR;
12
13        type_error("Incompatible types in assignment!", $asgn->line)
14      unless ($lt == $exp->{t});
15
16        type_error("The C language does not allow assignments to non-scalar types!", $asgn->line)
17      unless ($lt == $INT) or ($lt == $CHAR); # Structs will also be allowed
18
19      # Assignments are expressions. Its type is the type of the lhs or the rhs
20      $asgn->{t} = $lt;
21
22      # Make explicit the type of assignment, i.e.  s/PLUSASSIGN/PLUSASSIGNINT/
23      $asgn->type(ref($asgn).ref($lt));
24
25      return 1;
26    }
Veamos un ejemplo de comprobación de tipos en asignaciones:
pl@nereida:~/Lbook/code/Simple-Types/script$ usetypes.pl prueba12.c 2
1 int a,b[10][20],e[10][20];
2
3 int f(char c) {
4   e[5] = b[5];
5   a = b[1][2];
6 }
7
Type Error at line 4: The C language does not allow assignments to non-scalar types!

