source: Deliverables/D2.3/8051-memoryspaces-branch/cparser/Lexer.mll @ 460

Last change on this file since 460 was 460, checked in by campbell, 9 years ago

Port memory spaces changes to latest prototype compiler.

File size: 20.5 KB
Line 
1(*
2 *
3 * Copyright (c) 2001-2003,
4 *  George C. Necula    <necula@cs.berkeley.edu>
5 *  Scott McPeak        <smcpeak@cs.berkeley.edu>
6 *  Wes Weimer          <weimer@cs.berkeley.edu>
7 *  Ben Liblit          <liblit@cs.berkeley.edu>
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * 3. The names of the contributors may not be used to endorse or promote
22 * products derived from this software without specific prior written
23 * permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
26 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
29 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 *)
38(* FrontC -- lexical analyzer
39**
40** 1.0  3.22.99 Hugues Cassé    First version.
41** 2.0  George Necula 12/12/00: Many extensions
42*)
43{
44open Lexing
45open Parse_aux
46open Parser
47
48exception Eof
49
50module H = Hashtbl
51
52let newline lb =
53  let cp = lb.lex_curr_p in
54  lb.lex_curr_p <- { cp with pos_lnum = 1 + cp.pos_lnum }
55
56let setCurrentLine lb lineno =
57  let cp = lb.lex_curr_p in
58  lb.lex_curr_p <- { cp with pos_lnum = lineno }
59
60let setCurrentFile lb file =
61  let cp = lb.lex_curr_p in
62  lb.lex_curr_p <- { cp with pos_fname = file }
63
64let matchingParsOpen = ref 0
65
66let currentLoc = Cabshelper.currentLoc_lexbuf
67
68let int64_to_char value =
69  assert (value <= 255L && value >= 0L);
70  Char.chr (Int64.to_int value)
71
72(* takes a not-nul-terminated list, and converts it to a string. *)
73let rec intlist_to_string (str: int64 list):string =
74  match str with
75    [] -> ""  (* add nul-termination *)
76  | value::rest ->
77      let this_char = int64_to_char value in
78      (String.make 1 this_char) ^ (intlist_to_string rest)
79
80(*
81** Keyword hashtable
82*)
83let lexicon = H.create 211
84let init_lexicon _ =
85  H.clear lexicon;
86  List.iter
87    (fun (key, builder) -> H.add lexicon key builder)
88    [ ("_Bool", fun loc -> UNDERSCORE_BOOL loc);
89      ("auto", fun loc -> AUTO loc);
90      ("const", fun loc -> CONST loc);
91      ("__const", fun loc -> CONST loc);
92      ("__const__", fun loc -> CONST loc);
93      ("static", fun loc -> STATIC loc);
94      ("extern", fun loc -> EXTERN loc);
95      ("long", fun loc -> LONG loc);
96      ("short", fun loc -> SHORT loc);
97      ("register", fun loc -> REGISTER loc);
98      ("signed", fun loc -> SIGNED loc);
99      ("__signed", fun loc -> SIGNED loc);
100      ("unsigned", fun loc -> UNSIGNED loc);
101      ("volatile", fun loc -> VOLATILE loc);
102      ("__volatile", fun loc -> VOLATILE loc);
103      (* WW: see /usr/include/sys/cdefs.h for why __signed and __volatile
104       * are accepted GCC-isms *)
105      ("char", fun loc -> CHAR loc);
106      ("int", fun loc -> INT loc);
107      ("float", fun loc -> FLOAT loc);
108      ("double", fun loc -> DOUBLE loc);
109      ("void", fun loc -> VOID loc);
110      ("enum", fun loc -> ENUM loc);
111      ("struct", fun loc -> STRUCT loc);
112      ("typedef", fun loc -> TYPEDEF loc);
113      ("union", fun loc -> UNION loc);
114      ("break", fun loc -> BREAK loc);
115      ("continue", fun loc -> CONTINUE loc);
116      ("goto", fun loc -> GOTO loc);
117      ("return", fun loc -> RETURN loc);
118      ("switch", fun loc -> SWITCH loc);
119      ("case", fun loc -> CASE loc);
120      ("default", fun loc -> DEFAULT loc);
121      ("while", fun loc -> WHILE loc); 
122      ("do", fun loc -> DO loc); 
123      ("for", fun loc -> FOR loc);
124      ("if", fun loc -> IF loc);
125      ("else", fun _ -> ELSE);
126      (*** Implementation specific keywords ***)
127      ("__signed__", fun loc -> SIGNED loc);
128      ("__inline__", fun loc -> INLINE loc);
129      ("inline", fun loc -> INLINE loc);
130      ("__inline", fun loc -> INLINE loc);
131      ("_inline", fun loc ->
132                      if !msvcMode then
133                        INLINE loc
134                      else
135                        IDENT ("_inline", loc));
136      ("__attribute__", fun loc -> ATTRIBUTE loc);
137      ("__attribute", fun loc -> ATTRIBUTE loc);
138(*
139      ("__attribute_used__", fun loc -> ATTRIBUTE_USED loc);
140*)
141      ("__blockattribute__", fun _ -> BLOCKATTRIBUTE);
142      ("__blockattribute", fun _ -> BLOCKATTRIBUTE);
143      ("__asm__", fun loc -> ASM loc);
144      ("asm", fun loc -> ASM loc);
145      ("__typeof__", fun loc -> TYPEOF loc);
146      ("__typeof", fun loc -> TYPEOF loc);
147      ("typeof", fun loc -> TYPEOF loc);
148      ("__alignof", fun loc -> ALIGNOF loc);
149      ("__alignof__", fun loc -> ALIGNOF loc);
150      ("__volatile__", fun loc -> VOLATILE loc);
151      ("__volatile", fun loc -> VOLATILE loc);
152
153      ("__FUNCTION__", fun loc -> FUNCTION__ loc);
154      ("__func__", fun loc -> FUNCTION__ loc); (* ISO 6.4.2.2 *)
155      ("__PRETTY_FUNCTION__", fun loc -> PRETTY_FUNCTION__ loc);
156      ("__label__", fun _ -> LABEL__);
157      (*** weimer: GCC arcana ***)
158      ("__restrict", fun loc -> RESTRICT loc);
159      ("restrict", fun loc -> RESTRICT loc);
160(*      ("__extension__", EXTENSION); *)
161      (**** MS VC ***)
162      ("__int64", fun loc -> INT64 loc);
163      ("__int32", fun loc -> INT loc);
164      ("_cdecl",  fun loc -> MSATTR ("_cdecl", loc));
165      ("__cdecl", fun loc -> MSATTR ("__cdecl", loc));
166      ("_stdcall", fun loc -> MSATTR ("_stdcall", loc));
167      ("__stdcall", fun loc -> MSATTR ("__stdcall", loc));
168      ("_fastcall", fun loc -> MSATTR ("_fastcall", loc));
169      ("__fastcall", fun loc -> MSATTR ("__fastcall", loc));
170      ("__w64", fun loc -> MSATTR("__w64", loc));
171      ("__declspec", fun loc -> DECLSPEC loc);
172      ("__forceinline", fun loc -> INLINE loc); (* !! we turn forceinline
173                                                 * into inline *)
174      ("__try", fun loc -> TRY loc);
175      ("__except", fun loc -> EXCEPT loc);
176      ("__finally", fun loc -> FINALLY loc);
177      (* weimer: some files produced by 'GCC -E' expect this type to be
178       * defined *)
179      ("__builtin_va_list", fun loc -> NAMED_TYPE ("__builtin_va_list", loc));
180      ("__builtin_va_arg", fun loc -> BUILTIN_VA_ARG loc);
181      ("__builtin_types_compatible_p", fun loc -> BUILTIN_TYPES_COMPAT loc);
182      ("__builtin_offsetof", fun loc -> BUILTIN_OFFSETOF loc);
183      (* On some versions of GCC __thread is a regular identifier *)
184      ("__thread", fun loc -> THREAD loc);
185      (* 8051 memory space extensions *)
186      ("__data", fun loc -> DATA loc);
187      ("__idata", fun loc -> IDATA loc);
188      ("__pdata", fun loc -> PDATA loc);
189      ("__xdata", fun loc -> XDATA loc);
190      ("__code", fun loc -> CODE loc);
191    ]
192
193(* Mark an identifier as a type name. The old mapping is preserved and will
194 * be reinstated when we exit this context *)
195let add_type name =
196   (* ignore (print_string ("adding type name " ^ name ^ "\n"));  *)
197   H.add lexicon name (fun loc -> NAMED_TYPE (name, loc))
198
199let context : string list list ref = ref []
200
201let push_context _ = context := []::!context
202
203let pop_context _ =
204  match !context with
205    [] -> assert false
206  | con::sub ->
207                (context := sub;
208                List.iter (fun name ->
209                           (* ignore (print_string ("removing lexicon for " ^ name ^ "\n")); *)
210                            H.remove lexicon name) con)
211
212(* Mark an identifier as a variable name. The old mapping is preserved and
213 * will be reinstated when we exit this context  *)
214let add_identifier name =
215  match !context with
216    [] -> () (* Just ignore raise (InternalError "Empty context stack") *)
217  | con::sub ->
218       context := (name::con)::sub;
219       H.add lexicon name (fun loc -> IDENT (name, loc))
220
221
222(*
223** Useful primitives
224*)
225let scan_ident lb id =
226  let here = currentLoc lb in
227  try (H.find lexicon id) here
228  (* default to variable name, as opposed to type *)
229  with Not_found -> IDENT (id, here)
230
231
232(*
233** Buffer processor
234*)
235 
236
237let init ~(filename: string) ic : Lexing.lexbuf =
238  init_lexicon ();
239  (* Inititialize the pointer in Errormsg *)
240  Parse_aux.add_type := add_type;
241  Parse_aux.push_context := push_context;
242  Parse_aux.pop_context := pop_context;
243  Parse_aux.add_identifier := add_identifier;
244  (* Build lexbuf *)
245  let lb = Lexing.from_channel ic in
246  let cp = lb.lex_curr_p in
247  lb.lex_curr_p <- {cp with pos_fname = filename; pos_lnum = 1};
248  lb
249
250let finish () =
251  ()
252
253(*** Error handling ***)
254let error = parse_error
255
256
257(*** escape character management ***)
258let scan_escape (char: char) : int64 =
259  let result = match char with
260    'n' -> '\n'
261  | 'r' -> '\r'
262  | 't' -> '\t'
263  | 'b' -> '\b'
264  | 'f' -> '\012'  (* ASCII code 12 *)
265  | 'v' -> '\011'  (* ASCII code 11 *)
266  | 'a' -> '\007'  (* ASCII code 7 *)
267  | 'e' | 'E' -> '\027'  (* ASCII code 27. This is a GCC extension *)
268  | '\'' -> '\''   
269  | '"'-> '"'     (* '"' *)
270  | '?' -> '?'
271  | '(' when not !msvcMode -> '('
272  | '{' when not !msvcMode -> '{'
273  | '[' when not !msvcMode -> '['
274  | '%' when not !msvcMode -> '%'
275  | '\\' -> '\\'
276  | other -> error ("Unrecognized escape sequence: \\" ^ (String.make 1 other)); raise Parsing.Parse_error
277  in
278  Int64.of_int (Char.code result)
279
280let scan_hex_escape str =
281  let radix = Int64.of_int 16 in
282  let the_value = ref Int64.zero in
283  (* start at character 2 to skip the \x *)
284  for i = 2 to (String.length str) - 1 do
285    let thisDigit = Cabshelper.valueOfDigit (String.get str i) in
286    (* the_value := !the_value * 16 + thisDigit *)
287    the_value := Int64.add (Int64.mul !the_value radix) thisDigit
288  done;
289  !the_value
290
291let scan_oct_escape str =
292  let radix = Int64.of_int 8 in
293  let the_value = ref Int64.zero in
294  (* start at character 1 to skip the \x *)
295  for i = 1 to (String.length str) - 1 do
296    let thisDigit = Cabshelper.valueOfDigit (String.get str i) in
297    (* the_value := !the_value * 8 + thisDigit *)
298    the_value := Int64.add (Int64.mul !the_value radix) thisDigit
299  done;
300  !the_value
301
302let lex_hex_escape remainder lexbuf =
303  let prefix = scan_hex_escape (Lexing.lexeme lexbuf) in
304  prefix :: remainder lexbuf
305
306let lex_oct_escape remainder lexbuf =
307  let prefix = scan_oct_escape (Lexing.lexeme lexbuf) in
308  prefix :: remainder lexbuf
309
310let lex_simple_escape remainder lexbuf =
311  let lexchar = Lexing.lexeme_char lexbuf 1 in
312  let prefix = scan_escape lexchar in
313  prefix :: remainder lexbuf
314
315let lex_unescaped remainder lexbuf =
316  let prefix = Int64.of_int (Char.code (Lexing.lexeme_char lexbuf 0)) in
317  prefix :: remainder lexbuf
318
319let lex_comment remainder lexbuf =
320  let ch = Lexing.lexeme_char lexbuf 0 in
321  let prefix = Int64.of_int (Char.code ch) in
322  if ch = '\n' then newline lexbuf;
323  prefix :: remainder lexbuf
324
325let make_char (i:int64):char =
326  let min_val = Int64.zero in
327  let max_val = Int64.of_int 255 in
328  (* if i < 0 || i > 255 then error*)
329  if compare i min_val < 0 || compare i max_val > 0 then begin
330    let msg = Printf.sprintf "clexer:make_char: character 0x%Lx too big" i in
331    error msg
332  end;
333  Char.chr (Int64.to_int i)
334
335
336(* ISO standard locale-specific function to convert a wide character
337 * into a sequence of normal characters. Here we work on strings.
338 * We convert L"Hi" to "H\000i\000"
339  matth: this seems unused.
340let wbtowc wstr =
341  let len = String.length wstr in
342  let dest = String.make (len * 2) '\000' in
343  for i = 0 to len-1 do
344    dest.[i*2] <- wstr.[i] ;
345  done ;
346  dest
347*)
348
349(* This function converst the "Hi" in L"Hi" to { L'H', L'i', L'\0' }
350  matth: this seems unused.
351let wstr_to_warray wstr =
352  let len = String.length wstr in
353  let res = ref "{ " in
354  for i = 0 to len-1 do
355    res := !res ^ (Printf.sprintf "L'%c', " wstr.[i])
356  done ;
357  res := !res ^ "}" ;
358  !res
359*)
360
361}
362
363let decdigit = ['0'-'9']
364let octdigit = ['0'-'7']
365let hexdigit = ['0'-'9' 'a'-'f' 'A'-'F']
366let letter = ['a'- 'z' 'A'-'Z']
367
368
369let usuffix = ['u' 'U']
370let lsuffix = "l"|"L"|"ll"|"LL"
371let intsuffix = lsuffix | usuffix | usuffix lsuffix | lsuffix usuffix
372              | usuffix ? "i64"
373               
374
375let hexprefix = '0' ['x' 'X']
376
377let intnum = decdigit+ intsuffix?
378let octnum = '0' octdigit+ intsuffix?
379let hexnum = hexprefix hexdigit+ intsuffix?
380
381let exponent = ['e' 'E']['+' '-']? decdigit+
382let fraction  = '.' decdigit+
383let decfloat = (intnum? fraction)
384              |(intnum exponent)
385              |(intnum? fraction exponent)
386              | (intnum '.')
387              | (intnum '.' exponent)
388
389let hexfraction = hexdigit* '.' hexdigit+ | hexdigit+
390let binexponent = ['p' 'P'] ['+' '-']? decdigit+
391let hexfloat = hexprefix hexfraction binexponent
392             | hexprefix hexdigit+   binexponent
393
394let floatsuffix = ['f' 'F' 'l' 'L']
395let floatnum = (decfloat | hexfloat) floatsuffix?
396
397let ident = (letter|'_'|'$')(letter|decdigit|'_'|'$')*
398let blank = [' ' '\t' '\012' '\r']+
399let escape = '\\' _
400let hex_escape = '\\' ['x' 'X'] hexdigit+
401let oct_escape = '\\' octdigit octdigit? octdigit?
402
403rule initial =
404        parse   "/*"                    { comment lexbuf;
405                                          initial lexbuf}
406|               "//"                    { onelinecomment lexbuf;
407                                          newline lexbuf;
408                                          initial lexbuf
409                                           }
410|               blank                   { initial lexbuf}
411|               '\n'                    { newline lexbuf;
412                                          initial lexbuf }
413|               '\\' '\r' * '\n'        { newline lexbuf;
414                                          initial lexbuf
415                                        }
416|               '#'                     { hash lexbuf}
417(*
418|               "_Pragma"               { PRAGMA (currentLoc lexbuf) }
419*)
420|               '\''                    { CST_CHAR (chr lexbuf, currentLoc lexbuf)}
421|               "L'"                    { CST_WCHAR (chr lexbuf, currentLoc lexbuf) }
422|               '"'                     { (* '"' *)
423(* matth: BUG:  this could be either a regular string or a wide string.
424 *  e.g. if it's the "world" in
425 *     L"Hello, " "world"
426 *  then it should be treated as wide even though there's no L immediately
427 *  preceding it.  See test/small1/wchar5.c for a failure case. *)
428                                          CST_STRING (str lexbuf, currentLoc lexbuf) }
429|               "L\""                   { (* weimer: wchar_t string literal *)
430                                          CST_WSTRING(str lexbuf, currentLoc lexbuf) }
431|               floatnum                {CST_FLOAT (Lexing.lexeme lexbuf, currentLoc lexbuf)}
432|               hexnum                  {CST_INT (Lexing.lexeme lexbuf, currentLoc lexbuf)}
433|               octnum                  {CST_INT (Lexing.lexeme lexbuf, currentLoc lexbuf)}
434|               intnum                  {CST_INT (Lexing.lexeme lexbuf, currentLoc lexbuf)}
435|               "!quit!"                {EOF}
436|               "..."                   {ELLIPSIS}
437|               "+="                    {PLUS_EQ}
438|               "-="                    {MINUS_EQ}
439|               "*="                    {STAR_EQ}
440|               "/="                    {SLASH_EQ}
441|               "%="                    {PERCENT_EQ}
442|               "|="                    {PIPE_EQ}
443|               "&="                    {AND_EQ}
444|               "^="                    {CIRC_EQ}
445|               "<<="                   {INF_INF_EQ}
446|               ">>="                   {SUP_SUP_EQ}
447|               "<<"                    {INF_INF}
448|               ">>"                    {SUP_SUP}
449|               "=="                    {EQ_EQ}
450|               "!="                    {EXCLAM_EQ}
451|               "<="                    {INF_EQ}
452|               ">="                    {SUP_EQ}
453|               "="                             {EQ}
454|               "<"                             {INF}
455|               ">"                             {SUP}
456|               "++"                    {PLUS_PLUS (currentLoc lexbuf)}
457|               "--"                    {MINUS_MINUS (currentLoc lexbuf)}
458|               "->"                    {ARROW}
459|               '+'                             {PLUS (currentLoc lexbuf)}
460|               '-'                             {MINUS (currentLoc lexbuf)}
461|               '*'                             {STAR (currentLoc lexbuf)}
462|               '/'                             {SLASH}
463|               '%'                             {PERCENT}
464|               '!'                     {EXCLAM (currentLoc lexbuf)}
465|               "&&"                    {AND_AND (currentLoc lexbuf)}
466|               "||"                    {PIPE_PIPE}
467|               '&'                             {AND (currentLoc lexbuf)}
468|               '|'                             {PIPE}
469|               '^'                             {CIRC}
470|               '?'                             {QUEST}
471|               ':'                             {COLON}
472|               '~'                    {TILDE (currentLoc lexbuf)}
473       
474|               '{'                    {LBRACE (currentLoc lexbuf)}
475|               '}'                    {RBRACE (currentLoc lexbuf)}
476|               '['                             {LBRACKET}
477|               ']'                             {RBRACKET}
478|               '('                    { (LPAREN (currentLoc lexbuf)) }
479|               ')'                             {RPAREN}
480|               ';'                    { (SEMICOLON (currentLoc lexbuf)) }
481|               ','                             {COMMA}
482|               '.'                             {DOT}
483|               "sizeof"                {SIZEOF (currentLoc lexbuf)}
484|               "__asm"                 { if !msvcMode then
485                                             MSASM (msasm lexbuf, currentLoc lexbuf)
486                                          else (ASM (currentLoc lexbuf)) }
487
488(* If we see __pragma we eat it and the matching parentheses as well *)
489|               "__pragma"              { matchingParsOpen := 0;
490                                          let _ = matchingpars lexbuf in
491                                          initial lexbuf
492                                        }
493
494(* __extension__ is a black. The parser runs into some conflicts if we let it
495 * pass *)
496|               "__extension__"         {initial lexbuf }
497|               ident                   {scan_ident lexbuf (Lexing.lexeme lexbuf)}
498|               eof                     {EOF}
499|               _                       {parse_error "Invalid symbol"; raise Parsing.Parse_error }
500and comment =
501    parse       
502      "*/"                              { () }
503|     eof                               { () }
504|     '\n'                              { newline lexbuf; comment lexbuf }
505|               _                       { comment lexbuf }
506
507
508and onelinecomment = parse
509    '\n'|eof    { () }
510|   _           { onelinecomment lexbuf }
511
512and matchingpars = parse
513  '\n'          { newline lexbuf; matchingpars lexbuf }
514| blank         { matchingpars lexbuf }
515| '('           { incr matchingParsOpen; matchingpars lexbuf }
516| ')'           { decr matchingParsOpen;
517                  if !matchingParsOpen = 0 then
518                     ()
519                  else
520                     matchingpars lexbuf
521                }
522|  "/*"         { comment lexbuf; matchingpars lexbuf}
523|  '"'          { (* '"' *)
524                  let _ = str lexbuf in
525                  matchingpars lexbuf
526                 }
527| _              { matchingpars lexbuf }
528
529(* # <line number> <file name> ... *)
530and hash = parse
531  '\n'          { newline lexbuf; initial lexbuf}
532| blank         { hash lexbuf}
533| intnum        { (* We are seeing a line number. This is the number for the
534                   * next line *)
535                  let s = Lexing.lexeme lexbuf in
536                  begin try
537                    setCurrentLine lexbuf (int_of_string s - 1)
538                  with Failure ("int_of_string") ->
539                    (* the int is too big. *)
540                    ()
541                  end;
542                  (* A file name may follow *)
543                  file lexbuf }
544| "line"        { hash lexbuf } (* MSVC line number info *)
545| "pragma" blank
546                { let here = currentLoc lexbuf in
547                  PRAGMA_LINE (pragma lexbuf, here)
548                }
549| _             { endline lexbuf}
550
551and file =  parse
552        '\n'                    { newline lexbuf; initial lexbuf}
553|       blank                   { file lexbuf}
554|       '"' [^ '\012' '\t' '"']* '"'    { (* '"' *)
555                                   let n = Lexing.lexeme lexbuf in
556                                   let n1 = String.sub n 1
557                                       ((String.length n) - 2) in
558                                   setCurrentFile lexbuf n1;
559                                 endline lexbuf}
560
561|       _                       { endline lexbuf}
562
563and endline = parse
564        '\n'                    { newline lexbuf; initial lexbuf}
565|   eof                         { EOF }
566|       _                       { endline lexbuf}
567
568and pragma = parse
569   '\n'                 { newline lexbuf; "" }
570|   _                   { let cur = Lexing.lexeme lexbuf in
571                          cur ^ (pragma lexbuf) } 
572
573and str = parse
574        '"'             {[]} (* no nul terminiation in CST_STRING '"' *)
575|       hex_escape      { lex_hex_escape str lexbuf}
576|       oct_escape      { lex_oct_escape str lexbuf}
577|       escape          { lex_simple_escape str lexbuf}
578|       _               { lex_unescaped str lexbuf}
579
580and chr =  parse
581        '\''            {[]}
582|       hex_escape      {lex_hex_escape chr lexbuf}
583|       oct_escape      {lex_oct_escape chr lexbuf}
584|       escape          {lex_simple_escape chr lexbuf}
585|       _               {lex_unescaped chr lexbuf}
586       
587and msasm = parse
588    blank               { msasm lexbuf }
589|   '{'                 { msasminbrace lexbuf }
590|   _                   { let cur = Lexing.lexeme lexbuf in
591                          cur ^ (msasmnobrace lexbuf) }
592
593and msasminbrace = parse
594    '}'                 { "" }
595|   _                   { let cur = Lexing.lexeme lexbuf in
596                          cur ^ (msasminbrace lexbuf) } 
597and msasmnobrace = parse
598   ['}' ';' '\n']       { lexbuf.Lexing.lex_curr_pos <-
599                               lexbuf.Lexing.lex_curr_pos - 1;
600                          "" }
601|  "__asm"              { lexbuf.Lexing.lex_curr_pos <-
602                               lexbuf.Lexing.lex_curr_pos - 5;
603                          "" }
604|  _                    { let cur = Lexing.lexeme lexbuf in
605
606                          cur ^ (msasmnobrace lexbuf) }
607
608{
609
610}
Note: See TracBrowser for help on using the repository browser.