

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!

