--------- COP C-like
compiler for NXT lego ROBOT -------
28th of August 2007
– v1.2

-
partial enrichment of the “programming
guide”
-
optimized management of library, only functions
that are called are generated
-
enrichment of the sound library
-
several bugs are fixed, see : 11 – Fixed bugs
-
all error messages
are now translated in English
-
entire translation of the GUI in English
_________________________________________________________________________________________________________________________________________________________
Find in this WEB page, explanations about a C-like COP compiler
dedicated to the NXT Lego ROBOT.
I have started this project 6 months ago, and I have not enough time to work on it,
so it is still an ongoing project J
To be quite honest, I have not built any robots, and my son ( 5 years
old ) looks at the mountain of pieces and asks :“Daddy, when are you building
this robot ?” and
I always answer : “When this compiler is finished !”. I guess he doesn’t
understand why.
Sources of this compiler are free, that is to say that anybody can
reuse, and modify this compiler. I don’t know if this compiler can be useful
for other people ...
To help other developers, this web page intends to give enough
information to make this compiler a reusable source.
This WEB page and compiler are beta-versions, many remaining issues are
to be completed, especially :
-
a complete specification of code patterns
-
lot of bugs to be
discovered !!! J
-
automated generation of code to allocate memory
for arrays
-
a complete library
-
a library dedicated to mathematic function to
be developed
-
and so many other stuffs like that
Find below explanations concerning this compiler and files to be
downloaded.
Do not hesitate to send me an email to reports bugs of the compiler and
or any comments on this web page to :
![]()
__________________________________________________________________________________________________________________________________________________________
Web sites :
Lego WEB site :
http://mindstorms.lego.com/Overview/NXT_Software.aspx
Extensions of NXT :
http://www.philohome.com/nxt.htm
National Instrument tool kit :
http://www.ni.com/academic/mindstorms/
A Web site where you can purchase NXT robots :
http://www.robopolis.com/produit/2474/20/Robots-programmables/MINDSTORMS-NXT-V41.php
NBC compiler, which is the code generated by COP compiler
:
http://bricxcc.sourceforge.net/nbc/
An assembly language fot NXT :
http://users.ece.utexas.edu/~valvano/assmbly/syntax.htm
More sensors for NXT :
Robots developed for computer science training course, in the
http//www.irisa.fr/caps/people/puaut/Mindstorm/TPMindstorm.html#TP4
Bricx Command Center
3.3 :
http://bricxcc.sourceforge.net/nbc/
NBC Debugger :
http://nxtasy.org/2006/11/29/nbc-debugger-for-nxt/
Other tools :
http://www.lysator.liu.se/~nisse/lego-nxt-dev/
Debugger for NXT :
http://www.sorosy.com/lego/nxtdbg/
Forum :
French Forum
: http://www.vieartificielle.com/forum/
English/American Forum : http://thenxtstep.com/forums.html
French WEB site dedicated
to LEGO : http://www.freelug.org/
English/American Forum : http://forums.nxtasy.org
Lego Forum :
http://messageboards.lego.com/ShowForum.aspx?ForumID=1042
POB-Technology, a company
dedicated to robots : http://pob-technology.com/
__________________________________________________________________________________________________________________________________________________________
4- Grammar implemented
in COP compiler
-
6.1 Principles
-
6.2 Data
model
-
6.3 Lexical parsing
-
6.4 Syntax parsing
1.
Principles
4.
Comments on the syntax parsing in
the COP compiler
2.
Dedicated grammar for operators
3.
Mapping between rules and C
functions
-
6.5 Code generation
1.
Principles
:
2.
Mapping between C structures and
code generation functions :
10 – Download section : sources, files and executable
__________________________________________________________________________________________________________________________________________________________
For X-mas, I
got a Lego NXT robot. As I am a lazy guy, I do not want to code NBC
instructions. So I decided to write my own C-like compiler which generates NBC
codes. For people which are familiar with the C language syntax, I guess they
won’t be destabilized by COP compiler.
This
compiler is fully open, it means that you can enrich it in term of functions or
data or enrich its library as well, C sources are downloadable.
As I am not
a very good programmer, the C code is not commented ( few comments are in
French ) but in section 5, I try to give enough information for a better
understanding. Moreover, I have fixed a huge number of bugs, but I am quite
sure there are still lot of bugs to be
discovered and fixed. Do not hesitate to report bugs.
This
compiler is compiled with lcc compiler ( http://www.cs.virginia.edu/~lcc-win32/
) and use an external library (dislin : http://www.mps.mpg.de/dislin/).
To complete
this introduction, as you can read ( see ) , I am
French and English is not my native language, so do not hesitate to report me
all misunderstandings due to my poor
English.
__________________________________________________________________________________________________________________________________________________________
The
installation is quite simple :
1) Create a
directory named “COP” and copy “cop.exe” in this directory (
see executable file )
2) Create a
sub-directory named “source”
3) Create a
sub-directory of
“source” named “lib” and copy all library files in this directory (see 6 - Libraries )
4) If you
want to use COP source examples, copy these files in the “source” directory ( see 7 - Example of
COP sources )
5) Create
you own COP sources in the “source” directory.
The
directory tree must look as below :
COP --+
+ cop.exe
+ source -- +
+ COP files eg. essai_librairie_def.cop.txt
+ lib -- +
Or download
the package : 10 – Download section : sources,
files and executable
__________________________________________________________________________________________________________________________________________________________
The use of
COP compiler is quite simple.
The only
thing you have to do is to execute cop.exe.
Below this
window will be displayed :

The
selection of the “exit” menu will end
the program.
The
selection of the “help” menu will show you the current version of COP compiler.
The
selection of file will offer you a dedicated window to select the cop file you
want to compile.
The
following options are offered :
- Syntax Parsing traces : if
selected, the entire syntax parsing is traced in the text window.
- Syntax tree, types and variables :
if selected, the entire syntax tree which is the result of the parsing step is
displayed in the text window.
- Code generation traces : If
selected, traces will be added in the target .nbc file.
- Automatic generation mutex : If
selected, mutexes are automatically declared and invoked to protect accesses to
all functions.
To compile
the only thing you have to do, is to press the “OK” button.
_____________________________________
COP Compiler v.1.2 / 28 th August 2007
Author : Olivier POURCHER
_____________________________________
PASS #1 : pre-processing ( defines lexical
parsing of define completed
Lexical parsing of define completed :
D:\DELTA\lcc1\source\essai_sound.cop.txt - 68 lines
Lexical parsing of define completed :
lib\display.cop.lib.txt - 123 lines
Lexical parsing of define completed :
lib\file.cop.lib.txt - 118 lines
Lexical parsing of define completed :
lib\motor.cop.lib.txt - 115 lines
Lexical parsing of define completed :
lib\sensor.cop.lib.txt - 181 lines
Lexical parsing of define completed :
lib\sound.cop.lib.txt - 154 lines
Lexical parsing of define completed :
lib\string.cop.lib.txt - 55 lines
Lexical parsing of define completed :
lib\system.cop.lib.txt - 74 lines
PASS #1 : Successfully completed / 117
'defines' parsed
PASS #2 : Lexical parsing of libraries and
module to be compiled
Lexical parsing completed :
lib\display.cop.lib.txt - 123 lines
Lexical parsing completed :
lib\file.cop.lib.txt - 118 lines
Lexical parsing completed :
lib\motor.cop.lib.txt - 115 lines
Lexical parsing completed :
lib\sensor.cop.lib.txt - 181 lines
Lexical parsing completed :
lib\sound.cop.lib.txt - 154 lines
Lexical parsing completed :
lib\string.cop.lib.txt - 55 lines
Lexical parsing completed :
lib\system.cop.lib.txt - 74 lines
PASS #2 : Successfully completed
PASS #2 : Lexical parsing completed :
D:\DELTA\lcc1\source\essai_sound.cop.txt
- 68 lines
PASS #3 : Syntax parsing of libraries and
module to be compiled
End of parsing of global variables
-------> module lib\file.cop.lib.txt line
31 ::
[Warning
Error #SX0675: Types not compatible in expression ] token = )
-------> module lib\file.cop.lib.txt line
39 ::
[Warning
Error #SX0675: Types not compatible in expression ] token = )
End of parsing of functions and tasks
compiled line = 68
# of types =12
# of variables = 89
# of functions = 47
# of tasks = 1
PASS #3 : Successfully completed
PASS #3 : Syntax parsing completed
D:\DELTA\lcc1\source\essai_sound.cop.txt - total compiled lines = 888
PASS #4 : Code generation of libraries (only
those called) and module to be compiled
Code generation completed
D:\DELTA\lcc1\source\essai_sound.cop.txt
PASS #4 : Successfully completed
Press a key to terminate
D:\DELTA\lcc1\source\essai_sound.cop.txt
__________________________________________________________________________________________________________________________________________________________
Find below
a description of the grammar of the COP language.
<Program>
-> [ <define declaration> |
<struct declaration> | <variable declarations>| <mutex
declarations> | <function> |
<task> ]0..n
<define
declaration> -> define <ident>
<text>
<struct
declaration> -> struct {
< field definition >1..n };
<field
definition> -> <type> <list of fields>
<list of
fields> -> <field> ,
<list of fields> | <field> ;
<field>
-> [*]0|1
<ident> [ [<integer>] ]
0..n
<variable
declarations> -> <type> <list of variables>
<list of
variables> -> <variable> ,
<list of variables> | <field> ;
<variable> -> [*]0|1 <ident> [ [<integer>] ] 0..n
[= <init>]0|1
<init> -> <numeric value> | <string>
<type> -> char
| schar |
byte | int | sint
| long | slong | <ident type>
<list of
mutex> -> <mutex> ,
<list of mutex> | <mutex> ;
<
mutex> -> mutex <ident>
<ident
type> -> <generic ident >
<ident
> -> <generic ident >
<function>
-> <ident> ( <list of
parameters> ) < body > |
< return value > <ident> (
<list of parameters> | void ) < body >
<list of
parameters> -> <list of
parameters> ,<parameter>
| <parameter>
<parameter>
-> [ mod ] 0|1 <type> [*]0|1 <ident>
<return
value> -> void |
<type>
<task>
-> task <ident> (
) < body >
<body>
-> { [<variable
declarations>] 0|1 [<instruction>]0..n
}
<instruction>
-> <assignment> |
<for loop> |
<do while loop> |
<if then else> |
<switch> |
<goto> |
<label> |
<continue> |
<break> |
<exit> |
<return> |
<acquire> |
<release> |
<precedes> |
<arrinit> |
<arrsize> |
<arrbuild> |
<arrsubset> |
<inline> |
< function call> ;
<assignment>
-> [ [*( <ident> + <expr> ) | <ident assign> ] [=
<expr> ; ] 0|1 | <ident>
++; | <ident> -- ;
<for
loop> -> for ( [
<affectation> ] 0..1 ;
[<expr>] 0..1 ; <affectation> ] 0..1 ) <body instruction>
<do
while loop> -> do { [<instruction>]0..n
}
while ( <expr> ) ;
<if then
else> -> if ( <expr> ) <body instruction> [ else <body instruction> ] 0..1
<switch>
-> switch ( <expr> ) { [< switch
body>]0..1 }
<switch
body> -> case <expr> : [<body instruction>] 0..1 [break ; ]
0..1 |
default
: [<body instruction>] 0..1
<goto>
-> goto <ident> ;
<label>
-> <ident> :
<continue>
-> continue ;
<break>
-> break ;
<exit> -> exit ( ) ;
<return>
-> return ( expr ) ;
<acquire>
-> acquire ( <ident> ) ;
<release>
-> release ( <ident> ) ;
<precedes>->
precedes <list of tasks> ;
<list of
tasks> -> <list of tasks> , <ident>
| <ident>
<arrinit>
-> arrsubset ( <ident>, <expr>,
<expr> ) ;
<arrsize>
-> arrssize ( <ident>, <ident>
) ;
<arrbuild>
-> arrsbuild ( <list of arrays> ) ;
<list of
arrays> -> <list of arrays> , <ident>
| <ident>
<arrsubset> -> arrsubset ( <ident>, <ident>, <expr>, <expr> ) ;
<inline> -> inline “<text>” ;
<body instruction> -> { [<instruction>]0..n
}
|
<instruction>
<expr> -> [ <expr rec ou> ] 0..1
<expr rec ou> -> <expr rec et> | <expr rec et> || <expr rec ou>
<expr rec et> -> <expr rec comp> | <expr rec comp> && <expr rec et>
<expr rec comp> -> <expr rec arith> | <expr rec arith> [ ==| != | >| <| <=| >= ] <expr rec comp>
<expr rec arith> -> <expr rec> | <expr rec> [ + | - | | ] <expr rec arith>
<expr rec> -> <expr rec shr shl> | <expr rec shr shl> [ & | / | * | % ] <expr rec>
<expr rec shr shl> -> <expr rec not> | <expr rec not > [ >> | << ] <expr rec shr shl >
<expr
rec not> -> <expr rec
neg> | !
<expr rec neg >
<expr
rec neg> -> <expr rec
atom> | - <expr rec atom
>
<expr
rec atom> -> <atom> |
<var func> | (<expr rec
ou> )
<var
func> - > <ident assign>| <function call>
<ident
assign>-> <ident> |
<ident> ++
; |
<ident> -- ;
|
<ident> [ . <ident
assign> ] 1..n |
<ident> [ [<expr> ]
] 1..n
<function
call> -> <ident> ( [< list of function parameters>]0..1 )
< list
of function parameters> -> < list of function parameters> , <expr> | <expr>
<atom>
-> <numeric value> | <string>
<generic
ident > -> [a..z] | [A..Z] [[a..z] | [A..Z] | [0..9] | _
] 0..n
<string>
-> ”[all
ASCII code] 0..n”
<numeric
value> -> <binary> | <hexa> | <decimal>
<binary>
-> 0b [0|1]
1..n
<hexa>
-> 0x [ [0|1]
| [ [A..F] | [a..f] ] ]
1..n
<decimal>->
[0..9] [0..9] 1..n
<text>
-> [all ASCII code] 0..n
__________________________________________________________________________________________________________________________________________________________
A COP
program contains at least one task which is called ‘main’.
This is the entry point of the program. Several tasks can be defined and
launched, see precedes.
These tasks
can be executed in parallel.
Below an
example of program :
task tache1()
{
}
task tache2()
{
}
task main()
{
precedes
tache1,tache2;
}
A COP
program can contain several functions. Some of these functions are defined in
libraries, eg. COP_wait() and cannot be double defined.
As they are
not really local variables ( they are emulated by the COP compiler ),
mutex can be automatically generated at complie time to have a one and only one
call at a given time.
A function is composed of 4 parts : < return value > <ident>
( <list
of parameters>) < body >
- type
of returned value, if exists :
- the type can be void
if no value are returned
- the type can be an
atomic ‘type’ or structure
- identifier
of the function
- parameters
- parameters can be
passed by value or can be modified ( mod
)
- body
of the function
- the body contains a
set of instruction and local variables ( see variables )
Example1
:
void ffff()
{
}
task main()
{
ffff();
}
example
2 :
int abcdefgh ()
{
return(1);
}
task main()
{
int v;
v=abcsdefgh();
}
example
3 :
struct
COORD
{
int x;
int y;
};
struct LINE
{
COORD ext1;
COORD ext2;
};
int ff(mod int g, int k,mod int x,mod COORD z)
{
int a,b,c,d:
g=1;
x = 0;
z.x=1;
z.y=2;
}
task main()
{
int a,b,c;
LINE line1;
COORD point;
c=ff(a,b,line.ext1.x,point);
}
Cop program
can define data types and structures.
Atoms :
byte
unsigned 8 bits
char unsigned 8 bits
schar signed 8 bits
int unsigned 16 bits
sint signed 16 bits
long unsigned 32 bits
slong signed 32 bits
<type> -> char
| schar |
byte | int | sint
| long | slong | <ident type>
Nota : float is not available, this type is not supported by the NXT. I am
writing a library dedicated to “float” an mathematic functions ( cos, sin, …
).
Nota : bollean type doesn’t exist, but can be replaced by a byte variable, 0
is ‘FALSE’, all other values (>0) are ‘TRUE’.
Pointers:
Pointers
are used to handle arrays which are passed as ‘reference’ parameters in
function.
<parameter> -> [ mod
] 0|1 <type> [*]0|1
<ident>
Arrays :
Arrays are
scalar types. Arrays can be applied to atom or structures. Arrays can be
multi-dimensional, COP compiler support up to 10 dimensions.
These
dimensions are used to address the exact memory location.
Strings are
defined as arrays of
char, eg. char String[10].
Strings must be terminated by a null byte.
<variable> -> [*]0|1 <ident> [ [<integer>] ] 0..n
[= <init>]0|1
Nota : If arrays are passed by ‘reference’ in a called, they must be then used
as pointer in the called function.
Structures :
A structure
is set of fields which are gathered into a one and only one structure. A structure
can contains, atoms, arrays, structures or arrays of structures.
<struct declaration> -> struct
{ < field definition >1..n };
<field definition> -> <type> <list of
fields>
<list of fields> -> <field> , <list of fields> | <field> ;
<field> -> [*]0|1 <ident> [ [<integer>] ] 0..n
Example
1 :
struct COORD
{
int x;
int y;
};
struct LINE
{
COORD
ext1;
COORD ext2;
};
LINE line[10];
void
assign(mod int d,int s)
{
d=s;
}
void
init_line(mod LINE *l,int index, int x1, int y1,int
x2,int y2)
{
LINE
v;
assign(v.ext1.x,x1);
assign(v.ext1.y,y1);
v.ext2.x=x2;
v.ext2.y=y2;
*(l+index)=v;
}
task main()
{
int x;
int valeur;
char buffer[10];
LINE v;
inline "arrinit
globale_line,0 , 10";
COP_DrawText(1,1,"INIT");
COP_Wait(1000);
x=0;
do
{
init_line(line,x,1,x,60,60-x);
x++;
}
while(x<10);
for(x=0;x<10;x++)
{
v=line[x];
COP_LineOut(v.ext1.x, v.ext1.y, v.ext2.x, v.ext2.y, 1);
COP_Wait(1000);
}
COP_DrawText(1,1,"FIN");
COP_Wait(1000);
COP_LineOut(1, 1, 20, 20, 1);
COP_Wait(5000);
}
to be
completed
to be
completed
to be
completed
The if instruction
follows this pattern: if (
<expr> ) <body
instruction> [ else <body
instruction> ] 0..1
if (a==b)
k=0;
example
2 :
if (a==b)
{
k=0;
d=1;
}
example
3 :
if (a==b)
{
k=0;
d=1;
}
else
{
k=1;
d=0;
}
The for instruction
follows this pattern: for ( [
<affectation> ] 0..1 ;
[<expr>] 0..1 ; <affectation> ] 0..1 ) <body instruction>
The for
loop is divided into 3 :
-
initial value
-
logical expression which stops the loop if
equal to false, eg. if i =5, (i<4) is evaluated as FALSE
-
incrementation, this assignement change values of variable which are
part of the logical expression
The ‘break’ instruction ‘jumps’ to next instruction
which follows the for loop.
The ‘continue’ instruction ‘jumps’ to the beginning of
the for loop but executes the incremental instructions.
example
1 :
task main()
{
int a;
char chaine[10];
int inv;
for(a=0;a<10;a++)
{
if(inv==1)
{
inv=1-inv;
continue;
}
inv=1-inv;
}
/* test 2 */
for(a=0;;a++)
{
if(a>5) break;
}
/* test 3 */
a=0;
for(;;)
{
if(a>5) break;
a++;
}
The do/while instruction
follows this pattern: <do while loop> -> do { [<instruction>]0..n
}
while ( <expr> ) ;
The while loop evaluate a logical expression which stops the loop if
equal to FALSE, eg. x<10
The ‘break’ instruction ‘jumps’ to next instruction
which follows the for do/while loop.
The ‘continue’ instruction ‘jumps’ to the beginning of
the do/while loop but executes the incremental instructions.
example 1 :
task main()
{
int x;
int
valeur;
char buffer[10];
COP_DrawText(1,1,"AFFICHAGE");
COP_Wait(1000);
x=0;
do
{
COP_NumtoString(x,buffer);
COP_DrawText(1,1,buffer);
COP_Wait(1000);
x++;
}
while(x<10);
COP_DrawText(1,1,"FIN");
COP_Wait(1000);
}
return
is use to return value ( amazing ! ). Return can only be used in functions
which return values.
return
can contain complex expression, but the return type must comply with the
declared type of the function.
example 1 :
int f(int a,int x,int b)
{
return(a*x+b);
}
task main()
{
int x;
int
valeur;
char buffer[10];
COP_DrawText(1,1,"AFFICHAGE");
COP_Wait(1000);
x=0;
do
{
valeur=f(2,x,3);
COP_NumtoString(valeur,buffer);
COP_DrawText(1,1,buffer);
COP_Wait(1000);
x++;
}
while(x<10);
COP_DrawText(1,1,"FIN");
COP_Wait(1000);
}
to be
completed
to be
completed
to be
completed
to be
completed
to be
completed
label
and goto are used to jump to a given instruction of the program.
God of
programmers never uses the goto instruction, using goto is strictly forbidden ( even in the toilet J).
Obviously ,
to program a goto, a label must be declared in the code.
<goto> -> goto <ident> ;
<label> -> <ident> :
example 1 :
/**/
/**/
/**/
/*******************************/
/* this
function opens file in */
/* read or
write mode */
/*******************************/
byte
COP_Fopen(char *name,char *mode)
{
inline "dseg
segment";
inline "FO
TFileOpen";
inline "expr_g_byte_tab_COP_Fopen
byte[]";
inline "expr_d_byte_tab_COP_Fopen
byte[]";
inline "expr_g_byte_COP_Fopen
byte";
inline "expr_d_byte_COP_Fopen
byte";
inline "expr_byte_tab_COP_Fopen
byte[]";
inline "inc_COP_Fopen
word";
inline "dseg
ends";
if(mode=="w")
{
inline "mov FO.Filename, COP_Fopen_name";
inline "mov FO.Length, 100";
inline "syscall FileOpenWrite, FO";
inline "mov expr_byte_COP_Fopen, FO.FileHandle";
goto end_fopen;
}
if(mode=="r")
{
inline "mov FO.Filename, COP_Fopen_name";
inline "mov FO.Length, 100";
inline "syscall FileOpenRead, FO";
inline "mov expr_byte_COP_Fopen, FO.FileHandle";
}
end_fopen:
}
inline
is a very simple and powerful instruction. It can be used to directly low level
nbc instructions.
‘inline’ is also massively used in libraries to make the link
between COP functions and nbc libraries.
<inline> -> inline “<text>” ;
Nota : the text between the two quotes is not parsed.
example 1 :
/**/
/**/
/**/
/*******************************/
/* this
function opens file in */
/* read or
write mode */
/*******************************/
byte
COP_Fopen(char *name,char *mode)
{
inline "dseg segment";
inline "FO TFileOpen";
inline "expr_g_byte_tab_COP_Fopen byte[]";
inline "expr_d_byte_tab_COP_Fopen byte[]";
inline "expr_g_byte_COP_Fopen byte";
inline "expr_d_byte_COP_Fopen byte";
inline "expr_byte_tab_COP_Fopen byte[]";
inline "inc_COP_Fopen word";
inline "dseg ends";
if(mode=="w")
{
inline "mov FO.Filename,
COP_Fopen_name";
inline "mov FO.Length, 100";
inline "syscall
FileOpenWrite, FO";
inline "mov
expr_byte_COP_Fopen, FO.FileHandle";
goto end_fopen;
}
if(mode=="r")
{
inline "mov FO.Filename,
COP_Fopen_name";
inline "mov FO.Length, 100";
inline "syscall
FileOpenRead, FO";
inline "mov
expr_byte_COP_Fopen, FO.FileHandle";
}
end_fopen:
}
to be
completed
__________________________________________________________________________________________________________________________________________________________
The C code
is made of 4 C files (see 9 –
Download section : sources, files and executable)
:
- cop.c : this is the heart of COP
compiler, this module contains the entry point of the program ( main ) and the
calls of the four passes.
- lexical.c : this module focuses on
the lexical parsing pass and pre-processing pass
- syntaxique.c : this module focuses
on the syntax parsing pass
- genere_code.c : this module
focuses on the code generation pass
- delta_encrier.h : this header
contains C structures and defines used by COP compiler.
The COP
compiler is a 4 passes compiler :
- 1) pre-processing pass, which
identifies all defines
- 2) a lexical parsing pass
- 3) a syntax parsing pass
- 4) a code generation pass

