bnf.mll 4.61 KB
Newer Older
MARCHE Claude's avatar
MARCHE Claude committed
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
(* $Id: transf.mll,v 1.11 2009-03-03 09:53:08 uid562 Exp $ *)

{ open Lexing;;
  let idx = Buffer.create 5
  let full_kw = Buffer.create 5

  let modern = ref false

  let escape_keyword s =
    let buf = Buffer.create 5 in
    String.iter
      (function
           c when ('A' <= c && c <= 'Z') ||
                  ('a' <= c && c <= 'z') ||
                  ('0' <= c && c <= '9')
             -> Buffer.add_char buf c
         | c -> Buffer.add_string buf
             (Printf.sprintf "\\char%d" (int_of_char c))) s;
    Buffer.contents buf

  let make_keyword () =
    let keyword = Buffer.contents full_kw in
    let index = Buffer.contents idx in
    print_string "\\addspace";
    if !modern then
      Printf.printf
        "\\lstinline$%s$" keyword
    else
      Printf.printf "\\texttt{%s}" (escape_keyword keyword);
    if index <> "" then
      Printf.printf "\\indextt%s{%s}"
        (if keyword.[0] = '\\' then "bs" else "") index;
    print_string "\\spacetrue";
    Buffer.clear idx;
    Buffer.clear full_kw
}

rule main = parse
    "\\begin{syntax}" {
      print_string "\\begin{syntax}";
      syntax lexbuf }
  | "\\@" {
      print_string "@";
      main lexbuf }
  | _ {
      print_char (lexeme_char lexbuf 0); main lexbuf }
  | eof {
      () }

and syntax = parse
    "\\end{syntax}" {
      print_string "\\end{syntax}";
      main lexbuf }
  | ";" ([^ '\n']* as s) '\n' [' ''\t']* '|' {
      print_string "& \\textrm{";
      print_string s;
      print_string "} \\alt{}";
      syntax lexbuf }
  | ";" ([^ '\n']* as s) '\n' [' ''\t']* '\\' [' ''\t']* '\n' {
      print_string "& \\textrm{";
      print_string s;
      print_string "} \\sep{}";
      syntax lexbuf }
  | ";" ([^ '\n']* as s) '\n' {
      print_string "& \\textrm{";
      print_string s;
      print_string "} \\newl{}";
      syntax lexbuf }
  | "@" {
      print_string "}";
      main lexbuf }
  | '\'' {
      Buffer.clear idx;
      Buffer.clear full_kw;
      inquote lexbuf }
  | '"' {
      Buffer.clear idx;
      Buffer.clear full_kw;
      indoublequote lexbuf }
  | "below" { print_string "\\below"; syntax lexbuf }
  | "epsilon" { print_string "\\emptystring"; syntax lexbuf }
  | ['A'-'Z''a'-'z''-'] + {
      print_string "\\nonterm{";
      print_string (lexeme lexbuf);
      print_string"}";
      check_nonterm_note lexbuf }
  | '\\' ['a'-'z''A'-'Z'] + {
      print_string (lexeme lexbuf);
      syntax lexbuf }
  | ['_' '^'] _ {
      print_string (lexeme lexbuf);
      syntax lexbuf }
  | "*" { print_string "\\repetstar{}"; syntax lexbuf }
  | "+" { print_string "\\repetplus{}"; syntax lexbuf }
  | "?" { print_string "\\repetone{}"; syntax lexbuf }
  | "(" { print_string "\\lparen{}"; syntax lexbuf }
  | ")" { print_string "\\rparen{}"; syntax lexbuf }
  | "::=" { print_string "\\is{}"; syntax lexbuf }
  | "|" { print_string "\\orelse{}"; syntax lexbuf }
  | "\\" { print_string "\\sep{}"; syntax lexbuf }
  | "{" { print_string "\\begin{notimplementedenv}"; check_implementation_note lexbuf }
  | "}" { print_string "\\end{notimplementedenv}"; syntax lexbuf }
  | _ {
      print_char (lexeme_char lexbuf 0);
      syntax lexbuf }

and inquote = parse
    ['A'-'Z' 'a'-'z' '0'-'9' '?'] as c {
      Buffer.add_char full_kw c;
      Buffer.add_char idx c;
      inquote lexbuf }
  | '\'' {
      make_keyword ();
      syntax lexbuf }
  | '_' {
      Buffer.add_char full_kw '_';
      Buffer.add_string idx "\\_";
      inquote lexbuf
    }
  | _ as c {
      Buffer.add_char full_kw c;
      inquote lexbuf }

and indoublequote = parse
    ['A'-'Z' 'a'-'z' '0'-'9' '?'] as c {
      Buffer.add_char full_kw c;
      Buffer.add_char idx c;
      indoublequote lexbuf }
  | '"' {
      make_keyword();
      syntax lexbuf }
  | '_' {
      Buffer.add_char full_kw '_';
      Buffer.add_string idx "\\_";
      indoublequote lexbuf
    }
  | _ as c {
      Buffer.add_char full_kw c;
      indoublequote lexbuf }
and check_implementation_note = parse
  | "[" { print_string "["; implementation_note lexbuf }
  | "" { syntax lexbuf }
and implementation_note = parse
    "]" { print_string "]"; syntax lexbuf }
  | _  { print_char (lexeme_char lexbuf 0);
           implementation_note lexbuf }
and check_nonterm_note = parse
  | "[" { print_string "{"; nonterm_note lexbuf }
  | ""  { print_string "{}"; syntax lexbuf }
and nonterm_note = parse
    "]" { print_string "}"; syntax lexbuf }
  | _  { print_char (lexeme_char lexbuf 0);
           nonterm_note lexbuf }

{

  let () = Arg.parse
    [ "-modern", Arg.Set modern, "set modern style"; ]
    (fun f ->
       let cin = open_in f in
       let lb = from_channel cin in
       main lb;
       close_in cin)
    "transf [-modern] file"

}