Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

lustrec / src / lexer_lustre.mll @ 5c1184ad

History | View | Annotate | Download (5.25 KB)

1
(* ----------------------------------------------------------------------------
2
 * SchedMCore - A MultiCore Scheduling Framework
3
 * Copyright (C) 2009-2011, ONERA, Toulouse, FRANCE - LIFL, Lille, FRANCE
4
 *
5
 * This file is part of Prelude
6
 *
7
 * Prelude is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public License
9
 * as published by the Free Software Foundation ; either version 2 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * Prelude is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY ; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this program ; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20
 * USA
21
 *---------------------------------------------------------------------------- *)
22

    
23
{
24
open Parser_lustre
25
open Utils
26

    
27
exception Error of Location.t
28

    
29
(* As advised by Caml documentation. This way a single lexer rule is
30
   used to handle all the possible keywords. *)
31
let keyword_table =
32
  create_hashtable 20 [
33
  "function", FUNCTION;
34
  "struct", STRUCT;
35
  "enum", ENUM;
36
  "automaton", AUTOMATON;
37
  "state", STATE;
38
  "until", UNTIL;
39
  "unless", UNLESS;
40
  "last", LAST;
41
  "resume", RESUME;
42
  "restart", RESTART;
43
  "stateless", STATELESS;
44
  "if", IF;
45
  "then", THEN;
46
  "else", ELSE;
47
  "merge", MERGE;
48
  "arrow", ARROW;
49
  "fby", FBY;
50
  "when", WHEN;
51
  "whenot", WHENNOT;
52
  "every", EVERY;
53
  "node", NODE;
54
  "let", LET;
55
  "tel", TEL;
56
  "returns", RETURNS;
57
  "var", VAR;
58
  "imported", IMPORTED;
59
  "wcet", WCET;
60
  "type", TYPE;
61
  "int", TINT;
62
  "bool", TBOOL;
63
  "float", TFLOAT;
64
  "real", TREAL;
65
  "clock", TCLOCK;
66
  "not", NOT;
67
  "tail", TAIL;
68
  "and", AND;
69
  "or", OR;
70
  "xor", XOR;
71
  "mod", MOD;
72
  "pre", PRE;
73
  "div", DIV;
74
  "const", CONST;
75
  "open", OPEN;
76
  "assert", ASSERT;
77
]
78

    
79

    
80
(* Buffer for parsing specification/annotation *)
81
let buf = Buffer.create 1024
82

    
83
let make_annot lexbuf s = 
84
  try
85
    let ann = LexerLustreSpec.annot s in
86
    ANNOT ann
87
  with _ -> (Format.eprintf "Impossible to parse the following annotation:@.%s@.@?" s; exit 1)
88

    
89
let make_spec lexbuf s = 
90
  try
91
    let ns = LexerLustreSpec.spec s in
92
    NODESPEC ns
93
  with _ -> (Format.eprintf "Impossible to parse the following node specification:@.%s@.@?" s; exit 1)
94
   
95
}
96

    
97
let newline = ('\010' | '\013' | "\013\010")
98
let notnewline = [^ '\010' '\013']
99
let blank = [' ' '\009' '\012']
100

    
101
rule token = parse
102
| "--@" { Buffer.clear buf;
103
	  spec_singleline lexbuf }
104
| "(*@" { Buffer.clear buf; 
105
	  spec_multiline 0 lexbuf }
106
| "--!" { Buffer.clear buf; 
107
	  annot_singleline lexbuf }
108
| "(*!" { Buffer.clear buf; 
109
	  annot_multiline 0 lexbuf }
110
| "(*"
111
    { comment 0 lexbuf }
112
| "--" [^ '!' '@'] notnewline* (newline|eof)
113
    { incr_line lexbuf;
114
      token lexbuf }
115
| newline
116
    { incr_line lexbuf;
117
      token lexbuf }
118
| blank +
119
    {token lexbuf}