Above, a
schema which illustrates flows and main functions of the COP compilers.
The first
pass, pre-processing, parses all files and
stores all defines ( #define
<ident> text ).
ð it generates a table
of defines
ð file : lexical.c
ð entry point : cop.c :
o
pre-processing : analyse_lexicale_define()
The second
pass, lexical parsing, parses all files
and identifies a flow of lexem ( +, -,
<ident>, for, if, else … ), if an <ident> is detected and if
this <ident> is a ‘define’, it is replaced by its value.
ð it generates a table
of lexems
ð file : lexical.c
ð entry point : cop.c : analyse_lexicale()
The third
pass, syntax parsing, parses the list of
lexems according to the grammar rules specified in the chapter 4- Grammar implemented in COP
compiler.
ð it generates table of
structures, table of variables, table of functions, table of tasks, tables of
instructions. Those table can be considered as a syntax tree.
ð file : syntaxique.c
ð entry point : cop.c : analyse_syntaxique()
The fourth
pass, code generation, generates the NBC
codes by analysing the syntax tree.
=> it generates a NBC target file
ð file : genere_code.c
ð entry point : generation_de_code()
In the next
chapters, main data, and each pass is
explained in detailed.
Below the
data model of the COP compiler.

This table
comments the data model :
|
Structure |
Array/variable |
Index |
Semantic |
Display/debug
function |
|
PROGRAM |
PROGRAM program; |
|
This
variable contains the Variable_globales array. The
principle is that even if we are facing to a local variable of a function or
a task, variables are stored in the same table. To find the relevant
variable, first, we always try to find it in the function or task and if it
is not defined at this level, we assume that it is a global variable. |
void analyse_syntaxique(void) printf("\n LISTE DES
VARIABLES "); for(i=0;i<program.nb_vg;i++) { printf("\n\n#################################\n VARIABLE
%d",i); affiche_variable(i); } |
|
TACHE |
TACHE tab_tache[MAX_TACHE]; |
int nb_tache; |
This
table contains the list of task that are defined in the program. |
void analyse_syntaxique(void) for(i=0;i<nb_tache;i++) { printf("\n\n#################################\n TACHE %d '%s'
nb_instruction %d",i,tab_tache[i].ident_tache,tab_tache[i].nb_instruction); affichage_instruction(tab_tache[i].liste_instruction); } |
|
FONCTION |
FONCTION tab_fonction[MAX_FONCTION]; |
int nb_fonction; |
This
table contains the list of function that are defined in the program |
void analyse_syntaxique(void) printf("\n LISTE DES
INSTRUCTIONS "); for(i=0;i<nb_fonction;i++) { printf("\n\n#################################\n
FONCTION %d '%s' nb_instruction %d
",i,tab_fonction[i].ident_fonction,tab_fonction[i].nb_instruction); affichage_instruction(tab_fonction[i].liste_instruction); } |
|
VARIABLE_GLOBALE |
See
PROGRAM |
|
This
structure models variable, both global and local variables. |
void affiche_variable(int index) |
|
TYPE_VARIABLE |
TYPE_VARIABLE tab_type_variable[MAX_TYPE_VARIABLE]; |
int
nb_tab_type_variable; |
This
structure models types of variables. A type of variable can be : - atom ( #define ATOME 1 ) - array ( #define TABLEAU 2 ) - array of structure ( #define
TABLEAU_STRUCTURE 4 ) - structure ( #define STRUCTURE 2) - field of a structure ( #define CHAMP 5
) This is a
recursive structure. The void init_type_variable(char
*prof_bloc) function defines atom types such as int, char, byte, long, sint,
char, sbyte, slong … |
void affiche_type(TYPE_VARIABLE *type,int prof) |
|
INSTRUCTION |
INSTRUCTION tab_instruction[MAX_INSTRUCTION]; |
int
nb_instruction; |
This
structure models a list of atomic instructions such as an assignment, a for
loop … |
void affichage_instruction(INSTRUCTION *inst) |
|
INSTRUCTION_ELT |
|
|
This
union models an atomic instructions such as an assignment, a for loop, an if,
… |
|
|
SEXPRESSION |
|
|
This
structure models binary expression, in other words a node of a binary tree
which contains an operator and 2 or 1 argument. Example, < +,
sub-exp1,sup-exp2> or <not,sub-exp1,null > or a leaf (feuille in
French ). |
void affichage_recursif(SEXPRESSION *exp) |
|
FEUILLE |
|
|
This
union models leaf of tree, which be really a leaf such an integer, a string …
but can also be a call of function which contains arguments which are also
modelled as expression trees ( eg. f(1+2,3*4 ) ) … but can also be an array
variable which contains dimensions which are also modelled as expression
trees ( tab[2][f(3-2)][tab1[j*3]] … |
See void affichage_recursif(SEXPRESSION *exp) |
|
SATOME |
|
|
This structure models a real leaf of an expression tree, it means that it cannot be decomposed. Eg. integer value = 1968 |
|
|
SPOINTEUR |
|
|
This
structure models indirection of a pointer. |
|
|
SVARIABLE |
|
|
This
structure models variables which can be simple variable such as i or j, or
scalar variable such as array ( t[2][i] ) or structures ( a.b.c ). |
|
|
SFONCTION |
|
|
This
structure models call of function such as
f(1+2,3*4 ) |
|
|
SAFFECTATION |
|
|
This
structure models an assignment of a
variable. |
See void affichage_instruction(INSTRUCTION *inst) |
|
SIF |
|
|
This
structure models the « if » instruction. |
void affiche_inst_if(INSTRUCTION *inst) |
|
SFOR |
|
|
This
structure models the « for » instruction. |
void affiche_inst_for(INSTRUCTION *inst) |
|
SBLOC |
|
|
|
|
|
SSWITCH |
|
|
This
structure models the « switch » instruction. |
See void affichage_instruction(INSTRUCTION *inst) |
|
SDO_REPEAT |
|
|
This
structure models the « do while » instruction. |
void affiche_inst_do_while(INSTRUCTION *inst) |
|
SRETURN |
|
|
This
structure models the « return » instruction. |
See void affichage_instruction(INSTRUCTION *inst) |
|
SARRSIZE |
|
|
This
structure models the « arrsize » instruction. |
See void affichage_instruction(INSTRUCTION *inst) |
|
SARRINIT |
|
|
This
structure models the « arrinit » instruction. |
See void affichage_instruction(INSTRUCTION *inst) |
|
SARRSUBSET |
|
|
This
structure models the « arrsubset » instruction. |
See void affichage_instruction(INSTRUCTION *inst) |
|
SARRBUILD |
|
|
This
structure models the « arrbuild » instruction. |
See void affichage_instruction(INSTRUCTION *inst) |
|
SPRECEDE |
|
|
This
structure models the « precede » instruction. |
See void affichage_instruction(INSTRUCTION *inst) |
|
TAB_MUTEX |
TAB_MUTEX tab_mutex[MAX_MUTEX]; |
int
nb_mutex; |
This
structure models mutex ( semaphore ). |
void analyse_syntaxique(void) for(i=0;i<nb_mutex;i++) { printf("\n\n#################################\n MUTEX %d \n ident
='%s' module '%s' ligne '%d' ", i tab_mutex[i].ident, tab_mutex[i].module, tab_mutex[i].ligne); } |
|
TAB_DEFINE |
TAB_DEFINE tab_define[MAX_DEFINE]; |
int nb_define; |
This
structure models defines that are processed during the lexical analysis
pre-processing. See Pre-processing pass : |
|
|
ECHANT |
ECHANT *Techant; |
long
nb_echant; |
This
structure models a lexem, it means an elementary token of the COP language,
such as LFOR, LBEGIN (“{“ ), LEND (“=” ), see Lexical
parsing : |
|

The entry
point is the lexical.c :: analyse_lexicales_define()
function.This function calls the lecture_donnees_define()
function.
The lecture_donnees_define() function opens the
file to be parsed, calls a line after line parsing function named analyse_fichier_ligne_a_ligne_define(), and
then closes the file.
The analyse_fichier_ligne_a_ligne_define(), parses
line after line the file and store defines in the tab_define[]
array ( nb_define is the index ) by
invoking the ajout_define() function (
ajout = add in English ).

The lexical
parsing is far more complex.
Before
commenting in detail the C code, below a summary of the lexical parsing
principle.
The lexical
parsing analyses a flow of ASCII characters and generates a flow of lexems.
A lexem is
:
- a
keyword : for,
task , while, define,
break … are keywords
- an integer : 123, 0xfffff, 0b0110110 … are
integers
- a string : « hello world » …
is a string
- an ident : variable_identifier, i, j … are
idents
- separators : , ; { } ( ) … are seprators
- operators : + - / * == != .. are operators
All ASCII
characters between /* ignored ASCII charecters and */ are ignored. /* */ is used for comments.
All ASCII
such as CarriageReturn, Line Feed, Tab … are ignored.
In theory,
lexems to be recognized can me modelled as a state machine. The principle is to
recognize the longer string as possible.
Below a
simplified state machine for the COP language :

In this
state machine, there are states and arrows between states. “Start” is the
initial state. LBEGIN, LEND, LENTIER … are “end” states. The current ASCII
character is the key used to determine the relevant transition between two
states. Actually, in COP compiler, this state machine is hard-coded.
The entry
point is the lexical.c :: analyse_lexicales()
function.This function calls the lecture_donnees()
function.
The lecture_donnees() function opens the file to be
parsed, calls a line after line parsing function named analyse_fichier_ligne_a_ligne(), and then
closes the file.
The analyse_fichier_ligne_a_ligne(), parses line
after line the file, skips comments ( /* */ ) and recognized lexems ans stores
them in the Techant[] array ( nb_echant is the index ).
Example for
LBEGIN which is the lexem attached to {
:
if(buff[index]=='{')
{
#ifdef
TESTLEX
printf("
{ [%d] ",nb_echant);
#endif
Techant[nb_echant].type_lexeme=LBEGIN;
strcpy(Techant[nb_echant].lexeme,"{");
Techant[nb_echant].num_ligne=ligne_lu;
strcpy(Techant[nb_echant].module,nom_fic);
nb_echant++;
index++;
goto
fin;
}
Example for
LCOMPEG which is the lexem attached to == :
/*
LEG 31 /* = */
/*
LCOMPEG 20 /* == */
if(buff[index]=='=')
{
if(buff[index+1]=='=')
{
#ifdef
TESTLEX
printf("
== [%d] ",nb_echant);
#endif
Techant[nb_echant].type_lexeme=LCOMPEG;
strcpy(Techant[nb_echant].lexeme,"==");
Techant[nb_echant].num_ligne=ligne_lu;
strcpy(Techant[nb_echant].module,nom_fic);
index=index+2;
nb_echant++;
goto
fin;
}
else
{
#ifdef
TESTLEX
printf("
= [%d] ",nb_echant);
#endif
Techant[nb_echant].type_lexeme=LEG;
strcpy(Techant[nb_echant].lexeme,"=");
Techant[nb_echant].num_ligne=ligne_lu;
strcpy(Techant[nb_echant].module,nom_fic);
index++;
nb_echant++;
goto
fin;
}
}
Example for LIF which is the lexem attached to if :
if( ((buff[index]>='a')&&(buff[index]<='z'))
||
((buff[index]>='A')&&(buff[index]<='Z'))
)
{
char
chaine_tempo[1000];
int
k;
k=0;
for(;(
((buff[index]>='a')&&(buff[index]<='z')) ||
((buff[index]>='A')&&(buff[index]<='Z'))
||
((buff[index]>='0')&&(buff[index]<='9')) ||
(buff[index]=='_'))
;)
{
chaine_tempo[k]=buff[index];
k++;index++;
}
chaine_tempo[k]='\0';
/* LIF 21 /* if */
if(strcmp("if",chaine_tempo)==0)
{
#ifdef TESTLEX
printf("
IF %s [%d] ",chaine_tempo,nb_echant);
#endif
Techant[nb_echant].type_lexeme=LIF;
strcpy(Techant[nb_echant].lexeme,chaine_tempo);
Techant[nb_echant].num_ligne=ligne_lu;
strcpy(Techant[nb_echant].module,nom_fic);
nb_echant++;
goto
fin;
}/*if*/
In
this compiler, the following list of lexems are implemented :
#define
LBEGIN 0 /*{ */
#define
LEND 1 /* } */
#define
LFOR 2 /* for */
#define
LWHILE 3 /* while */
#define
LDO 4 /* do */
#define
LTASK 5 /* task */
#define
LSUBROUTINE 6 /* subroutine */
#define
LIDENT 7 /*identifier */
#define
LENTIER 8 /* int */
#define
LCHAR 24 /* char */
#define
OCTET 26 /* byte */
#define
LFLOTTANT 25 /* float */
#define
CHAINE 9 /* chaine = string*/
#define
LPV 10 /* ; */
#define
LV 11 /* , */
#define
LPLUS 12 /* + */
#define
LMOINS 13 /* - */
#define
LMUL 14 /* * */
#define
LDIV 15 /* / */
#define
LEG 31 /* = */
#define
LOP 32 /* ( */
#define
LCL 33 /* ) */
#define
LCOMPINF 16 /* < */
#define
LCOMPSUP 17 /* > */
#define
LCOMPINFEG 18 /* <= */
#define
LCOMPSUPEG 19 /* >= */
#define
LCOMPEG 20 /* == */
#define
LIF 21 /* if */
#define
LELSE 22 /* else */
#define
LRETURN 23 /* return */
#define
LCONTINUE 27 /* continue */
#define
LBREAK 28 /* break */
#define
LSWITCH 29 /* switch */
#define
LCASE 30 /* case */
#define
LDP 34 /* : */
#define
LET 35 /* & */
#define
LOU 36 /* | */
#define
LCOMPET 37 /* && */
#define
LCOMPOU 38 /* || */
#define
LNON 39 /* ! */
#define
LADDR 40 /* & */
#define
LCROP 41 /*[*/
#define
LCRCL 42 /* ] */
#define
LCHIFFREENT 43 /* 123
*/
#define
LCHIFFRREEL 44 /*123.52 */
#define
LOPCOMM 45 /* /* */
#define
LCLCOMM 46 /* */
#define
LPOINT 47 /* . */
#define
LSTRUCT 48 /* struct */
#define
LEXIT 49 /* exit */
#define
LVOID 50 /* LVOID */
#define
LINC 51 /* ++ */
#define
LDEC 52 /* -- */
#define
LGOTO 53 /* goto */
#define
LCOMPDIFF 54 /* != */
#define
LINDIRECT 55 /* -> */
#define
LSIZEOF 56 /* sizeof */
#define
LDEFAULT 57 /* default */
#define
LMODULO 58 /* % */
#define
LSCHAR 59 /* schar */
#define
LSINT 60 /* sint */
#define
LLONG 61 /* long */
#define
LSLONG 62 /* slong */
#define
LSHL 63 /* << */
#define
LSHR 64 /* >> */
#define
LPRECEDES 65 /* precedes */
#define
LMODIFY 66 /* mod */
#define
LINLINE 67 /* inline */
#define
LNEG 68 /* moins unaire */
#define
LMUTEX 69 /* semaphore mutex */
#define
LACQUIRE 70 /* acquire */
#define
LRELEASE 71 /* release */
#define
LARRSIZE 72 /* arrsize */
#define
LARRINIT 73 /* arrinit */
#define
LARRSUBSET 74 /* arrsubset */
#define
LARRBUILD 75 /* arrbuild */
The
syntax parsing is far far more complex
than the two previous steps …
Before
commenting in detail the C code, below a summary of the parsing principles.
The syntax
parsing analyses a flow of lexems
character and generates a syntax tree.

In theory,
there are different types of languages, some of them can be modelled by using
state machine, eg. LALR(2) state machine.
Smart
programmers use yacc tool ( yet another compiler compiler ) to generate
automatically state machines.
As I am not
a smart guy, I have chosen to program my own syntax parser by using a simple
“functional” parser. In a nutshell, a functional parser associates a function
per “grammar rules”.
The stack
which saves contexts is handled by the compiler itself and is managed by the
micro-processor during the execution.
Below an
example of syntax parsing of the “for” instruction : <for loop> -> for ( [ <affectation> ] 0..1 ; [<expr>] 0..1 ;
<affectation> ] 0..1 )
<body instruction>

Example :
<bloc>
-> { <sint> }
<sint>
-> <inst> | <inst> <sinit>
<inst>
-> <if> | <assign> | <func call>
<assign>
-> <ident> = <exp>;
<func
call> -> <ident> ();
<if>
-> if <expr> <bloc>
<exp>
-> <comp> | <func call exp>
| 1
<comp>
-> <ident> ==
<ident>
<func
call exp> -> <ident> ()
The
top-down approach is based on the fact that the grammar rule to be
recognized is chosen first, in other words, before having read all the
tokens. That’s why in some cases, backtrack is required if ambiguous choice
between several grammar rules occur.
If we
consider a top-down approach , this grammar is modelled as follow :

Example of
parsing :
{
if ( i=j) {g();k=1;}
}
Below the
stack at each step of the parsing process :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
|
1 |
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
) |
) |
|
|
= |
= |
= |
|
|
|
|
|
|
|
|
|
|
|
|
|
= |
( |
( |
( |
|
Ident “k” |
Ident “k” |
Ident “k” |
Ident “k” |
|
|
|
|
|
|
|
|
|
|
|
|
Ident “g” |
Ident “g” |
Ident “g” |
Ident “g” |
Ident “g” |
inst |
inst |
inst |
inst |
inst |
|
|
|
|
|
|
|
ident |
ident |
|
|
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
|
|
|
|
|
|
== |
== |
== |
|
) |
) |
) |
) |
) |
) |
) |
) |
) |
) |
) |
) |
|
|
|
|
|
ident “i” |
ident “i” |
ident “i” |
ident “i” |
exp |
exp |
exp |
exp |
exp |
exp |
exp |
exp |
exp |
exp |
exp |
exp |
exp |
|
|
|
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
|
|
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
if |
|
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
{ |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inst |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inst |
sinst |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
) |
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exp |
exp |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
( |
( |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if |
if |
inst |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
{ |
{ |
bloc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The
bottom-up approach is based on the fact
that the grammar rule to be recognized is reduced after a complete recognition
of the right part of the “grammar rule”, e.g <A> ->
<atome> () is reduced only
if <atom> and () have been
previously recognized. In some cases, there are conflicts between rules to be
reduced or reduce/shift (reading ).
Example :
<bloc>
-> { <sint> }
<sinst>
-> <inst> | <inst> <sinst>
<inst>
-> <if> | <assign> | <func call>
<assign>
-> <ident> = <exp>;
<func
call> -> <ident> ();
<if>
-> if <expr> <bloc>
<exp>
-> <comp> | <func call exp>
<comp>
-> <ident> ==
<ident>
<func
call exp> -> <ident> ()
If we
consider a bottom-up approach , this grammar is modelled by an LR(0), as follow
: ( I’ve processed this state machine by hand, and it is not very easy … )

table of
the LR(0) parser :
S : Shift :
Read the current token ( lexem )
R : Reduce
|
State |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
|
<bloc> |
|
|
|
R <bloc>->{<sinst>} |
R <inst>-><assign> |
R <inst>-><if> |
R <inst>-><func
call> |
|
|
|
|
R <func
call>-><ident>(); |
S/26 |
|
|
R <exp>-<comp> |
<exp>-><func
call exp> |
|
|
|
<comp>-><ident>
== <ident> |
<func
call exp>-> <ident>() |
|
R <sinst>-><inst><sinst> |
R <assign>-><ident>=<expr>; |
R <if>->if<expr><bloc> |
|
<assign> |
|
S/5 |
|
|
S/5 |
|
|
|
|
|
|
|
|
|
||||||||||||
|
<if> |
|
S/6 |
|
|
S/6 |
|
|
|
|
|
|
|
|
|
||||||||||||
|
<sinst> |
|
S/3 |
|
|
S/24 |
|
|
|
|
|
|
|
|
|
||||||||||||
|
<inst> |
|
S/9 |
|
|
S/
9 ( <sint>
-> .<inst> <sint> ) R/9
(<sint> -> <inst>.) Conflict Use ‘}’to make the right choice |
|
|
|
|
|
|
|
|
|
||||||||||||
|
<func
call> |
|
S/7 |
|
|
S/7 |
|
|
|
|
|
|
|
|
|
||||||||||||
|
<comp> |
|
|
|
|
|
|
|
|
S/16 |
S/16 |
|
|
|
|
||||||||||||
|
<func
call exp> |
|
|
|
|
|
|
|
|
S/17 |
S/17 |
|
|
|
|
||||||||||||
|
<expr> |
|
|
|
|
|
|
|
|
S/23 |
S/13 |
|
|
|
|
||||||||||||
|
<ident> |
|
S/8 |
|
|
S/8 |
|
|
|
S/18 |
S/18 |
|
S/21 |
|
|
||||||||||||
|
( |
|
|
|
S/10 |
|
|
|
|
|
|
S/20 |
|
|
|
||||||||||||
|
) |
|
|
|
|
|
S/11 |
|
|
|
|
|
|
S/22 |
|
||||||||||||
|
{ |
S/2 |
|
|
|
|
|
|
S/2 |
|
|
|
|
|
|
||||||||||||
|
} |
|
|
S/4 |
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
; |
|
|
|
|
|
|
S/12 |
|
|
|
|
|
|
S/25 |
||||||||||||
|
= |
|
|
|
S/14 |
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
== |
|
|
|
|
|
|
|
|
|
|
S/19 |
|
|
|
||||||||||||
|
if |
|
S/15 |
|
|
S/15 |
|
|
|
|
|
|
|
|
|
This type
of state machine engenders conflicts :
-
Shift / Reduce conflicts
-
Reduce/Reduce conflicts
To solve
conflicts, there is a simple method which consists in determining the next
token to be read in order to choose the relevant action to be processed. For
example to choose between “shitfing” <inst> in the rule <sint>
-> .<inst> <sint> or reducing <sint> -> <inst>., you may say that if the following token is “}” you reduce
else you shift. But in some cases this method do not solve the problem, more
powerful state machines must then be used.
The LR
parsing algorithm now works as follows:
1. The stack is initialized
with [0]. The current state will always be the state that is at the top
of the stack.
2. Given the current state and
the current terminal on the input stream an action is looked up in the action
table. There are four cases:
o
a shift sn:
§
the current terminal is removed from the input stream
§
the state n is pushed onto the stack and becomes the current state
o
a reduce rm:
§
the number m is written to the output stream
§
for every symbol in the right-hand side of rule m a state is removed
from the stack
§
given the state that is then on top of the stack and the left-hand side of
rule m a new state is looked up in the goto table and made the new
current state by pushing it onto the stack
o
an accept: the string is accepted
o
no action: a syntax error is reported
3. Step 2 is repeated until
either the string is accepted or a syntax error is reported.
Below an
execution of the algorithm according to the table of action.
Example of
parsing :
{
if i=j {g();k=f();}
}
|
Reduction |
|
|
|
|
|
<comp>
-> <ident> ==
<ident> |
|
<exp>
-> <comp> |
|
|
|
|
|
|
<func
call exp> -> <ident> () |
|
<inst>
-> <func call> |
|
|
Token |
{ |
if |
Ident |
== |
Ident |
{ |
{ |
{ |
{ |
{ |
Ident |
( |
) |
; |
; |
Ident |
Ident |
Ident |
|
State |
1 |
2 |
15 |
18 |
19 |
21 |
15 |
16 |
15 |
13 |
2 |
8 |
10 |
11 |
12 |
2 |
7 |
2 |
|
Action |
S/2 |
S/15 |
S/18 |
S/19 |
S/21 |
R |
S/16 |
R |
S/13 |
S/2 |
S/8 |
S/10 |
S/11 |
S/12 |
R |
S/7 |
R |
R |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;12 |
;12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
);11 |
);11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(;10 |
(;10 |
(;10 |
|
|
|
|
|
|
|
|
|
Ident- |
Ident- |
|
|
|
|
|
Ident-g;8 |
Ident-g;8 |
Ident-g;8 |
Ident-g;8 |
<fun call>;12 |
<fun call>;12 |
<inst>;7 |
|
|
|
|
|
==;18 |
==;18 |
==;18 |
|
|
|
|
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
|
|
|
|
Ident- I;15 |
Ident- |
Ident- |
Ident- |
<comp>;15 |
<comp>;15 |
<exp>;15 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
|
|
|
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
|
|
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
|
Reduction |
|
|
|
|
|
|
<func
call exp> -> <ident> () |
|
<exp>
-> <func call exp> |
|
|
<assign>
-> <ident> = <exp>; |
|
<inst>
-> <assign> |
<sinst>
-> <inst> |
|
|
Token |
Ident |
Ident |
= |
Ident |
( |
) |
; |
; |
; |
; |
; |
} |
} |
} |
} |
} |
|
State |
2 |
9 |
8 |
14 |
18 |
20 |
22 |
14 |
17 |
14 |
23 |
25 |
9 |
5 |
9 |
9 |
|
Action |
S/9 |
S/8 |
S/14 |
S/18 |
S/20 |
S/22 |
R |
S/17 |
R |
S/23 |
S25 |
R |
S/5 |
R |
R |
S/24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
);20 |
);20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(;18 |
(;18 |
(;18 |
|
|
|
|
;;25 |
|
|
|
|
|
|
|
|
|
Ident;14 |
Ident;14 |
Ident;14 |
Ident;14 |
<Func all exp>;14 |
<Func all exp>;14 |
<exp>;14 |
<exp>;14 |
<exp>;14 |
|
|
|
|
|
|
|
|
=;8 |
=;8 |
=;8 |
=;8 |
=;8 |
=;8 |
=;8 |
=;8 |
=;8 |
=;8 |
|
|
|
|
|
|
|
Ident;9 |
Ident;9 |
Ident;9 |
Ident;9 |
Ident;9 |
Ident;9 |
Ident;9 |
Ident;9 |
Ident;9 |
Ident;9 |
Ident;9 |
<assign>;9 |
<assign>;9 |
<inst>;9 |
<sinst>;9 |
|
|
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
<inst>;2 |
|
|
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
{;2 |
|
|
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
|
|
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
|
|
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
|
Reduction |
<sinst>
-> <inst> <sinst> |
|
|
<bloc>
-> { <sint> } |
|
<if>
-> if <expr>
<bloc> |
|
<inst>
-> <if> |
|
<sinst>
-> <inst> |
|
|
<bloc>
-> { <sint> } |
|
|
|
|
Token |
} |
} |
} |
} |
} |
} |
} |
} |
} |
} |
} |
void |
|
|
|
|
|
State |
2 |
2 |
3 |
4 |
13 |
26 |
2 |
2 |
2 |
9 |
2 |
3 |
|
|
|
|
|
Action |
R |
S/3 |
S/4 |
R |
S/26 |
R |
S/6 |
R |
S/9 |
R |
S/3 |
S/4 |
R |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<sinst>;2 |
<sinst>;2 |
<sinst>;2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{;2 |
{;2 |
{;2 |
<bloc>;13 |
<bloc>;13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
<exp>;13 |
|
|
|
|
|
|
};4 |
|
|
|
|
|
|
If;2 |
If;2 |
If;2 |
If;2 |
If;2 |
<i>;2 |
<if>;2 |
<inst>;2 |
<inst>;2 |
<sinst>;2 |
<sinst>;2 |
<sinst>;2 |
|
|
|
|
|
|
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
{;1 |
<bloc> |
|
|
|
As you can
seen, the bottom-up approach is far more complex than the top-down
approach, and for my COP compiler I have chosen the simplest solution.
As seen
above, the simplest way to parse simple grammar is to use the top-down
approach.
The
principle of implementation in the COP compiler is to associate a C function to
each grammar rule.
The lire_token() function returns in the token string the value of the token ( eg.
for LIDENT, the value of the identifier ), and the type_token the type of the token ( eg.
LFOR ).
In case of
conflict between 2 or more C functions to call, eg. “assignment” or “function
call”, backtrack mechanism is put in place and the retour_arriere() function is used to
position the current token to the appropriate lexem to be read.
Example for
the <for loop> -> for ( [
<affectation> ] 0..1 ;
[<expr>] 0..1 ; <affectation> ] 0..1 ) <body instruction> :
In red,
error which are detected, eg. message_erreur("Erreur
Fatale #S0130 :: ( attendue ") is raised
if the parenthesis after “for” is missing.
In orange,
calls to analysis of rules :
-
analyse_affectation(bloc_prof,type_pointeur_var); is called to parse the
assignment in the rule for(<assignement>… )
-
analyse_expression(bloc_prof); is called to parse the rule in the rule
“for(<assignement>;<expression>;… )”
INSTRUCTION
* analyse_for(char *bloc_prof)
{
SEXPRESSION *exp1;
SAFFECTATION *aff1,*aff2;
INSTRUCTION *inst;
INSTRUCTION *inst_r;
/*SFOR *sfor;*/
monte();
boucle++;
if(traceaff==1) printf("\n%s : for (token constatee
=%s;;)",affiche,token);
/* consommation du ( */
cr=lire_token();
if(cr==-1)
message_erreur("\n Erreur Fatale #S0129 :
fin prématuré du fichier source dans l'instruction for(;;) ");
if(traceaff==1) printf("\n%s : token lu apres le
for =%s",affiche,token);
if(type_token!=LOP)
message_erreur("Erreur
Fatale #S0130 :: ( attendue ");
/* analyse de l'affectation du for(xxx;;) */
cr=lire_token();
if(cr==-1)
message_erreur("\n
Erreur Fatale #S0131 : fin prématuré du fichier source dans l'instruction
for(;;) ");
if(type_token!=LPV)
{
int type_pointeur_var;
type_pointeur_var=TYP_PTR_VAR_NORMAL;
if(type_token==LMUL)
{
if(traceaff==1)
printf("\n X %s * detectee",affiche);
cr=lire_token();
if(cr==-1)
message_erreur("\n Erreur Fatale #S0132 : fin prématuré
du fichier source dans l'expression ");
type_pointeur_var=TYP_PTR_VAR_POINTEUR;
if(type_token==LMUL)
{
if(traceaff==1)
printf("\n Z %s ** detectee",affiche);
cr=lire_token();
if(cr==-1)
message_erreur("\n Erreur Fatale #S0133 : fin prématuré
du fichier source dans l'expression ");
type_pointeur_var=TYP_PTR_VAR_POINTEUR_POINTEUR;
}
}
aff1=analyse_affectation(bloc_prof,type_pointeur_var);
} /* patch
else aff1=NULL;
if(type_token!=LPV)
message_erreur("Erreur
Fatale #S0134 :: ; attendue ");
/* consommation du ; */
cr=lire_token();
if(cr==-1)
message_erreur("\n
Erreur Fatale #S0135 : fin prématuré du fichier source dans l'instruction
for(;;) ");
/* analyse de l'affectation du for(;xxx;) */
if(type_token!=LPV)
exp1=analyse_expression(bloc_prof); /* l'expression peut
être vide */
/*
patch
else exp1=NULL;
if(type_token!=LPV)
message_erreur("Erreur
Fatale #S0136 :: ; attendue ");
/* consommation du ; */
cr=lire_token();
if(cr==-1)
message_erreur("\n
Erreur Fatale #S0137 : fin prématuré du fichier source dans l'instruction
for(;;) ");
/* analyse de l'affectation du for(;;xxx) */
if(type_token!=LCL)
{
int type_pointeur_var;
type_pointeur_var=TYP_PTR_VAR_NORMAL;
if(type_token==LMUL)
{
if(traceaff==1)
printf("\n X %s * detectee",affiche);
cr=lire_token();
if(cr==-1)
message_erreur("\n Erreur Fatale #S0138 : fin prématuré
du fichier source dans l'expression ");
type_pointeur_var=TYP_PTR_VAR_POINTEUR;
if(type_token==LMUL)
{
if(traceaff==1)
printf("\n Z %s ** detectee",affiche);
cr=lire_token();
if(cr==-1)
message_erreur("\n Erreur
Fatale #S0139 : fin prématuré du fichier source dans l'expression ");
type_pointeur_var=TYP_PTR_VAR_POINTEUR_POINTEUR;
}
}
aff2=analyse_affectation(bloc_prof,type_pointeur_var);
} /* patch
else aff2=NULL;
if(type_token!=LCL)
message_erreur("Erreur
Fatale #S0140 :: ) attendue ");
cr=lire_token();
if(cr==-1)
message_erreur("\n
Erreur Fatale #S0141 : fin prématuré du fichier source dans l'instruction
for(;;) ");
/* analyse du corps du for */
inst=(INSTRUCTION
*)analyse_liste_instruction(bloc_prof,1);
/* analyse du corps du for */
descend();
inst_r=(INSTRUCTION
*)nouvelle_instruction(bloc_prof,INST_FOR,0,exp1,inst,NULL,aff1,aff2,NULL,0,NULL,NULL,NULL,NULL);
/* affiche_inst_for(inst_r);*/
boucle--;
return(inst_r);
}
This
grammar below is not really implemented
like described.
<expr> -> <ident> |
<ident> [ . <ident assign> ] 1..n |
<ident> [ [<expr> ]
] 1..n |
<atom> |
(<expr> ) |
<expr> [<math op> <expr>] 1..n |
- <math expr> |
<expr> [<logical
op> <logical expr>] 1..n |
! <expr>
Indeed, the
aim is to generate a binary tree which makes easier the code generation step :
the set of arithmetic instruction is based on binary argument.
The second
reason is that operators have precedence.
a+3*c is
equal to a + (3*c), the ‘*’ operator is prioritized. To recognize
a such pattern, the grammar must be written by following a particular
way.
<Exp>
-> <Sub_Exp> [+ | -] <Exp>
<Exp>
-> <Sub_Exp>
<Sub_Exp> -> <atom> [*
| /] <Sub_Exp>
<Sub_Exp> -> <atom>
<atom>
-> <variable> | <integer> | ( <Exp> )
example of
parsing which illustrates the precedence of the operator ‘*’ :

As you can
see above, 3*c is parsed as a <sub exp> rule and not as an <exp>
rule.
In the COP
compiler, such a grammar operator has been implemented.
a+3*c+d is parsed as shown below :

Below an
array which maps the grammar and the C function which code the parsing :
|
rules |
C function |
C structures |
Semantic and Syntax controls |
|
<Program> -> [
<define declaration> | <struct declaration> | <variable
declarations>| <mutex declarations>
| <function> | <task> ]0..n |
void analyse_corps(char *prof_bloc) |
|
|
|
<define declaration> -> define <ident> <text> |
|
Double
declaration of define |
|
|
<struct declaration> -> struct
{ < field definition >1..n }; |
void analyse_variable(char *prof_bloc), |
extern TYPE_VARIABLE tab_type_variable[MAX_TYPE_VARIABLE]; extern int nb_tab_type_variable; extern PROGRAM program; Storage of structure and fields : index_type=ajout_type(prof_bloc,
type,STRUCTURE,dimension, nb_dimension,
nom_structure, ident, nb_champ, type_pointeur); see more detail on variables and
structures #define MAX_VARIABLE_GLOBALE 1000 #define TYPE_VARIABLE struct type_variable TYPE_VARIABLE { int genre_variable; /* ATOME, STRUCTURE,
TABLEAU, pointeur */ char
type[MAX_IDENT]; /* type */ char champ_structure[MAX_IDENT]; /* ident du champ */ TYPE_VARIABLE
*type_variable_ptr[MAX_CHAMP]; /* champs de la structure */ int nb_type_variable; /* nombre de champs de la
structure */ int dimension[MAX_DIMENSION]; /* dimension du
tabelau, si tableau */ int nb_dimension; /*nombre de dimension du
tableau */ int nb_champ; /* nb de champ de la structure */ char
bloc[PROF_BLOC+1]; int type_pointeur; /* pour les champs */ }; |
Syntax
errors Double
declaration of structure Double
declaration of a filed of structure Too many
fields in the structure … |
|
<field definition> -> <type> <list of fields> |
|||
|
<list of fields> -> <field> , <list of fields> | <field> ; |
|||
|
<field> -> [*]0|1 <ident> [ [<integer>] ] 0..n |
|||
|
<variable declarations> -> <type> <list of
variables> |
void analyse_variable(char *prof_bloc), |
Storage of arrays : index_type=ajout_type(prof_bloc,type,TABLEAU,dimension, nb_dimension,NULL,NULL,0,type_pointeur); Storage of variables ( initialized or not ) : if(init_var==0) ajout_variable(prof_bloc,index_type,type,ident,NULL, init_var,type_pointeur); else jout_variable(prof_bloc,index_type,type,ident,valeur_token, init_var,type_pointeur); see more detail on variables and
structures #define POINTEUR 0 #define PASPOINTEUR 1 #define POINTEURPOINTEUR 2 #define MAX_TYPE_VARIABLE 1000 #define VARIABLE_GLOBALE struct
variable_globale VARIABLE_GLOBALE { TYPE_VARIABLE
*type_variable_ptr; char
ident[MAX_IDENT]; char
bloc[PROF_BLOC+1]; char
valeur[MAX_IDENT]; /* vaut null si pas de valeur initialisée */ int type_pointeur; int modify; }; |
Syntax
errors Double
declaration of variable Dimension
of an array exceed the maximum value Initialisation
with a constant which is not compatible with the type of the variable … |
|
<list of variables> -> <variable> , <list of variables> | <field> ; <variable> -> [*]0|1 <ident> [ [<integer>] ] 0..n
= [<init>]0|1 <init> -> <numeric value> | <string> |
|||
|
<mutex_declaration> -> mutex <list
of mutex> <list of mutex> -> <mutex> , <list of mutex> | <mutex> ; < mutex> -> <ident> |
void analyse_mutex(void) |
extern TAB_MUTEX tab_mutex[MAX_MUTEX]; extern int nb_mutex; #define MAX_MUTEX 10000 #define TAB_MUTEX struct tab_mutex TAB_MUTEX { char
ident[MAX_IDENT]; /* nom du mutex */ char
module[100]; /*
module */ int ligne; /*
ligne */ }; |
Syntax
errors Double
declaration of mutex … |
|
<function> -> <ident> (
<list of parameters> ) < body > | < return value >
<ident> ( <list of
parameters> | void ) < body > <list of parameters>
-> <list of parameters> ,<parameter>
| <parameter> <parameter> -> [ mod
] 0|1 <type> [*]0|1
<ident> <return value> -> void
| <type> |
void analyse_fonction(void) |
extern FONCTION tab_fonction[MAX_FONCTION]; extern int nb_fonction; #define MAX_FONCTION 1000 #define MAX_VARLOC 100 #define FONCTION struct fonction FONCTION { TYPE_VARIABLE
*type_variable_retournee_ptr; /* pointe sur le type de variable retournee
atome ou structure */ int
type_pointeur; /* type de pointeur retourne
PASPOINTEUR,POINTEUR,POINTEURPOINTEUR */ char
ident_fonction[MAX_IDENT]; /* nom de la fonction */ int
nb_parametre; /*nb de paramètres */ VARIABLE_GLOBALE
*parametres; /* liste des parametres */ int
nb_var_locale; /*nb de variable locale */ VARIABLE_GLOBALE
*var_locale; /* liste des parametres */ INSTRUCTION
*liste_instruction; /* listes des instructions */ int
nb_instruction; int
librairie; }; |
Syntax
errors Double
declaration of functions Bad type
of the return value … |
|
<task> -> task <ident> ( ) <
body > |
void analyse_tache(void) |
extern TACHE tab_tache[MAX_TACHE]; extern int nb_tache; #define MAX_TACHE 1000 #define TACHE struct tache TACHE { char ident_tache[MAX_IDENT]; /* nom de la
tache */ int nb_var_locale; /*nb de variable locale */ VARIABLE_GLOBALE
*var_locale; /* liste des parametres */ INSTRUCTION
*liste_instruction; /* listes des instructions */ int nb_instruction; }; |
Syntax
errors Double
declaration of tasks |
|
<body> -> { [<variable
declarations>] 0|1 [<instruction>]0..n } |
void analyse_variable(char *prof_bloc) |
extern TYPE_VARIABLE tab_type_variable[MAX_TYPE_VARIABLE]; extern int nb_tab_type_variable; extern PROGRAM program; |
Syntax
errors Double
declaration of functions Bad type
of the return value … |
|
<instruction> -> <assignment> | <for loop> | <do
while loop> | <if
then else> | <switch>
| <goto>
| <label>
| <continue>
| <break>
| <exit> | <return> | <acquire> | <release> | <precedes> | <arrinit> | <arrsize> | <arrbuild> | <arrsubset>
| <inline> | < function
call> ; |
INSTRUCTION * analyse_liste_instruction(char *bloc_prof,int
tag) |
extern INSTRUCTION tab_instruction[MAX_INSTRUCTION]; extern int nb_instruction; |
Syntax
errors |
|
<assignment> -> [ [*( <ident> + <expr>
) | <ident assign> ] [=
<expr> ; ] 0|1 | <ident>
++; | <ident> -- ; |
SAFFECTATION * analyse_affectation(char
*bloc_prof,int type_pointeur_var) |
#define AFF_EXP 0 #define AFF_INC 1 #define AFF_DEC 2 #define AFF_PTR 3 #define SAFFECTATION struct saffectation SAFFECTATION { SEXPRESSION
*variable; SEXPRESSION
*valeur_affectee; int
type_affectation; }; |
Syntax
errors |
|
<for loop> -> for (
[ <affectation> ] 0..1
; [<expr>] 0..1 ;
<affectation> ] 0..1 )
<body instruction> |
INSTRUCTION * analyse_for(char *bloc_prof) |
#define SFOR struct sfor SFOR { SAFFECTATION *argument_init_ptr; SEXPRESSION
*expression_ptr; SAFFECTATION
*argument_increment_ptr; INSTRUCTION
*corps_for; }; |
Syntax
errors |
|
<do while loop> -> do { [<instruction>]0..n
}
while ( <expr> ) ; |
INSTRUCTION * analyse_do_while(char *bloc_prof) |
#define SDO_REPEAT struct sdorepeat SDO_REPEAT { SEXPRESSION *expression_ptr; INSTRUCTION
*corps; }; |
Syntax
errors |
|
<if then else> -> if (
<expr> ) <body
instruction> [ else <body
instruction> ] 0..1 |
INSTRUCTION * analyse_if(char *bloc_prof) |
#define SIF struct sif SIF { int selse; SEXPRESSION
*argument; INSTRUCTION
*corps_if; INSTRUCTION
*corps_else; }; |
Syntax
errors |
|
<switch> -> switch
( <expr> ) { [<
switch body>]0..1 } <switch body> -> case
<expr> : [<body instruction>] 0..1 [break ; ]
0..1 | default : [<body instruction>]
0..1 |
INSTRUCTION * analyse_switch(char *bloc_prof) |
#define TYPE_CASE_CASE 1 #define TYPE_CASE_DEFAULT 2 #define MAX_CASE 100 #define SSWITCH struct sswitch SSWITCH { SEXPRESSION
*expression; SEXPRESSION
*expression_case[MAX_CASE]; INSTRUCTION
*cases[MAX_CASE]; int nb_case; int
type_case[MAX_CASE]; int
break_or_not[MAX_CASE]; }; |
Syntax
errors |
|
<goto> -> goto <ident> ; |
void analyse_goto(char *bloc_prof) |
INSTRUCTION_ELT { … char sgoto[MAX_IDENT]; … }; |
Syntax
errors |
|
<label> -> <ident> : |
void analyse_lident(char *bloc_prof) |
INSTRUCTION_ELT { … char slabel[MAX_IDENT]; … }; |
Syntax
errors |
|
<continue> -> continue
; |
INSTRUCTION * analyse_continue(char *bloc_prof) |
|
Syntax
errors |
|
<break> -> break
; |
INSTRUCTION * analyse_break(char *bloc_prof) |
|
Syntax
errors |
|
<exit> -> exit ( ) ; |
INSTRUCTION * analyse_exit(char
*bloc_prof) |
|
Syntax
errors |
|
<return> -> return (
expr ) ; |
INSTRUCTION * analyse_return(char *bloc_prof) |
#define SRETURN struct sreturn SRETURN { SEXPRESSION *expression_ptr; int exp; }; |
Syntax
errors |
|
<acquire> -> acquire (
<ident> ) ; |
void analyse_acquire(char
*bloc_prof) |
INSTRUCTION_ELT { … char
smutex_acquire[MAX_IDENT]; … }; |
Syntax
errors Unknown
mutex |
|
<release> -> release (
<ident> ) ; |
void analyse_release(char *bloc_prof) |
INSTRUCTION_ELT { … char smutex_release[MAX_IDENT]; … }; |
Syntax
errors Unknown
mutex |
|
<precedes>-> precedes <list of tasks> ; <list of tasks> -> <list of tasks> , <ident> | <ident> |
INSTRUCTION * analyse_precedes(char *bloc_prof) |
#define MAX_PRECEDES 20 #define SPRECEDES struct sprecedes SPRECEDES { int nb_label; char
label[MAX_PRECEDES][MAX_IDENT]; }; |
Syntax
errors Unknown
task |
|
<arrinit> -> arrinit (
<ident>, <expr>, <expr> ) ; |
void analyse_arrinit(char *bloc_prof) |
#define SARRINIT struct sarrinit SARRINIT { char label[MAX_IDENT]; SEXPRESSION
*expression_value_ptr; SEXPRESSION
*expression_size_ptr; }; |
Syntax
errors Unknown
array Bad init
type |
|
<arrsize> -> arrssize (
<ident>, <ident> ) ; |
void analyse_arrsize(char *bloc_prof) |
#define SARRSIZE struct sarrsize SARRSIZE { char label[MAX_IDENT]; char size[MAX_IDENT]; }; |
Syntax
errors Unknown
array Bad type
of the “size” parameter |
|
<arrbuild> -> arrsbuild ( <list of arrays> ) ; <list of arrays> -> <list of arrays> , <ident> | <ident> |
void analyse_arrbuild(char *bloc_prof) |
#define SARRBUILD struct sarrbuild SARRBUILD { int nb_tab; char *label[10]; }; |
Syntax
errors Unknown
arrays |
|
<arrsubset> -> arrsubset (
<ident>, <ident>, <expr>,
<expr> ) ; |
void analyse_arrsubset(char *bloc_prof) |
#define SARRSUBSET struct sarrsubset SARRSUBSET { char label_src[MAX_IDENT]; char label_dst[MAX_IDENT]; SEXPRESSION
*expression_index_ptr; SEXPRESSION
*expression_length_ptr; }; |
Syntax
errors Unknown
arrays |
|
<inline> -> inline “<text>” ; |
void analyse_inline(char *bloc_prof) |
INSTRUCTION_ELT { … char sinline[MAX_INLINE]; … }; |
Syntax
errors |
|
<body instruction> -> { [<instruction>]0..n
}
| <instruction> |
INSTRUCTION * analyse_liste_instruction(char *bloc_prof,int
tag) |
extern INSTRUCTION tab_instruction[MAX_INSTRUCTION]; extern int nb_instruction; #define INSTRUCTION_ELT union instruction_elt INSTRUCTION_ELT { SAFFECTATION *saffectation; SEXPRESSION *sfonction; SIF
sif; SFOR
sfor; SBLOC sbloc; SSWITCH sswitch; SDO_REPEAT sdo_repeat; SRETURN sreturn; SARRSIZE sarrsize; SARRINIT sarrinit; SARRSUBSET sarrsubset; SARRBUILD sarrbuild; char slabel[MAX_IDENT]; char sgoto[MAX_IDENT]; SPRECEDES sprecedes; char sinline[MAX_INLINE]; char
smutex_acquire[MAX_IDENT]; char smutex_release[MAX_IDENT]; }; #define INST_ATOME 14 #define INST_VARIABLE 13 #define INST_IF 0 #define INST_FOR 1 #define INST_DO_REPEAT 2 #define INST_SWITCH 3 #define INST_GOTO 4 #define INST_RETURN 5 #define INST_BREAK 6 #define INST_CASE 7 #define INST_CONTINUE 8 #define INST_AFFECTATION 9 #define INST_EXPRESSION 10 #define INST_FONCTION 11 #define INST_BLOC
12 #define INST_LABEL 15 #define INST_PRECEDES 16 #define INST_EXIT
17 #define INST_INLINE 18 #define INST_ACQUIRE 19 #define INST_RELEASE 20 #define INST_ARRSIZE 21 #define INST_ARRINIT 22 #define INST_ARRSUBSET 23 #define INST_ARRBUILD 24 #define MAX_INSTRUCTION 100000 #define INSTRUCTION struct
instruction INSTRUCTION { int
type_instruction; /* type de l'instruction */ INSTRUCTION_ELT
instruction; /* pointeur sur char
bloc[PROF_BLOC+1]; int index; }; |
Syntax
errors |
|
<expr> -> [ <expr rec ou> ] 0..1 |
SEXPRESSION * analyse_expression(char
*bloc_prof) |
SATOME { char
valeur[MAX_IDENT]; int type; }; #define SVARIABLE_VARIABLE 1 (type_svariable ) #define
SVARIABLE_TABLEAU_SEUL 2
(type_svariable ) #define
SVARIABLE_CHAMP_SEUL 3
(type_svariable ) #define SVARIABLE_CHAMP_TABLEAU
4 (type_svariable ) #define SVARIABLE struct svariable SVARIABLE { int ligne; int
type_svariable; char
ident_variable[MAX_IDENT]; VARIABLE_GLOBALE
*variable_ptr; char
ident_champ[MAX_IDENT]; TYPE_VARIABLE
*type; SVARIABLE
*suivant; int
indirection; SEXPRESSION
*dimension[MAX_DIMENSION]; int nb_dimension; }; #define
MAX_PARAMETRE 100 #define SFONCTION struct
sfonction SFONCTION { char
fonction[MAX_IDENT]; int
nb_argument; SEXPRESSION
*argument_ptr[MAX_PARAMETRE]; }; #define SPOINTEUR struct
spointeur SPOINTEUR { int
ligne; char
ident_variable[MAX_IDENT]; VARIABLE_GLOBALE
*variable_ptr; TYPE_VARIABLE
*type; SEXPRESSION
*index; }; #define FEUILLE union feuille FEUILLE { SFONCTION
sfonction; SVARIABLE
svariable; SATOME
satome; SPOINTEUR
spointeur; }; #define EXP_OPERATEUR 1 #define EXP_ATOME 2 #define EXP_VARIABLE 3 #define EXP_FONCTION 4 #define EXP_POINTEUR 5 #define SEXPRESSION struct
sexpression SEXPRESSION { int
operateur; /* + - / % */ /* penser à ajouter modulo */ SEXPRESSION
*gauche; SEXPRESSION
*droit; int
type; FEUILLE
feuille; int
type_resultant; }; |
Syntax
errors |
|
<expr rec ou> -> <expr rec et> | <expr rec et> ||
<expr rec ou> |
SEXPRESSION * analyse_recursive_expression_logique_ou(char
*bloc_prof) |
Syntax
errors |
|
|
<expr rec et> -> <expr rec comp> | <expr rec comp> && <expr
rec et> |
SEXPRESSION * analyse_recursive_expression_logique_et(char
*bloc_prof) |
Syntax
errors |
|
|
<expr rec comp> -> <expr rec arith> | <expr rec arith> [ ==| !=
| >|
<|
<=|
>=
] <expr rec comp> |
SEXPRESSION * analyse_recursive_expression_comparaison(char
*bloc_prof) |
Syntax
errors |
|
|
<expr rec arith> -> <expr rec> | <expr rec> [ + | -
| |
] <expr
rec arith> |
SEXPRESSION * analyse_recursive_expression_arithmetique(char
*bloc_prof) |
Syntax
errors |
|
|
<expr rec> -> <expr rec shr shl> | <expr rec shr shl> [ & | /
| * | % ] <expr
rec> |
SEXPRESSION * analyse_recursive(char
*bloc_prof) |
Syntax
errors |
|
|
<expr rec shr
shl> -> <expr rec
not> | <expr rec not > [ >> | <<
] <expr rec shr shl
> |
SEXPRESSION * analyse_recursive_shr_shl(char
*bloc_prof) |
Syntax
errors |
|
|
<expr rec not> ->
<expr rec neg> | ! <expr rec neg > |
SEXPRESSION * analyse_atome_non(char
*bloc_prof) |
Syntax
errors |
|
|
<expr rec neg> -> <expr
rec atom> | - <expr
rec atom > |
SEXPRESSION * analyse_atome_neg(char
*bloc_prof) |
Syntax
errors |
|
|
<expr rec atom> ->
<atom> | <var func> | (<expr rec ou>
) |
SEXPRESSION * analyse_atome(char * bloc_prof) |
Syntax
errors |
|
|
<var func> - > <ident assign>| <function call> |
SEXPRESSION * analyse_fonction_ou_variable(char
* bloc_prof,int type_pointeur_var) |
Syntax
errors Unknown function |
|
|
<ident assign>->
<ident> |
<ident> ++ ; |
<ident> -- ; |
<ident> [ .
<ident assign> ] 1..n
| <ident> [ [<expr> ]
] 1..n |
SEXPRESSION * analyse_synt_variable(char
*bloc_prof,int type_pointeur_var) |
Syntax
errors Unknown variable |
|
|
<function call> -> <ident> ( [<
list of function parameters>]0..1 ) < list of function parameters> -> < list of function
parameters> , <expr> |
<expr> |
SEXPRESSION * analyse_synt_fonction(char
*bloc_prof) |
Syntax
errors |
|
|
<atom> -> <numeric value> | <string> |
|
|
|
|
<generic ident >
-> [a..z] | [A..Z] [[a..z] | [A..Z] | [0..9] | _ ] 0..n |
|
|
|
|
<string> -> ”[all ASCII code] 0..n” |
|
|
|
|
<numeric value> -> <binary> | <hexa> | <decimal> |
|
|
|
|
<binary> -> 0b [0|1]
1..n |
|
|
|
|
<hexa> -> 0x [ [0|1] | [ [A..F] | [a..f] ] ] 1..n |
|
|
|
|
<decimal>-> [0..9]
[0..9] 1..n |
|
|
|
|
<text> -> [all ASCII code]
0..n |
|
|
|
|
<ident type> -> <generic ident > |
|
|
|
|
<ident > -> <generic ident > |
|
|
|
|
<type> -> char | schar | byte
| sbyte | int | sint
| long | slong | <ident type> |
|
|
The code
generation step is the last step of the COP compiler. In a nutshell, it consists in generating
codes to declare variables and data structures and in generating NBC
instructions by going thru the syntax tree.

