initial
[prop.git] / tools / pretty / niceprop.l
blob4cc042e515b198cc1e917f472846bcbd1eee3df7
1 /*
2  *  This is a simple filter to typeset Prop code embedded in a LaTeX file.
3  *  It recognizes the environment \begin{prop} ... \end{prop} and typesets
4  *  everything in the environment as Prop code.  Also, inlined Prop code
5  *  can be embedded as in <|...|>.  For example, <| datatype T = ... |>.
6  */
8 %{
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
14 id              [a-zA-Z_][a-zA-Z_0-9]*
15 c_keywords_1    if|else|while|for|goto|break|case|continue|return
16 c_keywords_2    volatile|register|auto|static|const|inline
17 c_keywords_3    struct|class|union|switch|extern|unsigned|signed
18 c_keywords_4    public|private|protected|virtual
19 c_keywords      ({c_keywords_1}|{c_keywords_2}|{c_keywords_3}|{c_keywords_4})
20 int             [0-9]+
21 char            \'([^\'\n]|\\.[0-9a-f]*)\'
22 real            {int}(\.[0-9]*)?[eE]{int}|{int}\.[0-9]*([eE]{int})?
23 string          \"([^\"\n]|\\.)*\"
24 regexp          \/([^\/\n*]|\\.)([^\/\n]|\\.)*\/
25 pat_var         ([\?\#\$]*{id}[\'\?]*|\#\#)
26 logical_var     \'{id}
27 back_quoted     \`([^\`]|\\.)*\`
28 prop_keywords_1 datatype|type|view|collectable|printable|refine|match|matchall
29 prop_keywords_2 rewrite|inference|sharing|traced|persistent|unifiable|and
30 prop_keywords_3 where|with|instantiate|finalizable|constraint|syntax
31 prop_keywords_4 unique|matchscan|sythesized|law|inherited|relation|applicative
32 prop_keywords   ({prop_keywords_1}|{prop_keywords_2}|{prop_keywords_3}|{prop_keywords_4})
34 keywords        ({c_keywords}|{prop_keywords})  
36 binop1          (\+|\-|\*|\/|\%|\||\&|\^)
37 binop2          (\&\&|\|\||\=)
38 unaryop         (\-|\!|\~)
39 relop           (\>|\<|\>\=|\<\=|\=\=|\!\=)
40 punct           (\(|\)|\{|\}|\[|\]|\?|;|:|,|\.|\:\:|\-\>|\=\>)
41 punct2          (\(\||\|\)|\{\||\|\}|\[\||\|\]|\#\(|\#\{|\#\[)
42 symbols         ({binop1}|{binop1}=|{binop2}|{unaryop}|{relop}|{punct}|{punct2})
44 %S      TeX Prop1 Prop2 Comment1 Comment2
48 int stack[256];
49 int top = 0; 
50 int sc  = 0;
51 #define PUSH(S) ((stack[top++] = sc), (BEGIN((sc = S))))
52 #define POP()   (BEGIN((sc = stack[--top])))
54 #define echo(text) fputs(text,stdout)
55 #define BEGIN_PROP1 "{\\CF\\begin{tabular}{l}\n"
56 #define END_PROP1   "\\end{tabular}}"
57 #define BEGIN_PROP2 "{\\CF "
58 #define END_PROP2   "}"
59 #define BEGIN_COMMENT1 "---{\\em "
60 #define END_COMMENT1   "}\\\\\n"
61 #define BEGIN_COMMENT2 "\verb./*.{\\em "
62 #define END_COMMENT2   "}\verb.*/."
64 void begin_prop1()    { PUSH(Prop1); echo(BEGIN_PROP1); }
65 void begin_prop2()    { PUSH(Prop2); echo(BEGIN_PROP2); }
66 void end_prop1()      { POP(); echo(END_PROP1); }
67 void end_prop2()      { POP(); echo(END_PROP2); }
68 void begin_comment1() { PUSH(Comment1); echo(BEGIN_COMMENT1); }
69 void begin_comment2() { PUSH(Comment2); echo(BEGIN_COMMENT2); }
70 void end_comment1()   { POP(); echo(END_COMMENT1); }
71 void end_comment2()   { POP(); echo(END_COMMENT2); }
73 void ident (const char * id)
74 {  for ( ; *id; id++)
75    {  if (*id == '_') echo("\\_"); 
76       else            putchar(*id);
77    }
80 void math (const char * symbol) { putchar('$'); echo(symbol); putchar('$'); }
82 void keyword (const char * text) { printf("{\\KW %s}",text); }
84 void tab (const char * spaces)
85 {  for ( ;*spaces; spaces++)
86    {  if (*spaces == '\t') echo("\\ \\ \\ ");
87       else echo("\\ ");
88    }
91 void verbatim(const char * text)
92 {  const char * quotes = ".|!~#$%^&-+=";
93    for ( ; *quotes; quotes++)
94    {  if (! strchr(text,*quotes))
95       {  printf("\\verb%c%s%c",*quotes,text,*quotes); return; }
96    }
97    fprintf(stderr,"Bad string %s\n", text);
98    exit(1);
101 void rule(const char * text)
102 {  for( ; *text; text++)
103      if (*text == '/') echo ("--");
109 <TeX>\\begin\{prop\}[\t ]*\n                    { begin_prop1(); }
110 <TeX>\\begin\{prop\}                            { begin_prop1(); }
111 <TeX>\<\|                                       { begin_prop2(); }
112 <TeX>.|\n                                       { echo(yytext); }
114 <Prop1>\\end\{prop\}                            { end_prop1(); }
115 <Prop2>\|\>                                     { end_prop2(); }
116 <Prop1,Prop2>{keywords}                         { keyword(yytext); }
117 <Prop1,Prop2,Comment1,Comment2>{string}         { verbatim(yytext); }
118 <Prop1,Prop2,Comment1,Comment2>{char}           { verbatim(yytext); }
119 <Prop1,Prop2,Comment1,Comment2>\*               { math("\\times"); }
120 <Prop1,Prop2,Comment1,Comment2>\-\>             { math("\\rightarrow"); }
121 <Prop1,Prop2,Comment1,Comment2>\=\>             { math("\\Rightarrow"); }
122 <Prop1,Prop2,Comment1,Comment2>\>=              { math("\\ge"); }
123 <Prop1,Prop2,Comment1,Comment2>\<=              { math("\\le"); }
124 <Prop1,Prop2,Comment1,Comment2>\!\=             { math("\\ne"); }
125 <Prop1,Prop2,Comment1,Comment2>\%               { math("\\%"); }
126 <Prop1,Prop2,Comment1,Comment2>\%\=             { math("\\%="); }
127 <Prop1,Prop2,Comment1,Comment2>\^               { math("\\verb.^."); }
128 <Prop1,Prop2,Comment1,Comment2>\&               { echo("\\verb.&."); }
129 <Prop1,Prop2,Comment1,Comment2>\&\&             { math("\\land"); }
130 <Prop1,Prop2,Comment1,Comment2>\|\|             { math("\\lor"); }
131 <Prop1,Prop2,Comment1,Comment2>\*\=             { math("\\times="); }
132 <Prop1,Prop2,Comment1,Comment2>\#\(             { math("\\verb.#.("); }
133 <Prop1,Prop2,Comment1,Comment2>\#\{             { math("\\verb.#.\{"); }
134 <Prop1,Prop2,Comment1,Comment2>\#\[             { math("\\verb.#.["); }
135 <Prop1,Prop2,Comment1,Comment2>\{               { math("\\{"); }
136 <Prop1,Prop2,Comment1,Comment2>\}               { math("\\}"); }
137 <Prop1,Prop2,Comment1,Comment2>{symbols}        { math(yytext); }
138 <Prop1,Prop2,Comment1,Comment2>\#               { echo("\\verb.#."); }
139 <Prop1,Prop2,Comment1,Comment2>{id}             { ident(yytext); }
140 <Prop1,Prop2,Comment2>^[\t ]+                   { tab(yytext); }
141 <Prop1,Prop2,Comment2>.                         { echo(yytext); }
142 <Prop1,Prop2>\n                                 { echo("\\\\\n"); }
143 <Prop1,Prop2>\/\/                               { begin_comment1(); }
144 <Prop1,Prop2>\/\*                               { begin_comment2(); }
146 <Comment1>\/+\ */\n                             { rule(yytext); end_comment1(); }
147 <Comment1>\n                                    { end_comment1(); }
148 <Comment2>\*\/                                  { end_comment2(); }
151 #undef yywrap
152 int yywrap() { return 1; }
154 int main()
155 {  printf("\\newfont{\\KW}{cmssbx9}\n"
156           "\\newfont{\\CF}{cmssq8}\n");
157    PUSH(TeX);
158    yylex();
159    return 0;