120
| ['0'-'9'] ['0'-'9']* '.' ['0'-'9']*
121
    {FLOAT (float_of_string (Lexing.lexeme lexbuf))}
122
| ['0'-'9']+ 
123
    {INT (int_of_string (Lexing.lexeme lexbuf)) }
124
| ['0'-'9']+ '.' ['0'-'9']+ ('E'|'e') ('+'|'-') ['0'-'9'] ['0'-'9']* as s {REAL s}
125
| "tel." {TEL}
126
| "tel;" {TEL}
127
| ['_' 'a'-'z' 'A'-'Z'] [ '_' 'a'-'z' 'A'-'Z' '0'-'9']*
128
    {let s = Lexing.lexeme lexbuf in
129
    try
130
      Hashtbl.find keyword_table s
131
    with Not_found ->
132
      IDENT s}
133
| "->" {ARROW}
134
| "=>" {IMPL}
135
| "<=" {LTE}
136
| ">=" {GTE}
137
| "<>" {NEQ}
138
| '<' {LT}
139
| '>' {GT}
140
| "!=" {NEQ}
141
| '-' {MINUS}
142
| '+' {PLUS}
143
| '/' {DIV}
144
| '*' {MULT}
145
| '=' {EQ}
146
| '(' {LPAR}
147
| ')' {RPAR}
148
| '[' {LBRACKET}
149
| ']' {RBRACKET}
150
| '{' {LCUR}
151
| '}' {RCUR}
152
| ';' {SCOL}
153
| ':' {COL}
154
| ',' {COMMA}
155
| '=' {EQ}
156
| '/' {DIV}
157
| "&&" {AMPERAMPER}
158
| "||" {BARBAR}
159
| "::" {COLCOL}
160
| "^" {POWER}
161
| '"' {QUOTE}
162
| eof { EOF }
163
| _ { raise (Error (Location.curr lexbuf)) }
164

    
165
and comment n = parse
166
| eof
167
    { raise (Error (Location.curr lexbuf)) }
168
| "(*"
169
    { comment (n+1) lexbuf }
170
| "*)"
171
    { if n > 0 then comment (n-1) lexbuf else token lexbuf }
172
| newline
173
    { incr_line lexbuf;
174
      comment n lexbuf }
175
| _ { comment n lexbuf }
176

    
177
and annot_singleline = parse
178
  | newline { incr_line lexbuf; make_annot lexbuf (Buffer.contents buf) }
179
  | _ as c { Buffer.add_char buf c; annot_singleline lexbuf }
180

    
181
and annot_multiline n = parse
182
  | "*)" as s { 
183
    if n > 0 then 
184
      (Buffer.add_string buf s; annot_multiline (n-1) lexbuf) 
185
    else 
186
      make_annot lexbuf (Buffer.contents buf) }
187
  | "(*" as s { Buffer.add_string buf s; annot_multiline (n+1) lexbuf }
188
  | newline as s { incr_line lexbuf; Buffer.add_string buf s; annot_multiline n lexbuf }
189
  | _ as c { Buffer.add_char buf c; annot_multiline n lexbuf }
190

    
191
and spec_singleline = parse
192
  | newline { incr_line lexbuf; make_spec lexbuf (Buffer.contents buf) }
193
  | _ as c { Buffer.add_char buf c; spec_singleline lexbuf }
194

    
195
and spec_multiline n = parse
196
  | "*)" as s { if n > 0 then 
197
      (Buffer.add_string buf s; spec_multiline (n-1) lexbuf) 
198
    else 
199
      make_spec lexbuf (Buffer.contents buf) }
200
  | "(*" as s { Buffer.add_string buf s; spec_multiline (n+1) lexbuf }
201
  | newline as s { incr_line lexbuf; Buffer.add_string buf s; spec_multiline n lexbuf }
202
  | _ as c { Buffer.add_char buf c; spec_multiline n lexbuf }
203