Code generation pass
Expliciter le princpe de la générationde code instruction / instercutopn
The module
“genere_code.c” contains the code generation functions.
The entry
point is the function void generation_de_code(char *nom), this function opens in write
mode the target nbc file and calls the void genere_code(void)
function.
This
function is described below :
void
genere_code(void)
{
int i;
fprintf(file_code,"#include
\"NXTDefs.h\""); Generate the include
command for the NXTDefs.h file.
fprintf(file_code,"\ndseg
segment");
genere_types(); Generate structures ( if some are defined )
genere_variables("0",0,0);
Generate global variables
genere_mutex(); Generate Mutex
for(i=0;i<nb_tache;i++)
{
genere_variables(tab_tache[i].ident_tache,0,0);
Generate local variables of tasks.
}
for(i=0;i<nb_fonction;i++)
{
genere_variables(tab_fonction[i].ident_fonction,tab_fonction[i].librairie,i);
Generates local variables of functions and parameters
as well.
}
fprintf(file_code,"\ndseg
ends");
genere_taches(); Generate codes of tasks
genere_fonctions(); Generate codes of functions
fprintf(file_code,"\n// End of
program");
}
Below this
table summarizes code patterns that are used to generate NBC codes.
|
Structure |
Array/variable |
Pattern |
C
function which generates the NMC code |
|
PROGRAM |
PROGRAM program; |
|
|
|
TACHE |
TACHE tab_tache[MAX_TACHE]; |
void genere_taches(void) |
|
|
FONCTION |
FONCTION tab_fonction[MAX_FONCTION]; |
void genere_fonctions(void) |
|
|
VARIABLE_GLOBALE |
See
PROGRAM |
for
global variables => genere_variables("0",0,0) for local
variable of task => genere_variables(tab_tache[i].ident_tache,0,0); for local
variables of functions and parameters => genere_variables(tab_fonction[i].ident_fonction,tab_fonction[i].librairie,i); |
|
|
TYPE_VARIABLE |
TYPE_VARIABLE tab_type_variable[MAX_TYPE_VARIABLE]; |
|
|
|
INSTRUCTION |
INSTRUCTION tab_instruction[MAX_INSTRUCTION]; |
|
void genere_instruction(INSTRUCTION *inst,char
*bloc) ; This
function contains a switch which associates to each type of instruction a
dedicated code generation pattern. Some cases have a dedicated C function and
some others are coded in the bodies of the cases. Below the
skeleton of this function ( find links to the detailed C code ) : void
genere_instruction(INSTRUCTION *inst,char *bloc) { if(inst==NULL) { end of
recursivity } else {
switch(inst->type_instruction) { case INST_INLINE: case_INST_INLINE case INST_IF : case_INST_IF case INST_FOR : case_INST_FOR case INST_DO_REPEAT : case_INST_DO_REPEAT case INST_SWITCH : case_INST_DO_REPEAT case INST_LABEL : case_INST_LABEL case INST_GOTO : case_INST_GOTO case INST_ACQUIRE : case_INST_ACQUIRE case INST_RELEASE : case_INST_RELEASE case INST_ARRSIZE: case_INST_ARRSIZE case INST_ARRINIT: case_INST_ARRINIT case INST_ARRSUBSET: case_INST_ARRSUBSET case INST_ARRBUILD: case_INST_ARRBUILD case INST_RETURN : case_INST_RETURN case INST_EXIT: case_INST_EXIT case INST_PRECEDES: case_INST_PRECEDES case INST_BREAK : case_INST_BREAK case INST_CONTINUE : case_INST_CONTINUE case INST_AFFECTATION
: case_INST_AFFECTATION case INST_FONCTION : case_INST_FONCTION case INST_BLOC : recursivity genere_instruction() case_INST_BLOC } } |
|
INSTRUCTION_ELT |
See #instruction_elt |
|
|
|
SEXPRESSION |
See expression |
|
|
|
FEUILLE |
See expression |
|
|
|
SATOME |
See expression |
|
|
|
SPOINTEUR |
See expression |
|
|
|
SVARIABLE |
See expression |
|
|
|
SFONCTION |
See expression |
||
|
SAFFECTATION |
See affectation |
||
|
SIF |
See if |
See case_INST_IF |
|
|
SFOR |
See for |
See case_INST_FOR void genere_inst_for(INSTRUCTION *inst,char *bloc) |
|
|
SBLOC |
|
|
|
|
SSWITCH |
See switch |
See case_INST_SWITCH |
|
|
SDO_REPEAT |
See do_repeat |
||
|
SRETURN |
See return |
See case_INST_RETURN |
|
|
SARRSIZE |
See arrsize |
||
|
SARRINIT |
See arrinit |
||
|
SARRSUBSET |
See arrsubset |
||
|
SARRBUILD |
See arrbuild |
||
|
SPRECEDE |
See precedes |
||
|
SLABEL |
See label |
See case_INST_LABEL |
|
|
SGOTO |
See goto |
See case_INST_GOTO |
|
|
SINLINE |
See inline |
See case_INST_INLINE |
|
|
ACQUIRE |
See acquire |
||
|
RELEASE |
See release |
||
|
Mutex |
#define MAX_MUTEX 10000 #define TAB_MUTEX struct tab_mutex TAB_MUTEX { char ident[MAX_IDENT]; /* nom du mutex */ char module[100]; /*
module */ int
ligne; /* ligne */ }; TAB_MUTEX tab_mutex[MAX_MUTEX]; int nb_mutex; |
void genere_mutex(void) |
To be
completed
To be
completed
To be
completed
The pattern
of expression requires some clear explanations.
Indeed, the
NXT virtual machine doesn’t offer a stack, in other words you cannot save a
context by using POP or PUSH instruction.
Due to this
limitation, the generation of codes for complex expressions requires an
explicit ‘management’ of stack.
The algorithm
is described hereafter :
If there is a right sub-tree :
Generate
recursively the code of this right sub-tree=> rtyped=genere_recursif(exp->droit,0,bloc,NULL);
If there is a left sub-tree ( not an unary
operator such as DEC, INC, NOT, NEG )
If
the right sub-tree is not an atom then PUSH the context to save the right value
Generate
recursively the code of this left sub-tree => rtypeg=genere_recursif(exp->gauche,0,bloc,NULL);
If
the right sub-tree is not an atom then POP the context to retrieve the right
value on top if the stack
Apply the operator, + , - ….
Example of
code :
task
main()
{
int a,b,c;
c=3*a+4*b;
}
A simple
pattern based on the following example shows that if stack is not managed, it
cannot work .
The
relevant solution relies on the use of a stack, see below the use of this stack
:
arrinit
expr_pile_byte_main, 0, 100
arrinit
expr_pile_sbyte_main, 0, 100
arrinit
expr_pile_word_main, 0, 100
arrinit
expr_pile_sword_main, 0, 100
arrinit
expr_pile_dword_main, 0, 100
arrinit
expr_pile_sdword_main, 0, 100
set expr_ptr_pile_byte_main,
0
set
expr_ptr_pile_sbyte_main, 0
set
expr_ptr_pile_word_main, 0
set
expr_ptr_pile_sword_main, 0
set
expr_ptr_pile_dword_main, 0
set
expr_ptr_pile_sdword_main, 0
mov expr_word_main, main_b // aff 1
mov expr_d_word_main, expr_word_main
replace expr_pile_word_main, expr_pile_word_main,
expr_ptr_pile_word_main, expr_d_word_main -> PUSH(1) save the value on the top
of the stack ‘b’
set
inc_main, 1
add expr_ptr_pile_word_main,
expr_ptr_pile_word_main, inc_main -> increment the stack pointer
set expr_byte_main, 4
set
inc_main, 1
sub
expr_ptr_pile_word_main, expr_ptr_pile_word_main, inc_main -> decrement the
stack pointer
index
expr_d_word_main, expr_pile_word_main, expr_ptr_pile_word_main -> POP(2) retreive the value on
the top of the stack -> expr_d_word_main = ‘b’
mov expr_g_byte_main, expr_byte_main
-> expr_g_byte_main = 4
mul expr_word_main,
expr_g_byte_main, expr_d_word_main -> expr_word_main = expr_g_byte_main *
expr_d_word_main = ‘4*b’
mov expr_d_word_main, expr_word_main
replace expr_pile_word_main, expr_pile_word_main,
expr_ptr_pile_word_main, expr_d_word_main -> PUSH(3) save the value on the top
of the stack ‘4*b’
set inc_main, 1
add expr_ptr_pile_word_main,
expr_ptr_pile_word_main, inc_main -> increment the stack pointer
mov expr_word_main, main_a // aff 1
mov expr_d_word_main, expr_word_main
replace expr_pile_word_main,
expr_pile_word_main, expr_ptr_pile_word_main, expr_d_word_main -> PUSH(4) save the value on the top
of the stack ‘a’
set inc_main, 1
add expr_ptr_pile_word_main,
expr_ptr_pile_word_main, inc_main -> increment the stack pointer
set expr_byte_main, 3
set inc_main, 1
sub
expr_ptr_pile_word_main, expr_ptr_pile_word_main, inc_main
index
expr_d_word_main, expr_pile_word_main, expr_ptr_pile_word_main -> POP(5) retreive the value on
the top of the stack -> expr_d_word_main = ‘a’
mov expr_g_byte_main, expr_byte_main
-> expr_g_byte_main = 3
mul expr_word_main,
expr_g_byte_main, expr_d_word_main -> expr_word_main = expr_g_byte_main *
expr_d_word_main= ‘3*a’
set inc_main, 1
sub
expr_ptr_pile_word_main, expr_ptr_pile_word_main, inc_main
index
expr_d_word_main, expr_pile_word_main, expr_ptr_pile_word_main -> POP(6) retreive the value on
the top of the stack -> expr_d_word_main = ‘4*b’
mov expr_g_word_main, expr_word_main
add expr_word_main,
expr_g_word_main, expr_d_word_main ->
expr_word_main = ‘3*a’ + ‘4*b’
mov expr_aff_word_main,
expr_word_main // affectation 3
mov main_c, expr_aff_word_main //
aff 3- > c = ‘3*a’ + ‘4*b’
SP is Stack
Pointer

Below a
table which maps operators versus instructions :
Nota :
types of left and right expressions are controlled, eg. we cannot add a string
and an integer. In some some cases the types are ‘forced’ as well.
|
operator |
token |
Generated
codes |
|
'<<' |
LSHL |
fprintf(file_code,"\n\tshl expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc); |
|
'>>' |
LSHR |
fprintf(file_code,"\n\tshr expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc); |
|
'*' |
LMUL |
fprintf(file_code,"\n\tmul expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc); |
|
'/' |
LDIV |
fprintf(file_code,"\n\tdiv expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc); |
|
'%' |
LMODULO |
fprintf(file_code,"\n\tmod expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc); |
|
'+' |
LPLUS |
fprintf(file_code,"\n\tadd expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc); |
|
'-' |
LMOINS |
fprintf(file_code,"\n\tsub expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc); |
|
'&&' |
LCOMPET |
fprintf(file_code,"\n\tbrtst EQ, false_et_%d, expr_g_%s_%s",ind_et,rtypeg,bloc); fprintf(file_code,"\n\tbrtst EQ, false_et_%d, expr_d_%s_%s",ind_et, rtyped,bloc); fprintf(file_code,"\n\tset expr_byte_%s, 1",bloc); fprintf(file_code,"\n\tjmp fin_test_et_%d",ind_et); fprintf(file_code,"\nfalse_et_%d:",ind_et); fprintf(file_code,"\n\tset
expr_byte_%s, 0",bloc); fprintf(file_code,"\nfin_test_et_%d:",ind_et); |
|
'||' |
LCOMPOU |
fprintf(file_code,"\n\tbrtst GT, true_ou_%d, expr_g_%s_%s",ind_ou,rtypeg,bloc); fprintf(file_code,"\n\tbrtst GT, true_ou_%d,
expr_d_%s_%s",ind_ou,rtyped,bloc); fprintf(file_code,"\n\tset
expr_byte_%s, 0",bloc); fprintf(file_code,"\n\tjmp fin_test_ou_%d",ind_ou); fprintf(file_code,"\ntrue_ou_%d:",ind_ou); fprintf(file_code,"\n\tset
expr_byte_%s, 1",bloc); fprintf(file_code,"\nfin_test_ou_%d:",ind_ou); |
|
'<' |
LCOMPINF |
fprintf(file_code,"\n\tcmp LT, expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc); |
|
'>' |
LCOMPSUP |
fprintf(file_code,"\n\tcmp GT,
expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc); |
|
'<=' |
LCOMPINFEG |
fprintf(file_code,"\n\tcmp LTEQ,
expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc); |
|
'>=' |
LCOMPSUPEG |
fprintf(file_code,"\n\tcmp GTEQ, expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc); |
|
'==' |
LCOMPEG |
fprintf(file_code,"\n\tcmp EQ, expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc); |
|
'!=’ |
LCOMPDIFF |
fprintf(file_code,"\n\tcmp NEQ,
expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s","byte",bloc,rtypeg,bloc,rtyped,bloc); |
|
'|' |
LOU |
fprintf(file_code,"\n\tor expr_%s_%s, expr_g_%s_%s,
expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc); |
|
'&' |
LET |
fprintf(file_code,"\n\tand expr_%s_%s, expr_g_%s_%s, expr_d_%s_%s",rtype,bloc,rtypeg,bloc,rtyped,bloc); |
|
'!' |
LNON |
fprintf(file_code,"\n\tnot expr_%s_%s,
expr_%s_%s",rtype,bloc,rtypeg,bloc); |
|
'- unaire' |
LNEG |
fprintf(file_code,"\n\tneg expr_%s_%s,
expr_%s_%s",rtype,bloc,rtypeg,bloc); |
|
'++' |
LINC |
rtype=genere_recursif(exp->gauche,2,bloc,NULL); |
|
'--' |
LDEC |
rtype=genere_recursif(exp->gauche,3,bloc,NULL); |
To be
completed
To be
completed
The ‘if’
condition follows the following pattern
:
Expression condition
brcmp EQ, else_main_if_2, expr_byte_main, 0
bloc if
jmp end_main_if_2
else_main_if_2:
bloc else
end_main_if_2:
Obviously
the “else” bloc is not generated if no ‘else’ is parsed.
Sample
of code :
task main()
{
int i;
if(i==1)
{
}
else {
}
}
Sample
of generated code :
//_________________________________________________
// task
main()
// {
thread main
// ALLOCATION DU TABLEAU D'INDEX
arrinit index_tab_main, 0, 100
// BODY
arrinit expr_pile_byte_main, 0, 100
arrinit expr_pile_sbyte_main, 0, 100
arrinit expr_pile_word_main, 0, 100
arrinit expr_pile_sword_main, 0, 100
arrinit expr_pile_dword_main, 0, 100
arrinit expr_pile_sdword_main, 0,
100
set expr_ptr_pile_byte_main, 0
set expr_ptr_pile_sbyte_main, 0
set expr_ptr_pile_word_main, 0
set expr_ptr_pile_sword_main, 0
set expr_ptr_pile_dword_main, 0
set expr_ptr_pile_sdword_main, 0
//
//
// Index instruction =3 main
// INSTRUCTION BLOC
//-- LISTE INSTRUCTION BLOC nb_inst 1
//-- SOUS INSTRUCTION BLOC 0
//
//
//----
Index instruction =2 main
//---- INSTRUCTION IF
//------ INSTRUCTION IF
// TYPE = byte
set expr_byte_main, 1
//---------- ATOME 1 OP = 0 TYPE = 43/ENTIER
// TYPED = byte
mov expr_d_byte_main,
expr_byte_main
//PUSH context expr_pile_byte_main
replace expr_pile_byte_main, expr_pile_byte_main,
expr_ptr_pile_byte_main, expr_d_byte_main
set inc_main, 1
add
expr_ptr_pile_byte_main, expr_ptr_pile_byte_main, inc_main
// TYPE VARIABLE=int NOM = 'main_i' DIM = 0
mov expr_word_main,
main_i // aff 1
//---------- VARIABLE 'i' type
ptr ='normal'
//---------- ident 'i' bloc
'main' valeur '' / type 'int'
'PASPOINTEUR'
//---------- TYPE VARIABLE 'word'
//POP context expr_pile_byte_main
set inc_main, 1
sub
expr_ptr_pile_byte_main, expr_ptr_pile_byte_main, inc_main
index expr_d_byte_main,
expr_pile_byte_main, expr_ptr_pile_byte_main
// TYPE = word
mov expr_g_word_main,
expr_word_main
//-------- TYPE VARIABLE d='byte' g='word'
// TYPE_RESULTANT word
//-------- OPERATEUR 20/ '=='
mov expr_d_word_main,
expr_d_byte_main
cmp EQ, expr_byte_main,
expr_g_word_main, expr_d_word_main
brcmp
EQ, else_main_if_2, expr_byte_main, 0
//------ THEN
//
//
//-------- Index instruction =0 main
//-------- INSTRUCTION BLOC
//---------- BLOC VIDE
jmp end_main_if_2
else_main_if_2:
//------ ELSE
//
//
//-------- Index instruction =1 main
//-------- INSTRUCTION BLOC
//---------- BLOC VIDE
end_main_if_2:
endt
// }
// End of
task main()
// End of
program
The ‘for’
loop follows the following pattern :
for(init;cond;inc_dec) body
pattern :
jmp eval_cond_main_for_2
main_for_2:
continue_main_for_2:
eval_cond_main_for_2:
brcmp GT, main_for_2,
expr_byte_main, 0
break_main_for_2:
Sample
of code :
task main()
{
int i;
i=1000;
for(i=1000;i>0;i--)
{
}
}
Sample
of generated code :
//_________________________________________________
// task
main()
// {
thread main
//
ALLOCATION DU TABLEAU D'INDEX
arrinit index_tab_main, 0, 100
// BODY
//
//
// Index
instruction =3 main
//
INSTRUCTION BLOC
//-- LISTE
INSTRUCTION BLOC nb_inst 2
//-- SOUS INSTRUCTION BLOC 0
//
//
//---- Index instruction =0 main
//------ =
AFF VARIABLE SIMPLE
// TYPE =
word
set expr_word_main, 1000
//--------
ATOME 1000 OP = 0 TYPE = 43/ENTIER
mov expr_aff_word_main,
expr_word_main // affectation 3
// TYPE
VARIABLE=int NOM = 'main_i' DIM = 0
mov main_i, expr_aff_word_main //
aff 3
//-------- VARIABLE 'i' type ptr ='normal'
//-------- ident 'i' bloc 'main' valeur '' / type 'int' 'PASPOINTEUR'
//-------- TYPE VARIABLE 'word'
//------ INSTRUCTION AFFECTATION 167b00 17afe0
//-- SOUS INSTRUCTION BLOC 1
//
//
//---- Index instruction =2 main
//---- INSTRUCTION FOR
//------ INSTRUCTION FOR(AFF1;EXP;INST1)LISTINST
//------ =
// TYPE = word
set expr_word_main,
1000
//-------- ATOME 1000 OP = 0 TYPE = 43/ENTIER
mov expr_aff_word_main,
expr_word_main
// TYPE VARIABLE=int NOM = 'main_i' DIM = 0
mov main_i,
expr_aff_word_main // aff 3
//-------- VARIABLE 'i' type ptr
='normal'
//-------- ident 'i' bloc 'main'
valeur '' / type 'int' 'PASPOINTEUR'
//-------- TYPE VARIABLE 'word'
jmp eval_cond_main_for_2
main_for_2:
//------
DEBUT CODE CORPS DU FOR
//
//
//-------- Index instruction =1
main
//-------- INSTRUCTION BLOC
//---------- BLOC VIDE
//------ FIN CODE CORPS DU FOR
continue_main_for_2:
//------ EVOLUTION VARIABLE DU
FOR
//------ -- DECREMENT
// TYPE VARIABLE=int NOM = 'main_i' DIM = 0
set expr_g_word_main, 1
sub main_i, main_i,
expr_g_word_main
mov expr_word_main,
main_i
//-------- VARIABLE 'i' type ptr
='normal'
//-------- ident 'i' bloc 'main'
valeur '' / type 'int' 'PASPOINTEUR'
//-------- TYPE VARIABLE 'word'
//------ EVALUATION CONDITION
eval_cond_main_for_2:
set expr_byte_main, 0
//---------- ATOME 0 OP = 0 TYPE = 43/ENTIER
// TYPED = byte
mov expr_d_byte_main,
expr_byte_main
//PUSH context expr_pile_byte_main
replace expr_pile_byte_main, expr_pile_byte_main,
expr_ptr_pile_byte_main, expr_d_byte_main
set inc_main, 1
add
expr_ptr_pile_byte_main, expr_ptr_pile_byte_main, inc_main
// TYPE VARIABLE=int NOM = 'main_i' DIM = 0
mov expr_word_main,
main_i // aff 1
//---------- VARIABLE 'i' type
ptr ='normal'
//---------- ident 'i' bloc
'main' valeur '' / type 'int'
'PASPOINTEUR'
//---------- TYPE VARIABLE 'word'
//POP context expr_pile_byte_main
set inc_main, 1
sub expr_ptr_pile_byte_main,
expr_ptr_pile_byte_main, inc_main
index expr_d_byte_main,
expr_pile_byte_main, expr_ptr_pile_byte_main
// TYPE = word
mov expr_g_word_main,
expr_word_main
//-------- TYPE VARIABLE d='byte' g='word'
// TYPE_RESULTANT word
//-------- OPERATEUR 17/ '>'
mov expr_d_word_main,
expr_d_byte_main
cmp GT, expr_byte_main,
expr_g_word_main, expr_d_word_main
//------ SAUT si EXPRESSION VRAI
brcmp GT, main_for_2, expr_byte_main, 0
break_main_for_2:
endt
// }
// End of
task main()
// End of
program
To be
completed
To be
completed
To be
completed
To be
completed
To be
completed
To be
completed
To be
completed
To be
completed
To be
completed
The ‘goto’
instruction follows the following pattern :
jmp main_switch_315_label_test1
code …
main_switch_315_label_test1:
Sample
of code :
task
main()
{
goto test1;
…
test1 :
}
To be
completed
To be
completed
To be
completed
__________________________________________________________________________________________________________________________________________________________
Below the
list of libraries that are currently created.
These libraries are not completed
yet and all “defines” are not defined yet ( eg. #define MOTOR_A 0x00
#define MOTOR_B 0x01,
#define MOTOR_C 0x02 in the motor lib) as well. This work is to be
continued !!! if someone wants to give a hand J, you are welcome !
The
principle is to have a set of libraries which defines a list of COP functions
mapped on low level libraries. Below an example which illustrates the use of
parameters and the inline
instructions.
/*******************************/
/* this function rotates motor */
/* forward */
/*******************************/
void COP_RotateMotorOnFwd(byte *motors,int power)
{
inline
"OnFwd(COP_RotateMotorOnFwd_motors,COP_RotateMotorOnFwd_power)";
}
|
Name of
the library |
Function |
File (
click on it to download ) |
Comments |
|
void
COP_SetScreenMode(void) void
COP_DrawText(int x, int y,char *string) COP_TextOut(sint
x, sint y, long cls, char *text) COP_NumOut(sint
x, sint y, long cls,slong number) COP_PointOut(sint x, sint y,long cls) COP_LineOut(sint x1, sint y1, sint x2, sint y2, long cls) COP_RectOut(sint
x, sint y, sint width, sint height, long cls) COP_CircleOut(sint x, sint y, byte radius, long cls) |
|
Few
functions to display information on or graphics on the screen of the NXT. Defines
and functions to be completed. |
|
|
byte
COP_Fopen(char *name,char *mode) byte
COP_FopenWrite(char *name) byte
COP_FopenRead(char *name) long
COP_Fread(byte handle,mod char *buffer,long length) long
COP_Fwrite(byte handle,char *buffer,long length) void
COP_Fclose(byte handle) |
Few
functions to manage files in the NXT. I’ve not really understood the
behaviours of these functions. Defines
and functions to be completed. |
||
|
void
COP_RotateMotorOnFwd(byte *motors,int power) void
COP_RotateMotorOnRev(byte *motors,int power) void
COP_RotateMotorOnFwdSync(byte *motors,int power,schar turnpct) void
COP_RotateMotorOnRevSync(byte *motors,int power,schar turnpct) void
COP_RotateMotorStop(byte *motors) void
COP_RotateMotorCoast(byte *motors) void
COP_RotateMotor(byte *motors,int power, sint angle) void
COP_RotateMotorEx(byte *motors,int power, sint angle, char turnpct, schar
bsync) |
Few
functions to manage motors. Defines
and functions to be completed. |
||
|
void
COP_InitSensors(void) void
COP_SetSensorModeSound_pct(void) void
COP_SetSensorModeSound_raw(void) void
COP_SetSensorModeLight_pct(void) void
COP_SetSensorModeLight_raw(void) void
COP_SetSensorModeUltraSonic_pct(void) void
COP_SetSensorModeUltraSonic_raw(void) int
COP_ReadSoundDetector(void) int
COP_ReadUltraSonicDetector(void) int
COP_ReadLightDetector(void) int
COP_ReadTouchDetector(void) void
COP_ResetTouchDetector(void) void COP_ResetSoundDetector(void) void
COP_ResetLightDetector(void) void
COP_ResetUltraSonicDetector(void) |
Few
functions to manage sensors. Defines
and functions to be completed. |
||
|
void
COP_SoundPlayTone(int freq,int time,byte loop,byte volume) new
: byte COP_SoundGetState(void) new
: byte COP_SoundSetState(byte state, byte flags) new
: byte COP_SoundPlayFile(char *name,byte loop,byte volume) |
Only one
function to manage sound. |
||
|
void
COP_NumtoString(int value,mod char *string) int
COP_Strlen(char *src) void
COP_Strcpy(mod char *tab,char *src) void
COP_Strcat(mod char *dest,char *src1, char *src2) |
Few
functions to manipulate strings. Defines
and functions to be completed. |
||
|
void
COP_Wait(int time) void
COP_Malloc(mod char *tab,int size) |
Few
system functions. Defines
and functions to be completed. |
__________________________________________________________________________________________________________________________________________________________
Below a
table which points on example of COP files. The purpose of some of them is to
test the detection error of the COP compiler or to test that the generated code
works correctly.
|
Name of
file |
COP
source file ( click on it to download ) |
NBC
compiled file ( click on it to download ) |
Comments |
|
This
program tests a simple exepression. |
|||
|
This
program is for testing the ‘for’ loop. |
|||
|
This
source is only for testing the ‘if’ instruction. It doesn’t have a “smart”
behaviour if downloaded in the NXT robot. |
|||
|
This
program tests that negative values of counters work correctly. |
|||
|
essai.cop.txt |
This
source is only for testing the syntax parser. It doesn’t have a “smart”
behaviour if downloaded in the NXT robot. |
||
|
essai_aff.cop.txt |
Small
program to test decrementation of counter in a ‘for’ loop. |
||
This program is only for testing :
arrsize,arrinit,arrsubset,arrbuild |
|||
|
essai_chaine1.cop.txt |
This program is for testing
comparison of strings. |
||
|
essai_diese.cop.txt |
|
This source is only for testing
the lexical parser. |
|
|
essai_et_ou.cop.txt |
This source is only to test
‘&&’ and ‘||’ operators. |
||
|
essai_et_ou_simp.cop.txt |
This source is only to test
‘&&’ and ‘||’ operators as well. |
||
|
essai_fichier.cop.txt |
This source is for testing the file library. |
||
|
essai_fonction.cop.txt |
This source is only for testing
the syntax parser. It doesn’t have a “smart” behaviour if downloaded in the
NXT robot. It focuses on the calls of function. |
||
|
essai_fonction1.cop.txt |
|
This source is only for testing the syntax parser. It doesn’t have a “smart” behaviour if downloaded in the NXT robot. It focuses on the calls of function. |
|
|
essai_graphic.cop.txt |
This source is for testing the
graphic file library. |
||
|
essai_librairie.cop.txt |
This source is for testing the
motor and sensor libraries. |
||
|
The same as above but with defines
(eg. MOTOR_A ) |
|||
|
This source is for testing
mutexes. |
|||
|
essai_not.cop.txt |
This source is only to test !’
(=not) operator. |
||
|
essai_struc.cop.txt |
This source is only for testing the syntax parser. It doesn’t have a “smart” behaviour if downloaded in the NXT robot. It focuses on arrays and structures. |
||
|
This program is for testing
multi-dimensionnal arrays. |
|||
|
essai_tableau.cop.txt |
This program is for testing
assignment of arrays. |
||
|
This program is for testing launch
of tasks. |
|||
|
This program is for testing the
‘for’ loop. |
|||
|
This program is for testing the
‘switch’ instruction. |
|||
|
This program is for testing the
‘while’ instruction; |
|||
|
This program is for testing
structures, array of structures. |
|||
|
This program is for testing which
index is itself an array, eg. t[y[x]]; |
|||
|
This program is for testing the return
instruction. |
|||
|
This program is for testing simple
function calls where parameters are modified. |
|||
|
essai_sound.cop.txt |
This program is for testing the
“Sound” library. |
__________________________________________________________________________________________________________________________________________________________
Below, find
the specification of errors which can be dectected by COP compiler. Label of
each error is meant to help the user to fix errors ( lexical,
syntax, and semantic ).
Format of
an error :
------->
module D:\DELTA\lcc1\source\essai_fonction1.cop.txt line
21 ::
[Fatal
Error #SX2190:
Variable or function identifier is not defined] token = fonction_lib
module
in which the error is detected : D:\DELTA\lcc1\source\essai_fonction1.cop.txt
line in the
compiled module : 21
number of
the error : #SX2190
Label
of the error :
Variable or function identifier is not defined
Current parsed token : fonction_lib
These
errors can be divided into 3 categories :
-
LeXical error : LX####, detected in PASS 1 ( pre-processing ) and PASS2
( lexical parsing )
-
SyntaX error : SX####, detected in PASS 3 ( syntax parsing )
-
Code Generation error : GC#### in PASS 4 ( code generation )
To help the
debug, the C function in which errors are detected, is specified.
In red,
find additional information about errors.
LX0001 "Fatal Error #LX0001: Allocation
Memory Error"
LX0010 "Fatal Error #LX0010: Allocation
Memory Error"
LX0020 "Fatal Error #LX0020: Lexical
parsing Error"
LX0030 "Fatal Error #LX0030: Lexical
parsing Error"
LX0040 "Fatal Error #LX0040:
Missing\" as end of the string"
Eg. “string
LX0050 "Fatal Error #LX0050: Lexical
parsing Error"
LX0060 "Fatal Error #LX0060: Double
defintion of Define\n lexical parsing of
'%s' line =%d '%s' = '%s' \n already defined '%s' line '%d' '%s' = '%s'"
LX0070 "Fatal Error #LX0070: Lexical
parsing Error during parsing of 'define'"
LX0080 "Fatal Error #LX0080: File %s
doesn't exist "
LX0090 "Fatal Error #LX0090: File %s
doesn't exist for parsing of 'define' "
ajout_variable()
SX0001 "Fatal Error #SX0001: Double
declaration of a variable"
Eg.
int a,b;
int
b;
SX0010 "Fatal Error #SX0010: Unknown type
of variable" ^
Eg.
Spock a,b,c;
and Spoke is not defined.
ajout_type()
SX0020 "Fatal Error #SX0030: Double
declaration of a structure"
Eg.
struct COORD
{
int x;
int y;
};
struct COORD
{
int xx;
int yy;
};
SX0030 "Fatal Error #SX0030: Unknown
structure, internal inconsistency of the compiler"
SX0040 "Fatal Error #SX0040: Double
declaration of field in the same structure"
Eg.
struct COORD
{
int x;
int x;
};
detecte_fonction()
SX0050 "Fatal Error #SX0050: Unexpected
end of file in the global variable zone"
SX0060 "Fatal Error #SX0060: Unexpected
end of file in the global variable zone"
SX0070 "Fatal Error #SX0070: Unexpected
end of file in the global variable zone"
SX0080 "Fatal Error #SX0080: Unexpected
end of file in the global variable zone"
SX0090 "Fatal Error #SX0090: Identifier
or pointer (*) expected"
SX0100 "Fatal Error #SX0100: Unexpected
end of file in the global variable zone"
SX0110 "Fatal Error #SX0110: Unexpected
end of file in the global variable zone"
SX0120 "Fatal Error #SX0120: Unexpected
end of file in the global variable zone"
SX0130 "Fatal Error #SX0130: Unexpected
end of file in the global variable zone"
void
analyse_variable()
SX0140 "Fatal Error #SX0140: Unexpected
end of file in the variable zone"
SX0150 "Fatal Error #SX0150: Unexpected
end of file in the variable zone"
SX0160 "Fatal Error #SX0160: Identifier
of variable or '*' (pointer) expected "
SX0170 "Fatal Error #SX0170: Unexpected
end of file in the variable zone"
SX0180 "Fatal Error #SX0180: Indentifier
of variable or '*' (pointer) expected"
SX0190 "Fatal Error #SX0190: Unexpected
end of file in the variable zone"
SX0200 "Fatal Error #SX0200: Identifier
of variable is expected"
SX0210 "Fatal Error #SX0210: Unexpected
end of file in the variable zone"
SX0220 "Fatal Error #SX0220: ';' or ','
or '[' is expected"
Eg.
int a,b;
char c
int z;
SX0230 "Fatal Error #SX0230: Integer
expected"
SX0240 "Fatal Error #SX0240: dimension of
array exceeds the limit ( >10 ) "
Eg.
int a[8][8] [8] [8] [8] [8] [8] [8] [8] [8] [8];
SX0250 "Fatal Error #SX0250: Unexpected
end of file in the variable zone"
SX0260 "Fatal Error #SX0260: ']' is
expected"
E.g
int b[10;
SX0270 "Fatal Error #SX0270: Unexpected
end of file in the variable zone"
SX0280 "Fatal Error #SX0280: Unexpected
end of file in the variable zone"
SX0290 "Fatal Error #SX0290: Integer or
string expected "
SX0300 "Fatal Error #SX0300: Bad
initialization of an integer to a bad type of variable ( different from
char/byte/int/long) "
E.g
int a = “toto”;
SX0310 "Fatal Error #SX0310: Bad
initialization of a negative value to a non signed type ( char, int, long )
"
SX0320 "Fatal Error #SX0320: Value
exceeds the capacity of the char or byte "
Eg.
byte a = 65535;
SX0330 "Fatal Error #SX0330: Value
exceeds the capacity of the schar "
SX0340 "Fatal Error #SX0340: Value exceeds
the capacity of the int "
SX0350 "Fatal Error #SX0350: Value
exceeds the capacity of the sint "
SX0360 "Fatal Error #SX0360: Value
exceeds the capacity of the long "
SX0370 "Fatal Error #SX0370: Value
exceeds the capacity of the slong "
SX0380 "Fatal Error #SX0380: Bad
initialization of a float "
SX0390 "Fatal Error #SX0390: Bad
initialisation of a string to a non string type of variable"
SX0400 "Fatal Error #SX0400: Bad
initialization of a string to an array which dimension is above 1 "
Eg.
char t[10][10] = “kirk”;
SX0410 "Fatal Error #SX0410: Bad
initialization of a string which length exceeds the size of the array of char
"
SX0420 "Fatal Error #SX0420: Unexpected
end of file in the variable zone"
SX0430 "Fatal Error #SX0430: ',' is
expected "
SX0440 "Fatal Error #SX0440: Unexpected
end of file in the variable zone"
SX0450 "Fatal
Error #SX0450: Identifier of sructure is expected "
Eg.
struct
{
int
a;
}
SX0460 "Fatal Error #SX0460: Unexpected
end of file in the variable zone"
SX0470 "Fatal Error #SX0470: '[' is
expected "
SX0480 "Fatal Error #SX0480: Too many
fileds in the definition of the structure "
SX0490 "Fatal Error #SX0490: Unexpected
end of file in the variable zone"
SX0500 "Fatal Error #SX0500: Unexpected
end of file in the variable zone"
SX0510 "Fatal Error #SX0510: Erreur
Fatale #S0048 : identifier of field or '*' (pointer) is expected "
SX0520 "Fatal Error #SX0520: Unexpected
end of file in the variable zone"
SX0530 "Fatal
Error #SX0530: Erreur Fatale #S0050 : identifier of filed or '*' (pointer) is
expected "
SX0540 "Fatal Error #SX0540: Unexpected
end of file in the variable zone"
SX0550 "Fatal Error #SX0550: Identifier
of field is expected "
SX0560 "Fatal Error #SX0560: Unexpected
end of file in the variable zone"
SX0570 "Fatal Error #SX0570: ';' or ','
or '[' is expected "
SX0580 "Fatal Error #SX0580: Integer is
expected "
SX0590 "Fatal Error #SX0590: Dimension of
array exceeds the limit ( >10 ) "
SX0600 "Fatal Error #SX0600: Unexpected
end of file in the variable zone"
SX0610 "Fatal Error #SX0610: ']' is
expected "
SX0620 "Fatal Error #SX0620: ',' is
expected "
SX0630 "Fatal Error #SX0630: Unexpected
end of file in the variable zone"
SX0640 "Fatal Error #SX0640: Bad
definition of structure, no field defined"
SX0650 "Fatal Error #SX0650: Unexpected
end of file in the variable zone"
SX0660 "Fatal Error #SX0660: ';' is
expected "
SX0670 "Fatal Error #SX0670: Syntax Error
in the variale zone "
compatibilite_type()
SX0675 "Warning Error #SX0675: Types not
compatible in expression "
nouvelle_expression()
SX0680 "Fatal Error #SX0680: Allocation
Memory Error"
SX0690 "Fatal Error #SX0690: Types not
compatible in expression "
SX0700 "Fatal Error #SX0700: Unknown
Function in the expression "
SX0710 "Fatal Error #SX0710: Unknown type
in the expression "
analyse_synt_variable_recursive()
SX0720 "Fatal Error #SX0720: Unexpected
end of file in the variable zone"
SX0730 "Fatal Error #SX0730: Allocation
Memory Error"
SX0740 "Fatal Error #SX0740: The number
of dimension of array exceeds the declared dimension"
SX0750 "Fatal Error #SX0750: Unexpected
end of file in the variable zone"
SX0760 "Fatal Error #SX0760: ']' is
expected "
SX0770 "Fatal Error #SX0770: Unexpected
end of file in the variable zone"
SX0780 "Fatal Error #SX0780: Dimension(s)
is/are missing in the use of an array "
SX0790 "Fatal Error #SX0790: Unexpected
end of file in the variable zone"
SX0800 "Fatal Error #SX0800: Allocation
Memory Error"
SX0810 "Fatal Error #SX0810: The number
of dimension of array exceeds the declared dimension"
SX0820 "Fatal Error #SX0820: Unexpected end
of file in the variable zone"
SX0830 "Fatal Error #SX0830: ']' is
expected "
SX0840 "Fatal Error #SX0840: Unexpected
end of file in the variable zone"
SX0850 "Fatal Error #SX0850: Dimension(s)
is/are missing in the use of an array as field"
SX0860 "Fatal Error #SX0860: Unexpected
end of file in the variable zone"
SX0870 "Fatal Error #SX0870: This
variable or field is not an array "
SX0880 "Fatal Error #SX0880: The type of
this variable is not a structure "
SX0890 "Fatal Error #SX0890: Unexpected
end of file in the variable zone"
SX0900 "Fatal Error #SX0900: An
identifier of a field of a structure is expected "
SX0910 "Fatal Error #SX0910: Identifier
of field is not declared "
SX0920 "Fatal Error #SX0920: Allocation Memory
Error"
SX0930 "Fatal Error #SX0930: Identifier
of field is not declared "
SX0940 "Fatal Error #SX0940: Allocation
Memory Error"
SX0950 "Fatal Error #SX0950: Unexpected
end of file in the variable zone"
analyse_synt_variable()
SX0960 "Fatal Error #SX0960: Identifier
of variable is not declared "
SX0970 "Fatal Error #SX0970: Allocation
Memory Error"
analyse_synt_fonction()
SX0980 "Fatal Error #SX0980: Unexpected
end of file in the expression/function"
SX0990 "Fatal Error #SX0990: '(' is
expected in the function call"
SX1000 "Fatal Error #SX1000: Unexpected
end of file in the expression/function"
SX1010 "Fatal Error #SX1010: Unexpected
end of file in the expression/function"
SX1020 "Fatal Error #SX1020: ',' or ')'
is expected in the function call "
analyse_fonction_ou_variable()
SX1030 "Fatal Error #SX1030: Unexpected
end of file in the ++/-- pattern"
SX1040 "Fatal Error #SX1040: Unexpected
end of file in the expression"
SX1050 "Fatal Error #SX1050: Variable or
function is not declared in the expression "
analyse_indirection()
SX1060 "Fatal Error #SX1060: Unexpected
end of file in the *(ptr+index) pattern"
SX1070 "Fatal Error #SX1070: Identifier
of pointer is expected in the *(ptr + index) pattern "
SX1080 "Fatal Error #SX1080: The pointer
is not declared in the *(ptr + index ) pattern"
SX1090 "Fatal Error #SX1090: The variable
is not a pointer in the *(ptr+ index ) pattern "
SX1100 "Fatal Error #SX1100: Unexpected
end of file in the *(ptr+index) pattern"
SX1110 "Fatal Error #SX1110: '+' is
expected in the *(ptr + index ) pattern"
SX1120 "Fatal Error #SX1120: Unexpected
end of file in the *(ptr+index) pattern"
SX1130 "Fatal Error #SX1130: ')' is expected
in the *(ptr + index) pattern"
analyse_atome()
SX1140 "Fatal Error #SX1140: Unexpected
end of file in the expression pattern"
SX1150 "Fatal Error #SX1150: Unexpected
end of file in the expression pattern"
SX1160 "Fatal Error #SX1160: Unexpected
end of file in the expression pattern"
SX1170 "Fatal Error #SX1170: Unexpected
end of file in the expression pattern"
SX1180 "Fatal Error #SX1180: Unexpected
end of file in the expression pattern"
SX1190 "Fatal Error #SX1190: Unexpected
end of file in the expression pattern"
analyse_atome_neg()
SX1200 "Fatal Error #SX1200: Unexpected
end of file in the 'neg' pattern"
analyse_atome_non()
SX1210 "Fatal Error #SX1210: Unexpected
end of file in the 'not' pattern"
analyse_recursive_shr_shl()
SX1220 "Fatal Error #SX1220: Unexpected
end of file in the 'shr'/'shl' pattern"
analyse_recursive()
SX1230 "Fatal Error #SX1230: Unexpected
end of file in the expression pattern"
analyse_recursive_expression_arithmetique()
SX1240 "Fatal Error #SX1240: Unexpected
end of file in the arithmetic operator pattern"
analyse_recursive_expression_comparaison()
SX1250 "Fatal Error #SX1250: Unexpected
end of file in the comparison operator pattern"
analyse_recursive_expression_logique_et()
SX1260 "Fatal Error #SX1260: Unexpected
end of file in the logical operator && pattern"
analyse_recursive_expression_logique_ou()
SX1270 "Fatal Error #SX1270: Unexpected
end of file in the logical operator || pattern"
analyse_affectation()
SX1280 "Fatal Error #SX1280: Unexpected
end of file in the assignment pattern"
SX1290 "Fatal Error #SX1290: Unexpected
end of file in the assignment pattern"
SX1300 "Fatal Error #SX1300: Unexpected
end of file in the assignment pattern"
SX1310 "Fatal Error #SX1310: '=' is
expected "
SX1320 "Fatal Error #SX1320: Unexpected
end of file in the assignment pattern"
SX1330 "Fatal Error #SX1330: ')' is not
expected"
SX1340 "Fatal Error #SX1340: ';' is not
expected"
SX1350 "Fatal Error #SX1350: Allocation
Memory Error"
analyse_if()
SX1360 "Fatal Error #SX1360: Unexpected
end of file in the 'if' pattern"
SX1370 "Fatal Error #SX1370: '(' is
expected in the 'if' pattern"
SX1380 "Fatal Error #SX1380: Unexpected
end of file in the 'if' pattern"
SX1390 "Fatal Error #SX1390: ')' is
expected in the 'if' pattern "
SX1400 "Fatal Error #SX1400: Unexpected
end of file in the 'if' pattern"
SX1410 "Fatal Error #SX1410: Unexpected
end of file in the 'if' pattern"
analyse_for()
SX1420 "Fatal Error #SX1420: Unexpected
end of file in the 'for' pattern"
SX1430 "Fatal Error #SX1430: '(' is
expected in the 'for' pattern "
SX1440 "Fatal Error #SX1440: Unexpected
end of file in the 'for' pattern"
SX1450 "Fatal Error #SX1450: Unexpected
end of file in the 'for' pattern"
SX1460 "Fatal Error #SX1460: Unexpected
end of file in the 'for' pattern"
SX1470 "Fatal Error #SX1470: ';' is
expected in the 'for' pattern"
SX1480 "Fatal Error #SX1480: Unexpected
end of file in the 'for' pattern"
SX1490 "Fatal Error #SX1490: ';' is
expected in the 'for pattern"
SX1500 "Fatal Error #SX1500: Unexpected
end of file in the 'for' pattern"
SX1510 "Fatal Error #SX1510: Unexpected
end of file in the 'for' pattern"
SX1520 "Fatal Error #SX1520: Unexpected
end of file in the 'for' pattern"
SX1530 "Fatal Error #SX1530: ')' is
expected in the 'for' pattern"
SX1540 "Fatal Error #SX1540: Unexpected
end of file in the 'for' pattern"
analyse_do_while()
SX1550 "Fatal Error #SX1550: Unexpected
end of file in the 'while' pattern"
SX1560 "Fatal Error #SX1560: 'while' is
expected in the 'while' pattern"
SX1570 "Fatal Error #SX1570: Unexpected
end of file in the 'while' pattern"
SX1580 "Fatal Error #SX1580: '(' is
expected in the 'while' pattern"
SX1590 "Fatal Error #SX1590: Unexpected
end of file in the 'while' pattern"
SX1600 "Fatal Error #SX1600: ')' is
expected in the 'while' pattern"
SX1610 "Fatal Error #SX1610: Unexpected
end of file in the 'while' pattern"
SX1620 "Fatal Error #SX1620: ';' is
expected in hte 'while' pattern"
SX1630 "Fatal Error #SX1630: Unexpected
end of file in the 'while' pattern"
analyse_goto()
SX1640 "Fatal Error #SX1640: Unexpected
end of file in the 'goto' pattern"
SX1650 "Fatal Error #SX1650: Unexpected
end of file in the 'goto' pattern"
SX1660 "Fatal Error #SX1660: ';' is
expected in the 'goto' pattern"
SX1670 "Fatal Error #SX1670: Unexpected
end of file in the 'goto' pattern"
SX1680 "Fatal Error #SX1680: identifier
of label expected in the 'goto' pattern "
analyse_return()
SX1690 "Fatal Error #SX1690: 'return' in
an inappropriate body ( function only )"
SX1700 "Fatal Error #SX1700: Unexpected
end of file in the 'return' pattern"
SX1710 "Fatal Error #SX1710: '(' is
expected in the 'return' pattern "
SX1720 "Fatal Error #SX1720: Unexpected
end of file in the 'return' pattern"
SX1730 "Fatal Error #SX1730: ')' expected
in the 'return' pattern"
SX1740 "Fatal Error #SX1740: Unexpected
end of file in the 'return' pattern"
SX1750 "Fatal Error #SX1750: Unexpected
end of file in the 'return' pattern"
analyse_break()
SX1760 "Fatal Error #SX1760: Incorrect
use of 'break', no 'while' or 'for' loop"
SX1765 "Fatal Error #SX1765: Unexpected
end of file in the 'break' pattern"
SX1770 "Fatal Error #SX1770: ';' is
expected in the 'break' pattern "
SX1780 "Fatal Error #SX1780: Unexpected
end of file in the 'break' pattern"
analyse_continue()
SX1790 "Fatal Error #SX1790: Incorrect
use of 'continue', no 'while' or 'for' loop"
SX1800 "Fatal Error #SX1800: Unexpected
end of file in the 'continue' pattern"
SX1810 "Fatal Error #SX1810: ';' is
expected "
SX1820 "Fatal Error #SX1820: Unexpected
end of file in the 'continue' pattern"
analyse_switch()
SX1830 "Fatal Error #SX1830: Unexpected
end of file in the 'switch' pattern"
SX1840 "Fatal Error #SX1840: '{' is
expected in the 'switch' pattern"
SX1850 "Fatal Error #SX1850: Unexpected
end of file in the 'switch' pattern"
SX1855 "Fatal Error #SX1855: 'case' or
'default' is expected in the 'switch' pattern"
SX1857 "Fatal Error #SX1857: Unexpected
end of file in the 'switch' pattern"
SX1860 "Fatal Error #SX1860: Unexpected
end of file in the 'switch' pattern"
SX1870 "Fatal Error #SX1870: ':' is
expected after 'case' or 'default' in the 'switch' pattern"
SX1880 "Fatal Error #SX1880: Unexpected
end of file in the 'switch' pattern"
SX1890 "Fatal Error #SX1890: Unexpected
end of file in the 'switch' pattern"
SX1900 "Fatal Error #SX1900: ';' is
expected in the 'switch' pattern"
SX1910 "Fatal Error #SX1910: Unexpected
end of file in the 'switch' pattern"
SX1920 "Fatal Error #SX1920: Unexpected
end of file in the 'switch' pattern"
SX1930 "Fatal Error #SX1930: ';' is
expected after 'case' or 'default' in the 'switch' pattern"
SX1940 "Fatal Error #SX1940: Unexpected
end of file in the 'switch' pattern"
SX1950 "Fatal Error #SX1950: Number of
'case' too important in the 'switch' pattern"
SX1960 "Fatal Error #SX1960: Unexpected end
of file in the 'switch' pattern"
analyse_exit()
SX1970 "Fatal Error #SX1970: Unexpected
end of file in the 'exit' pattern"
SX1980 "Fatal Error #SX1980: '(' is
expected in the 'exit' pattern"
SX1990 "Fatal Error #SX1990: Unexpected
end of file in the 'exit' pattern"
SX2000 "Fatal Error #SX2000: ')' is
expected in the 'exit' pattern"
SX2010 "Fatal Error #SX2010: Unexpected
end of file in the 'exit' pattern"
SX2020 "Fatal Error #SX2020: ';' is
expected in the 'exit' pattern"
SX2030 "Fatal Error #SX2030: Unexpected
end of file in the 'exit' pattern"
analyse_precedes()
SX2040 "Fatal Error #SX2040: Unexpected
end of file in the 'precedes' pattern"
SX2050 "Fatal Error #SX2050: Too many
tasks in the 'precede' pattern"
SX2060 "Fatal Error #SX2060: Unexpected
end of file in the 'precedes' pattern"
SX2070 "Fatal Error #SX2070: ',' or ';'
is expected in the 'precedes' pattern"
SX2080 "Fatal Error #SX2080: Unexpected
end of file in the 'precedes' pattern"
SX2090 "Fatal Error #SX2090: Identifier
of 'task' is expected "
SX2100 "Fatal Error #SX2100: Unexpected
end of file in the 'precedes' pattern"
analyse_lident()
SX2110 "Fatal Error #SX2110: Unexpected
end of file in the 'Identifier' pattern ( label,
variable, function )"
SX2120 "Fatal Error #SX2120: Unexpected
end of file in the 'Identifier' pattern ( label, variable, function )"
SX2130 "Fatal Error #SX2130: Unexpected
end of file in the 'Identifier' pattern ( label, variable, function )"
SX2140 "Fatal Error #SX2140: Unexpected
end of file in the 'Identifier' pattern ( label, variable, function )"
SX2150 "Fatal Error #SX2150: Unexpected
end of file in the 'Identifier' pattern ( label, variable, function )"
SX2160 "Fatal Error #SX2160: ';' is
expected after assignment"
SX2170 "Fatal Error #SX2170: Unexpected
end of file in the 'Assignment' pattern"
SX2180 "Fatal Error #SX2180: Indirection
'*' or '**' of function doesn't exist "
SX2190 "Fatal Error #SX2190: Variable or
function identifier is not defined"
SX2200 "Fatal Error #SX2200: ')' is
expected"
SX2210 "Fatal Error #SX2210: Unexpected
end of file in the call of function"
SX2220 "Fatal Error #SX2220: ';' is
expected after the call of function"
SX2230 "Fatal Error #SX2230: Unexpected
end of file in the call of function"
analyse_pointeur()
SX2240 "Fatal Error #SX2240: Unexpected
end of file in the '*(variable+index)' pattern"
SX2250 "Fatal Error #SX2250: ';' is
expected after assignment "
SX2260 "Fatal Error #SX2260: ';' is
expected after assignment "
SX2270 "Fatal Error #SX2270: Unexpected
end of file in the 'Assignment' pattern"
SX2280 "Fatal Error #SX2280: Allocation
Memory Error"
analyse_inline()
SX2290 "Fatal Error #SX2290: Unexpected
end of file in the 'inline' pattern"
SX2300 "Fatal Error #SX2300: nbc
instruction is expected in the 'inline' pattern"
SX2310 "Fatal Error #SX2310: Unexpected
end of file in the 'inline' pattern"
SX2320 "Fatal Error #SX2320: ';' is
expected in the 'inline' pattern"
SX2340 "Fatal Error #SX2340: Unexpected
end of file in the 'inline' pattern"
analyse_acquire()
SX2350 "Fatal Error #SX2350: Unexpected
end of file in the 'acquire' pattern"
SX2360 "Fatal Error #SX2360: '(' is
expected in the 'acquire' pattern"
SX2370 "Fatal Error #SX2370: Unexpected
end of file in the 'acquire' pattern"
SX2380 "Fatal Error #SX2380: Mutex
Identifier is expected in the 'acquire' pattern"
SX2390 "Fatal Error #SX2390: Unexpected
end of file in the 'acquire' pattern"
SX2400 "Fatal Error #SX2400: ')' is
expected in the 'acquire' pattern"
SX2410 "Fatal Error #SX2410: Unexpected
end of file in the 'acquire' pattern"
SX2420 "Fatal Error #SX2420: ';' is
expected in the 'acquire' pattern"
SX2430 "Fatal Error #SX2430: Unexpected
end of file in the 'acquire' pattern"
analyse_release()
SX2440 "Fatal Error #SX2440: Unexpected
end of file in the 'release' pattern "
SX2450 "Fatal Error #SX2450: '(' is
expected in the 'release' pattern "
SX2460 "Fatal Error #SX2460: Unexpected
end of file in the 'release' pattern"
SX2470 "Fatal Error #SX2470: Mutex
Identifier in the 'release' pattern"
SX2480 "Fatal Error #SX2480: Unexpected
end of file in the 'release' pattern"
SX2490 "Fatal Error #SX2490: ')' is
expected in the in the 'release' pattern"
SX2500 "Fatal Error #SX2500: Unexpected
end of file in the 'release' pattern"
SX2510 "Fatal Error #SX2510: ';' is
expected in the 'release' pattern"
SX2520 "Fatal Error #SX2520: Unexpected
end of file in the 'release' pattern"
analyse_arrsize()
SX2530 "Fatal Error #SX2530: Unexpected
end of file in the 'arrsize' pattern "
SX2540 "Fatal Error #SX2540: '(' is
expected in the 'arrsize' pattern"
SX2560 "Fatal Error #SX2560: Unexpected
end of file in the 'arrsize' pattern "
SX2570 "Fatal Error #SX2570: Identifier
of array is expected in the 'arrsize' pattern"
SX2580 "Fatal Error #SX2580: Unexpected
end of file in the 'arrsize' pattern "
SX2590 "Fatal Error #SX2590: ',' is
expected in the 'arrsize' pattern"
SX2600 "Fatal Error #SX2600: Unexpected
end of file in the 'arrsize' pattern "
SX2610 "Fatal Error #SX2610: Identifier
of array is expected in the 'arrsize' pattern"
SX2620 "Fatal Error #SX2620: Unexpected
end of file in the 'arrsize' pattern "
SX2630 "Fatal Error #SX2630: ')' is
expected in the 'arrsize' pattern"
SX2640 "Fatal Error #SX2640: Unexpected
end of file in the 'arrsize' pattern "
SX2650 "Fatal Error #SX2650: ';' is
expected in the 'arrsize' pattern"
SX2660 "Fatal Error #SX2660: Unexpected
end of file in the 'arrsize' pattern "
SX2670 "Fatal Error #SX2670: Identifier
of array not defined in the 'arrsize' pattern"
SX2680 "Fatal Error #SX2680: the
identifier '%s' size is not declared in the 'arrsize' pattern"
SX2690 "Fatal Error #SX2690: the
identifier '%s' array is not declared in the 'arrsize' pattern"
SX2700 "Fatal Error #SX2700: the type of
the identifier '%s' size is not an integer in the 'arrsize' pattern "
analyse_arrinit()
SX2710 "Fatal Error #SX2710: Unexpected
end of file in the 'arrinit' pattern "
SX2720 "Fatal Error #SX2720: '(' is
expected in the 'arrinit' pattern "
SX2730 "Fatal Error #SX2730: Unexpected
end of file in the 'arrinit' pattern "
SX2740 "Fatal Error #SX2740: Identifier
of array is expected in the 'arrinit' pattern "
SX2750 "Fatal Error #SX2750: Unexpected
end of file in the 'arrinit' pattern "
SX2760 "Fatal Error #SX2760: ',' is
expected in the 'arrinit' pattern "
SX2770 "Fatal Error #SX2770: Unexpected
end of file in the 'arrinit' pattern "
SX2780 "Fatal Error #SX2780: ',' is
expected in the 'arrinit' pattern "
SX2790 "Fatal Error #SX2790: Unexpected
end of file in the 'arrinit' pattern "
SX2800 "Fatal Error #SX2800: ')' is
expected in the 'arrinit' pattern "
SX2810 "Fatal Error #SX2810: Unexpected
end of file in the 'arrinit' pattern "
SX2820 "Fatal Error #SX2820: ';' is
expected in the 'arrinit' pattern "
SX2830 "Fatal Error #SX2830: Unexpected
end of file in the 'arrinit' pattern "
SX2840 "Fatal Error #SX2840: the
identifier '%s' array is not declared in the 'arrinit' pattern"
SX2850 "Fatal Error #SX2850: the
identifier '%s' array is not an array or a pointer (*) in the 'arrinit'
pattern"
analyse_arrsubset()
SX2860 "Fatal Error #SX2860: Unexpected
end of file in the 'arrsubset' pattern "
SX2870 "Fatal Error #SX2870: '(' is
expected in the 'arrsubset' pattern "
SX2880 "Fatal Error #SX2880: Unexpected
end of file in the 'arrsubset' pattern "
SX2890 "Fatal Error #SX2890: Identifier
of array is expected in the 'arrsubset' pattern "
SX3000 "Fatal Error #SX3000: Unexpected
end of file in the 'arrsubset' pattern "
SX3010 "Fatal Error #SX3010: ',' is
expected in the 'arrsubset' pattern"
SX3020 "Fatal Error #SX3020: Unexpected
end of file in the 'arrsubset' pattern "
SX3030 "Fatal Error #SX3030: Identifier
of array is expected in the 'arrsubset' pattern"
SX3040 "Fatal Error #SX3040: Unexpected
end of file in the 'arrsubset' pattern "
SX3050 "Fatal Error #SX3050: ',' is
expected in the 'arrsubset' pattern "
SX3060 "Fatal Error #SX3060: Unexpected
end of file in the 'arrsubset' pattern "
SX3070 "Fatal Error #SX3070: ',' is
expected in the 'arrsubset' pattern "
SX3080 "Fatal Error #SX3080: Unexpected
end of file in the 'arrsubset' pattern "
SX3090 "Fatal Error #SX3090: ')' is
expected in the 'arrsubset' pattern "
SX3100 "Fatal Error #SX3100: Unexpected
end of file in the 'arrsubset' pattern "
SX3110 "Fatal Error #SX3110: ';' is
expected in the 'arrsubset' pattern"
SX3120 "Fatal Error #SX3120: Unexpected
end of file in the 'arrsubset' pattern "
SX3130 "Fatal Error #SX3130: the
identifier '%s' src array is not declared in the 'arrsubset' pattern"
SX3140 "Fatal Error #SX3140: the
identifier '%s' dst array is not declared in the 'arrsubset' pattern"
SX3150 "Fatal Error #SX3150: the
identifier '%s' src array is not an array or pointer (*) in the 'arrsubset'
pattern"
SX3160 "Fatal Error #SX3160: the
identifier '%s' dst array is not an array or pointer (*) in the 'arrsubset'
pattern"
analyse_arrbuild()
SX3170 "Fatal Error #SX3170: Unexpected
end of file in the 'arrbuild' pattern "
SX3180 "Fatal Error #SX3180: '(' is
expected in the 'arrbuild' pattern "
SX3190 "Fatal Error #SX3190: Unexpected
end of file in the 'arrbuild' pattern "
SX3200 "Fatal Error #SX3200: Too many
identifiers in the 'arrbuild' pattern "
SX3210 "Fatal Error #SX3210: Identifier
of array is expected in the 'arrbuild' pattern "
SX3220 "Fatal Error #SX3220: Unexpected
end of file in the 'arrbuild' pattern "
SX3230 "Fatal Error #SX3230: Unexpected
end of file in the 'arrbuild' pattern "
SX3240 "Fatal Error #SX3240: ')' is
expected in the arrbuild 'pattern' "
SX3250 "Fatal Error #SX3250: Unexpected
end of file in the 'arrbuild' pattern "
SX3260 "Fatal Error #SX3260: ';' is
expected in the 'arrbuild' pattern "
SX3270 "Fatal Error #SX3270: Unexpected
end of file in the 'arrbuild' pattern "
SX3280 "Fatal Error #SX3280: the
identifier '%s' size is not declared in the 'arrbuild' pattern"
SX3290 "Fatal Error #SX3290: the
identifier '%s' array is not an array or pointer (*) in the 'arrbuild'
pattern"
analyse_liste_instruction()
SX3300 "Fatal Error #SX3300: Unexpected
end of file in the 'list of instructions' pattern "
SX3310 "Fatal Error #SX3310: Unexpected
end of file in the 'list of instructions' pattern "
SX3320 "Fatal Error #SX3320: Allocation
Memory Error"
SX3340 "Fatal Error #SX3340: Bad format
of instruction "
SX3350 "Fatal Error #SX3350: Allocation
Memory Error"
SX3360 "Fatal Error #SX3360: Bad format
of instruction"
analyse_fonction()
SX3370 "Fatal Error #SX3370: Unexpected
end of file in the 'function type' pattern "
SX3380 "Fatal Error #SX3380: Unexpected
end of file in the 'function type' pattern "
SX3390 "Fatal Error #SX3390: An
identifier of type is expected in the 'function' pattern "
SX3400 "Fatal Error #SX3400: The returned
type is not defined in the 'function' pattern "
SX3410 "Fatal Error #SX3410: Unexpected
end of file in the 'function' pattern "
SX3420 "Fatal Error #SX3420: A pointer
(*) or a pointer of pointer (**) is expected "
SX3430 "Fatal Error #SX3430: Unexpected
end of file in the 'function type' pattern "
SX3440 "Fatal Error #SX3440: A pointer
(*) or a pointer of pointer (**) is expected "
SX3450 "Fatal Error #SX3450: Unexpected
end of file in the 'function type' pattern "
SX3460 "Fatal Error #SX3460: ')' is
expected in the 'function' pattern"
SX3470 "Fatal Error #SX3470: Unexpected
end of file in the 'function type' pattern "
SX3480 "Fatal Error #SX3480: The returned
type is not defined in the 'function' pattern"
SX3490 "Fatal Error #SX3490: The returned
type is not defined in the 'function' pattern"
SX3500 "Fatal Error #SX3500: Unexpected
end of file in the 'function type' pattern "
SX3510 "Fatal Error #SX3510: An
identifier of function is expected in the 'function' pattern"
SX3520 "Fatal Error #SX3520: Double
declaration of function in the 'function' pattern"
SX3530 "Fatal Error #SX3530: Unexpected
end of file in the 'function type' pattern "
SX3540 "Fatal Error #SX3540: '(' is
expected in the 'function (argument) pattern"
SX3550 "Fatal Error #SX3550: Unexpected
end of file in the 'function(argument)' pattern "
SX3560 "Fatal Error #SX3560: Unexpected
end of file in the 'function(mod argument)' pattern "
SX3570 "Fatal Error #SX3570: The type of
the argument is not defined in the 'function(argument) pattern"
SX3580 "Fatal Error #SX3580: Unexpected
end of file in the 'function(argument)' pattern "
SX3590 "Fatal Error #SX3590: A pointer
(*) or a pointer of pointer (**) is expected in the 'function' pattern "
SX3600 "Fatal Error #SX3600: Unexpected
end of file in the 'function(argument)' pattern "
SX3610 "Fatal Error #SX3610: An
identifier of argument or a pointer of pointer (**) is expected in the
'function' pattern"
SX3620 "Fatal Error #SX3620: Unexpected
end of file in the 'function(argument)' pattern "
SX3630 "Fatal Error #SX3630: An
identifier of argument is expected in the 'function' pattern"
SX3640 "Fatal Error #SX3640: Unexpected
end of file in the 'function(argument)' pattern "
SX3650 "Fatal Error #SX3650: A ',' or ')'
is expected in the 'function' pattern"
SX3660 "Fatal Error #SX3660: Unexpected
end of file in the 'function' pattern "
SX3670 "Fatal Error #SX3670: A '{' is
expected as a begin of the body of the function"
SX3680 "Fatal Error #SX3680: A '}' is
expected as an end of body of the function"
analyse_mutex()
SX3690 "Fatal Error #SX3690: Unexpected
end of file in the 'mutex' pattern "
SX3700 "Fatal Error #SX3700: An
identifier of mutex is expected in the 'mutex' pattern"
SX3710 "Fatal Error #SX3710: Double
declaration of mutex '%s', module '%s' - line '%d' / module '%s' - line '%d'
"
SX3720 "Fatal Error #SX3720: ',' or ';'
is expected in the 'mutex' pattern"
SX3730 "Fatal Error #SX3730: ',' is
expected in the 'mutex' pattern"
analyse_tache()
SX3740 "Fatal Error #SX3740: Unexpected
end of file in the 'task' pattern "
SX3750 "Fatal Error #SX3750: Identifier
of task is expected "
SX3760 "Fatal Error #SX3760: Unexpected
end of file in the 'task' pattern "
SX3770 "Fatal Error #SX3770: '(' is
expected in the 'task' pattern "
SX3780 "Fatal Error #SX3780: Unexpected
end of file in the 'task' pattern "
SX3790 "Fatal Error #SX3810: ')' is
expected in the 'task' pattern"
SX3800 "Fatal Error #SX3800: Unexpected
end of file in the 'task' pattern "
SX3810 "Fatal Error #SX3810: A '{' is
expected as a begin of the body of the task"
SX3820 "Fatal Error #SX3820: A '}' is
expected as an end of body of the task"
GC0001 "Fatal Error #GC0001: Internal
error, value of the Stack Pointer dedicated to Loops exceed the limit (>1000)"
GC0020 "Fatal Error #GC0020: Internal
error, negative value of the Stack Pointer dedicated to Loops (<-1) "
GC0030 "Fatal Error #GC0030: Internal
error, negative value of the Stack Pointer dedicated to Loops (<0) "
GC0040 "Fatal Error #GC0040: bloc=%s
variable=%s type=%s dimension of the expression %d is incorrect"
GC0050 "Fatal Error #GC0050: bloc=%s
variable=%s type=%s dimension of the expression %d is incorrect"
GC0060 "Fatal Error #GC0060: bloc=%s
variable=%s type=%s expression not compliant with '++'"
GC0070 "Fatal Error #GC0070: bloc=%s variable=%s
type=%s expression not compliant with '--'"
GC0080 "Fatal Error #GC0080: bloc=%s
typeg=%s typed=%s typer=%s "
GC0090 "Fatal Error #GC0090: bloc=%s
type=%s not compliant with the types of operator 'SHL' "
GC0100 "Fatal Error #GC0100: bloc=%s type=%s
not compliant with the types of operator 'SHR' "
GC0110 "Fatal Error #GC0110: bloc=%s
type=%s not compliant with the types of operator 'MUL' "
GC0120 "Fatal Error #GC0120: bloc=%s
type=%s not compliant with the types of operator 'DIV' "
GC0130 "Fatal Error #GC0130: bloc=%s
type=%s not compliant with the types of operator'MODULO' "
GC0140 "Fatal Error #GC0140: bloc=%s
type=%s not compliant with the types of operator 'PLUS' "
GC0150 "Fatal Error #GC0150: bloc=%s
type=%s not compliant with the types of operator 'MINUS' "
GC0160 "Fatal Error #GC0160: bloc=%s
type=%s not compliant with the types of operator '<' "
GC0170 "Fatal Error #GC0170: bloc=%s
type=%s not compliant with the types of operator '>' "
GC0180 "Fatal Error #GC0180: bloc=%s
type=%s not compliant with the types of operator '<=' "
GC0190 "Fatal Error #GC0190: bloc=%s
type=%s not compliant with the types of operator '>=' "
GC0200 "Fatal Error #GC0200: bloc=%s
type=%s not compliant with the types of operator '|' "
GC0210 "Fatal Error #GC0210: bloc=%s
type=%s not compliant with the types of operator '&' "
GC0220 "Fatal Error #GC0220: bloc=%s
type=%s not compliant with the types of operator '!' "
GC0230 "Fatal Error #GC0230: bloc=%s
type=%s not compliant with the types of operator '- unaire' "
GC0240 "Fatal Error #GC0240: bloc=%s
type=%s not compliant with the types of operator '++' "
GC0250 "Fatal Error #GC0250: bloc=%s
type=%s not compliant with the types of operator '--' "
GC0260 "Fatal Error #GC0260: bloc=%s
function '%s' is not defined "
GC0270 "Fatal Error #GC0270: bloc=%s
fonction '%s' missing parameter(s) %d/%d "
GC0280 "Fatal Error #GC0280: bloc=%s
function '%s' types '%s' not compliant with the type '%s' of parameter '%s'
"
GC0290 "Fatal Error #GC0290: bloc=%s
function'%s', type of the variable '%s' not compliant with the type '%s' of
parameter '%s' "
GC0300 "Fatal Error #GC0300: bloc=%s
type=%s not compliant in the instruction 'while'"
GC0310 "Fatal Error #GC0310: bloc=%s
type=%s not compliant in the instruction 'for' (initialization)"
GC0320 "Fatal Error #GC0320: bloc=%s
type=%s not compliant in the instruction 'for' (test)"
GC0330 "Fatal Error #GC0330: bloc=%s
type=%s not compliant in the instruction 'for' (increment)"
GC0340 "Fatal Error #GC0340: bloc=%s
type=%s not compliant in the instruction 'if'"
GC0350 "Fatal Error #GC0350: Goto '%s' is
not defined in function/task = '%s'"
GC0360 "Fatal Error #GC0360: Double
definition of label '%s' in function/task = '%s'"
GC0370 "Fatal Error #GC0370: Unknown task
'%s' used as parameter by 'precede' in '%s'"
GC0380 "Fatal Error #GC0380: bloc=%s
type=%s bad type for the 'switch'"
GC0390 "Fatal Error #GC0390: bloc=%s
type=%s bad type for the 'switch'"
GC0400 "Fatal Error #GC0400: bloc '%s' -
Unknown mutex '%s' in the call of 'Acquire()'"
GC0410 "Fatal Error #GC0410: bloc '%s' -
Unknown mutex '%s' in the call of 'Release()'"
GC0420 "Fatal Error #GC0420: bloc=%s
type=%s not compliant with the type of the parameter 'size' "
GC0430 "Fatal Error #GC0430: bloc=%s
type=%s not compliant with the type of the parameter 'index' "
GC0440 "Fatal Error #GC0440: bloc=%s
type=%s not compliant with the type of the parameter 'length' "
GC0450 "Fatal Error #GC0450: Unknow
function '%s'"
GC0460 "Fatal Error #GC0460: Functionn
'%s', returns a bad type '%s' : '%s'"
GC0470 "Fatal Error #GC0470: Function
'%s', returns a bad type '%s' : '%s'"
GC0480 "Fatal Error #GC0480: Incorrect
assignment of a void type to the variable '%s' "
GC0490 "Fatal Error #GC0490: Incorrect
assignment of a void type to the variable '%s' "
GC0500 "Fatal Error #GC0500: Failure of
the creation of the '.nbc' file"
__________________________________________________________________________________________________________________________________________________________
Download
this zip file to get the entire binairy, library and examples of COP sources : package
Below the C
sources of the COP compiler.
|
Name of
file |
File ( click
on it to download ) |
Type |
Comments |
|
cop.c |
.C source |
Main
module which manages GUI and calls to other modules |
|
|
lexical.c |
.C source |
Lexical
parsing |
|
|
syntaxique.c |
.C source |
Syntaxical
parsing |
|
|
genere_code.c |
.C source |
Generation of COP codes |
|
|
delta_encrier.h |
.H source |
Defines and C structures |
|
|
.EXE executable |
Executable file |
__________________________________________________________________________________________________________________________________________________________
version
1.1 (
-
modified parameters are now correctly
generated, eg. f(x); and void f(mod int y) {}
-
parameters which are passed by reference are now correctly generated,
eg. int t[10]; f(t); and void f(mod int *a) {}
-
pointer are now coorectly generated,eg. *(t+index) = y;
-
now, the compiler generates codes only if functions are called.
__________________________________________________________________________________________________________________________________________________________
void
genere_instruction(INSTRUCTION *inst,char *bloc)
{
char *rtype,*rtype1,*rtype2;
monte();
/*
printf("\n instruction %s
%d",bloc,inst->type_instruction);*/
if(inst==NULL)
{
/*if(traceaff==1) printf("\n%s FEUILLE
",affiche);*/
}
else
{
if(etat_trace2==1)
fprintf(file_code,"\n//\n//\n//%s Index instruction =%d %s",
affiche,((char *)inst-(char
*)&tab_instruction[0])/sizeof(INSTRUCTION),inst->bloc);
switch(inst->type_instruction)
{
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s INLINE ", affiche);
fprintf(file_code,"\n\t%s",
inst->instruction.sinline);
}break;
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION IF ", affiche);
genere_inst_if(inst,bloc);
}break;
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION FOR ", affiche);
genere_inst_for(inst,bloc);
}break;
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s DO WHILE ", affiche);
genere_inst_do_while(inst,bloc);
}break;
{
int
i;
if(etat_trace2==1)
fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION SWITCH ",affiche);
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION EXPRESSION ",affiche);
if(inst->instruction.sswitch.nb_case>0)
{
rtype=genere_recursif(inst->instruction.sswitch.expression,0,bloc,NULL);
if(recherche_atome(rtype)==-1)
{
char
libelle[200];
sprintf(libelle,"\nErreur
Fatale #GC0050 : bloc=%s type=%s affectation switch inadaptee",
bloc,rtype);
message_erreur(libelle);
}
fprintf(file_code,"\n\tmov
expr_switch_%d, expr_%s_%s",inst->index,rtype,bloc);
fprintf(file_code,"\n//%s
CORPS SWITCH NB CASE = %d ",affiche,inst->instruction.sswitch.nb_case);
}
else
if(etat_trace2==1) fprintf(file_code,"\n//%s CORPS SWITCH
VIDE",affiche);
for(i=0;i<inst->instruction.sswitch.nb_case;i++)
{
int
j;
monte();
if(etat_trace2==1)
fprintf(file_code,"\n//%s case/default %d",affiche,i);
if(inst->instruction.sswitch.type_case[i]==TYPE_CASE_CASE)
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s CASE ",affiche);
}
else
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s DEFAULT ",affiche);
}
monte();
if(inst->instruction.sswitch.expression_case[i]==NULL)
{
if(etat_trace2==1) fprintf(file_code,"\n//%s EXPRESSION VIDE",affiche);
}
else
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s EXPRESSION CASE #%d",affiche,i+1);
rtype1=genere_recursif(inst->instruction.sswitch.expression_case[i],0,bloc,NULL);
if(recherche_atome(rtype1)==-1)
{
char
libelle[200];
sprintf(libelle,"\nErreur
Fatale #GC0051 : bloc=%s type=%s affectation switch inadaptee",
bloc,rtype1);
message_erreur(libelle);
}
/*
correctif 14-04-07 */
fprintf(file_code,"\n\tmov
expr_sdword_%s, expr_%s_%s ",
bloc,rtype1,bloc);
/*
correctif 14-04-07 */
fprintf(file_code,"\n\tbrcmp
NEQ, %s_switch_%d_case_%d, expr_switch_%d, expr_%s_%s ",
inst->bloc,inst->index,i+1,inst->index,"sdword",bloc);
}
descend();
if(inst->instruction.sswitch.cases[i]==NULL)
{
if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION VIDE",affiche);
for(j=i+1;j<inst->instruction.sswitch.nb_case;j++)
if(inst->instruction.sswitch.cases[j]!=NULL)
break;
fprintf(file_code,"\n\tjmp
bloc_%s_switch_%d_case_%d",inst->bloc,inst->index,j);
}
else
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION DU CASE #%d",affiche,i+1);
fprintf(file_code,"\nbloc_%s_switch_%d_case_%d:",inst->bloc,inst->index,i);
genere_instruction(inst->instruction.sswitch.cases[i],bloc);
}
if(inst->instruction.sswitch.break_or_not[i]==1)
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s BREAK",affiche);
fprintf(file_code,"\n\tjmp
%s_switch_%d_case_%d",inst->bloc,inst->index,inst->instruction.sswitch.nb_case);
}
else
if(etat_trace2==1)
fprintf(file_code,"\n//%s PAS DE BREAK",affiche);
if((inst->instruction.sswitch.type_case[i]==TYPE_CASE_DEFAULT)&&
(inst->instruction.sswitch.break_or_not[i]==0))
{
fprintf(file_code,"\n\tjmp
%s_switch_%d_case_%d",inst->bloc,inst->index,inst->instruction.sswitch.nb_case);
}
descend();
fprintf(file_code,"\n%s_switch_%d_case_%d:",inst->bloc,inst->index,i+1);
}
/*fprintf(file_code,"\n%s_switch_%d_case_%d:",inst->bloc,inst->index,inst->instruction.sswitch.nb_case);*/
if(inst->instruction.sswitch.nb_case==0) {if(etat_trace2==1)
fprintf(file_code,"\n//%s CORPS SWITCH VIDE ",affiche);}
if(etat_trace2==1)
fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);
}break;
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION LABEL '%s' ",
affiche,inst->instruction.slabel);
fprintf(file_code,"\n%s_switch_%d_label_%s:",inst->bloc,inst->index,inst->instruction.slabel);
}break;
{
int
index;
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION GOTO '%s'",
affiche,inst->instruction.sgoto);
index=rechercher_index_label(inst->bloc,inst->instruction.sgoto);
fprintf(file_code,"\n\tjmp
%s_switch_%d_label_%s",inst->bloc,index,inst->instruction.sgoto);
}break;
{
int
index;
if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION ACQUIRE '%s'", affiche,inst->instruction.smutex_acquire);
index=rechercher_index_mutex(inst->instruction.smutex_acquire);
if(index==-1)
{
char libelle[200];
sprintf(libelle,"\nErreur Fatale #GC9200 : bloc '%s' - mutex '%s' de la primitive Acquire inconnu",
inst->bloc,inst->instruction.smutex_acquire);
message_erreur(libelle);
}
fprintf(file_code,"\n\tacquire
%s",inst->instruction.smutex_acquire);
}break;
{
int
index;
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION RELEASE '%s'",
affiche,inst->instruction.smutex_release);
index=rechercher_index_mutex(inst->instruction.smutex_release);
if(index==-1)
{
char
libelle[200];
sprintf(libelle,"\nErreur
Fatale #GC9300 : bloc '%s' - mutex '%s' de la primitive Release inconnu",
inst->bloc,inst->instruction.smutex_release);
message_erreur(libelle);
}
fprintf(file_code,"\n\trelease
%s",inst->instruction.smutex_release);
}break;
{
int
index_label;
int
index_size;
char
prefixe_label[MAX_IDENT];
char
prefixe_size[MAX_IDENT];
index_label=recherche_variable(inst->instruction.sarrsize.label,inst->bloc);
index_size
=recherche_variable(inst->instruction.sarrsize.size,inst->bloc);
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION ARRSIZE label='%s' size='%s'",
affiche,
inst->instruction.sarrsize.label,inst->instruction.sarrsize.size);
if(strcmp(program.vg[index_label].bloc,"0")==0)
strcpy(prefixe_label,"globale");
else
strcpy(prefixe_label,program.vg[index_label].bloc);
if(strcmp(program.vg[index_size].bloc,"0")==0)
strcpy(prefixe_size,"globale");
else
strcpy(prefixe_size,program.vg[index_size].bloc);
fprintf(file_code,"\n\tarrsize
%s_%s, %s_%s",
prefixe_size,inst->instruction.sarrsize.size,
prefixe_label,inst->instruction.sarrsize.label);
}break;
{
SEXPRESSION
*expression_value_ptr;
SEXPRESSION
*expression_size_ptr;
int
index_label;
char
prefixe_label[MAX_IDENT];
char
*rtype_value,*rtype_size;
int ind;
expression_value_ptr=inst->instruction.sarrinit.expression_value_ptr;
expression_size_ptr=inst->instruction.sarrinit.expression_size_ptr;
index_label=recherche_variable(inst->instruction.sarrinit.label,inst->bloc);
if(strcmp(program.vg[index_label].bloc,"0")==0)
strcpy(prefixe_label,"globale");
else
strcpy(prefixe_label,program.vg[index_label].bloc);
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION ARRINIT label='%s'", affiche,
inst->instruction.sarrinit.label);
rtype_value=genere_recursif(expression_value_ptr,0,bloc,NULL);
fprintf(file_code,"\n\tmov
%s_%s_%s, %s_%s_%s",
"value",rtype_value,bloc,
"expr", rtype_value,bloc);
rtype_size=genere_recursif(expression_size_ptr,0,bloc,NULL);
/* contrôle de la comptabilité du type à réaliser */
ind=recherche_atome(rtype_size);
if((ind!=TBYTE)&&(ind!=TWORD)&&(ind!=TDWORD))
{
char libelle[200];
sprintf(libelle,"\nErreur Fatale #GC10001 : bloc=%s type=%s incompatible avec le champ size ",
bloc,rtype_size);
message_erreur(libelle);
}
fprintf(file_code,"\n\tmov
%s_%s_%s, %s_%s_%s",
"size","word",bloc,
"expr",rtype_size,bloc);
fprintf(file_code,"\n\tarrinit
%s_%s, %s_%s_%s, %s_%s_%s",
prefixe_label,inst->instruction.sarrinit.label,
"value",rtype_value,bloc,
"size","word",bloc);
}break;
{
int
index_src;
int
index_dst;
char
prefixe_src[MAX_IDENT];
char
prefixe_dst[MAX_IDENT];
SEXPRESSION
*expression_index_ptr;
SEXPRESSION
*expression_length_ptr;
char
*rtype_index,*rtype_length;
int
ind;
expression_index_ptr=inst->instruction.sarrsubset.expression_index_ptr;
expression_length_ptr=inst->instruction.sarrsubset.expression_length_ptr;
index_src=recherche_variable(inst->instruction.sarrsubset.label_src,inst->bloc);
index_dst=recherche_variable(inst->instruction.sarrsubset.label_dst,inst->bloc);
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION ARRSUBSET src ='%s' dst='%s'",
affiche,
inst->instruction.sarrsubset.label_src,inst->instruction.sarrsubset.label_dst);
if(strcmp(program.vg[index_src].bloc,"0")==0)
strcpy(prefixe_src,"globale");
else
strcpy(prefixe_src,program.vg[index_src].bloc);
if(strcmp(program.vg[index_dst].bloc,"0")==0)
strcpy(prefixe_dst,"globale");
else
strcpy(prefixe_dst,program.vg[index_dst].bloc);
rtype_index=genere_recursif(expression_index_ptr,0,bloc,NULL);
/* contrôle de la comptabilité du type à réaliser */
ind=recherche_atome(rtype_index);
if((ind!=TBYTE)&&(ind!=TWORD)&&(ind!=TDWORD))
{
char libelle[200];
sprintf(libelle,"\nErreur Fatale #GC10002 : bloc=%s type=%s incompatible avec le champ index ",
bloc,rtype_index);
message_erreur(libelle);
}
fprintf(file_code,"\n\tmov
%s_%s_%s, %s_%s_%s",
"index","word",bloc,
"expr", rtype_index,bloc);
rtype_length=genere_recursif(expression_length_ptr,0,bloc,NULL);
/* contrôle de la comptabilité du type à réaliser */
ind=recherche_atome(rtype_length);
if((ind!=TBYTE)&&(ind!=TWORD)&&(ind!=TDWORD))
{
char libelle[200];
sprintf(libelle,"\nErreur Fatale #GC10003 : bloc=%s type=%s incompatible avec le champ length ",
bloc,rtype_length);
message_erreur(libelle);
}
fprintf(file_code,"\n\tmov
%s_%s_%s, %s_%s_%s",
"length","word",bloc,
"expr", rtype_length,bloc);
fprintf(file_code,"\n\tarrsubset
%s_%s, %s_%s, %s_%s_%s, %s_%s_%s",
prefixe_dst,inst->instruction.sarrsubset.label_dst,
prefixe_src,inst->instruction.sarrsubset.label_src,
"index","word",bloc,
"length","word",bloc);
}break;
{
int
i;
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION ARRBUILD %d", affiche,
inst->instruction.sarrbuild.nb_tab);
fprintf(file_code,"\n\tarrbuild
");
for(i=0;i<inst->instruction.sarrbuild.nb_tab;i++)
{
int
index_src;
char
prefixe_src[MAX_IDENT];
index_src=recherche_variable(inst->instruction.sarrbuild.label[i],inst->bloc);
if(strcmp(program.vg[index_src].bloc,"0")==0)
strcpy(prefixe_src,"globale");
else
strcpy(prefixe_src,program.vg[index_src].bloc);
if(i>0)
fprintf(file_code,",");
fprintf(file_code,"%s_%s
",prefixe_src,inst->instruction.sarrbuild.label[i]);
}
}break;
{
SEXPRESSION
*exp;
int
type;
int
j,k,l;
char
*rtype,*type_ret,*typer;
exp=inst->instruction.sreturn.expression_ptr;
type=inst->instruction.sreturn.exp;
if(etat_trace2==1)
fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION RETURN ",affiche);
if(type==1)
{
rtype=genere_recursif(exp,0,bloc,NULL);
for(j=0;j<nb_fonction;j++)
if(strcmp(bloc,tab_fonction[j].ident_fonction)==0)
break;
if(j==nb_fonction)
{
char
libelle[200];
sprintf(libelle,"\nErreur Fatale #GC0200 : fonction inconnue '%s'",bloc);
message_erreur(libelle);
}
type_ret=convertit_type_gen(tab_fonction[j].type_variable_retournee_ptr->type,0);
typer=calcul_type_resultant(type_ret,rtype);
k=recherche_atome(typer);
l=recherche_atome(type_ret);
if(recherche_atome(type_ret)==-1)
{
if(strcmp(rtype,type_ret)!=0)
{
char libelle[200];
sprintf(libelle,"\nErreur Fatale #GC0201 : fonction '%s', type retourne incompatible '%s' : '%s'",
bloc,rtype,type_ret);
message_erreur(libelle);
}
}
else
if(k!=l)
{
char
libelle[200];
sprintf(libelle,"\nErreur Fatale #GC0202 : fonction '%s', type retourne incompatible '%s' : '%s'",
bloc,rtype,type_ret);
message_erreur(libelle);
}
if(strcmp(type_ret,rtype)!=0) /* on ne genere ce code que si les types sont différents */
fprintf(file_code,"\n\tmov
expr_%s_%s, expr_%s_%s",type_ret,bloc,rtype,bloc);
}
else
{if(etat_trace2==1) fprintf(file_code,"\n//%s RETURN VIDE ",affiche);}
fprintf(file_code,"\n\tjmp
return_%s",bloc);
if(etat_trace2==1)
fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);
}break;
{
monte();
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION EXIT()", affiche);
fprintf(file_code,"\n\tstop
1");
descend();
}break;
{
int i;
int index;
if(inst->instruction.sprecedes.nb_label>0)
{
monte();
if(etat_trace2==1)
fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION PRECEDES ",affiche);
for(i=0;i<inst->instruction.sprecedes.nb_label;i++)
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s tache = '%s'
",affiche,&inst->instruction.sprecedes.label[i][0]);
}
fprintf(file_code,"\n\tprecedes
");
for(i=0;i<inst->instruction.sprecedes.nb_label;i++)
{
rechercher_tache(&inst->instruction.sprecedes.label[i][0],inst->bloc);
fprintf(file_code,"%s
",&inst->instruction.sprecedes.label[i][0]);
}
if(etat_trace2==1) fprintf(file_code,"\n//%s__________________________________________________________________________________",affiche);
descend();
}
}break;
{
INSTRUCTION
*inst_boucle;
monte();
if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION BREAK => SAUT SORTIE DE BOUCLE ", affiche);
inst_boucle=consulte_boucle();
if(inst_boucle->type_instruction==INST_FOR)
fprintf(file_code,"\n\tjmp
break_%s_for_%d",inst_boucle->bloc,inst_boucle->index);
else
if(inst_boucle->type_instruction==INST_DO_REPEAT)
fprintf(file_code,"\n\tjmp break_%s_do_while_%d",inst_boucle->bloc,inst_boucle->index);
descend();
}break;
case
INST_CASE :
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION CASE ", affiche);
}break;
{
INSTRUCTION *inst_boucle;
monte();
if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION CONTINUE => SAUT DEBUT DE BOUCLE ", affiche);
inst_boucle=consulte_boucle();
if(inst_boucle->type_instruction==INST_FOR)
fprintf(file_code,"\n\tjmp
continue_%s_for_%d",inst_boucle->bloc,inst_boucle->index);
else
if(inst_boucle->type_instruction==INST_DO_REPEAT)
fprintf(file_code,"\n\tjmp
%s_do_while_%d",inst_boucle->bloc,inst_boucle->index);
descend();
}break;
{
char *rtype1,*rtype2,*rtype;
SEXPRESSION *exp1;
SVARIABLE *suivant;
int dim,type;
monte();
/* printf("\naff %lx",inst->instruction.saffectation);*/
if(inst->instruction.saffectation->type_affectation==AFF_PTR)
{
/*printf("\n A");*/
if(etat_trace2==1) fprintf(file_code,"\n//%s = AFF POINTEUR ",affiche);
/*printf("\n B");*/
rtype1=genere_recursif(inst->instruction.saffectation->valeur_affectee,0,bloc,NULL);
/*printf("\n C");*/
if(strcmp(rtype1,"void")==0)
{
char libelle[200];
sprintf(libelle,"\nErreur Fatale #GC0400 : affectation d'un type 'void' à la variable '%s' ",
inst->instruction.saffectation->variable->feuille.svariable.ident_variable);
message_erreur(libelle);
}
/*printf("\n D");*/
exp1=inst->instruction.saffectation->valeur_affectee;
/*printf("\n E");*/
type=exp1->type;
/*printf("\n F");*/
fprintf(file_code,"\n\tmov
expr_aff_%s_%s, expr_%s_%s // affectation 0",rtype1,bloc,rtype1,bloc);
/*printf("\n
G");*/
rtype2=genere_recursif(inst->instruction.saffectation->variable,1,bloc,rtype1);
/*printf("\n
H");*/
rtype=calcul_type_resultant(rtype1,rtype2);
/*printf("\n
I");*/
}
else
if(inst->instruction.saffectation->type_affectation==AFF_EXP)
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s = AFF VARIABLE SIMPLE ",affiche);
rtype1=genere_recursif(inst->instruction.saffectation->valeur_affectee,0,bloc,NULL);
if(strcmp(rtype1,"void")==0)
{
char libelle[200];
sprintf(libelle,"\nErreur Fatale #GC0300 : affectation d'un type 'void' à la variable '%s' ",
inst->instruction.saffectation->variable->feuille.svariable.ident_variable);
message_erreur(libelle);
}
exp1=inst->instruction.saffectation->valeur_affectee;
type=exp1->type;
if(type==EXP_VARIABLE) /* c'est une variable */
{
suivant=exp1->feuille.svariable.suivant;
dim=exp1->feuille.svariable.variable_ptr->type_variable_ptr->nb_dimension;
/*printf("\n suivant=%lx d=%d",suivant,dim);*/
if((suivant==NULL)&&(dim>0)) /* affectation d'un tableau */
{
/* à corriger si tableau d'atome, tab en trop */
int ind_tab;
ind_tab=recherche_tab_atome(rtype1);
if(ind_tab==-1)
fprintf(file_code,"\n\tmov
expr_aff_%s_tab_%s, expr_%s_tab_%s // affectation
1",rtype1,bloc,rtype1,bloc);
else
fprintf(file_code,"\n\tmov
expr_aff_%s_%s, expr_%s_%s // affectation 1 tab
d'atome",rtype1,bloc,rtype1,bloc);
}
else /* ce n'est pas un tableau */
fprintf(file_code,"\n\tmov
expr_aff_%s_%s, expr_%s_%s // affectation 2",rtype1,bloc,rtype1,bloc);
}
else
/* c'est une expression */
fprintf(file_code,"\n\tmov
expr_aff_%s_%s, expr_%s_%s // affectation 3 ",rtype1,bloc,rtype1,bloc);
rtype2=genere_recursif(inst->instruction.saffectation->variable,1,bloc,rtype1);
rtype=calcul_type_resultant(rtype1,rtype2);
}
else
if(inst->instruction.saffectation->type_affectation==AFF_INC)
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s ++ INCREMENTATION ",affiche);
genere_recursif(inst->instruction.saffectation->variable,2,bloc,NULL);
}
else
if(inst->instruction.saffectation->type_affectation==AFF_DEC)
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s -- DECREMENTATION ",affiche);
genere_recursif(inst->instruction.saffectation->variable,3,bloc,NULL);
}
/*fprintf(file_code,"\n\tmov
expr_d_word, expr_word");*/
if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION AFFECTATION %lx %lx",
affiche,
inst->instruction.saffectation->variable,
inst->instruction.saffectation->valeur_affectee);
/*fprintf(file_code,"\n\tmov
expr_word,expr_d_word");*/
descend();
}break;
{
monte();
if(etat_trace2==1) fprintf(file_code,"\n//%s INSTRUCTION FONCTION ", affiche);
genere_recursif(inst->instruction.sfonction,0,bloc,NULL);
descend();
}break;
{
int
i;
if(etat_trace2==1)
fprintf(file_code,"\n//%s INSTRUCTION BLOC ", affiche);
monte();
if(inst->instruction.sbloc.nb_instruction==0)
{
if(etat_trace2==1) fprintf(file_code,"\n//%s BLOC VIDE ", affiche);
}
else
{
if(etat_trace2==1) fprintf(file_code,"\n//%s LISTE INSTRUCTION BLOC nb_inst %d", affiche,inst->instruction.sbloc.nb_instruction);
for(i=0;i<
inst->instruction.sbloc.nb_instruction;i++)
{
if(etat_trace2==1)
fprintf(file_code,"\n//%s SOUS INSTRUCTION BLOC %d", affiche,i);
genere_instruction(inst->instruction.sbloc.liste_instruction[i],bloc);
}
}
descend();
}break;
}
}
descend();
}