]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/mathml_editor/src/TPushLexer.cc
Now it's possible to insert and delete control sequence with arguments
[helm.git] / helm / DEVEL / mathml_editor / src / TPushLexer.cc
1
2 #include "TToken.hh"
3 #include "TPushLexer.hh"
4 #include "APushParser.hh"
5
6 TPushLexer::TPushLexer(APushParser& p) : APushLexer(p)
7 {
8   state = ACCEPT;
9 }
10
11 void
12 TPushLexer::reset()
13 {
14   buffer.erase();
15   state = ACCEPT;
16 }
17
18 void
19 TPushLexer::flush()
20 {
21   push(-1);
22 }
23
24 void
25 TPushLexer::transaction(char ch, State newState)
26 {
27   switch (ch)
28     {
29     case '{': parser.push(TToken(TToken::BEGIN)); break;
30     case '}': parser.push(TToken(TToken::END)); break;
31     case '$': parser.push(TToken(TToken::SHIFT)); break;
32     case '&': parser.push(TToken(TToken::ALIGN)); break;
33     case '\n':
34     case '\r': parser.push(TToken(TToken::EOL, ch)); break;
35     case '^': parser.push(TToken(TToken::SUPERSCRIPT)); break;
36     case '_': parser.push(TToken(TToken::SUBSCRIPT)); break;
37     case '\t':
38     case ' ': parser.push(TToken(TToken::SPACE, ch)); break;
39     case '~': parser.push(TToken(TToken::ACTIVE, ch)); break;
40     case '%': parser.push(TToken(TToken::COMMENT)); break;     
41     default:
42       if (isalpha(ch)) parser.push(TToken(TToken::LETTER, ch));
43       else if (isdigit(ch)) parser.push(TToken(TToken::DIGIT, ch));
44       else parser.push(TToken(TToken::OTHER, ch));
45       break;
46     }
47   state = newState;
48 }
49
50 void
51 TPushLexer::push(char ch)
52 {
53   switch (state)
54     {
55     case ACCEPT:
56       if (ch == '\\') state = ESCAPE;
57       else if (ch == '#') state = PARAMETER;
58       else if (ch == '\b') parser.push(TToken(TToken::GDELETE));
59       else if (ch == -1) ;
60       else transaction(ch, ACCEPT);
61       break;
62     case ESCAPE:
63       if (isalpha(ch))
64         {
65           buffer.push_back(ch);
66           state = MACRO;
67         }
68       else if (ch == '\b')
69         {
70           state = ACCEPT;
71         }
72       else if (ch == -1) error();
73       else
74         {
75           parser.push(TToken(TToken::CONTROL, ch));
76           state = ACCEPT;
77         }
78       break;
79     case MACRO:
80       if (ch == '\\')
81         {
82           parser.push(TToken(TToken::CONTROL, buffer));
83           buffer.erase();
84           state = ESCAPE;
85         }
86       else if (ch == '#')
87         {
88           parser.push(TToken(TToken::CONTROL, buffer));
89           buffer.erase();
90           state = PARAMETER;
91         }
92       else if (ch == '\b')
93         {
94           buffer.erase(buffer.length() - 1, 1);
95           if (buffer.length() == 0) state = ESCAPE;
96         }
97       else if (isalpha(ch))
98         buffer.push_back(ch);
99       else if (ch == -1)
100         {
101           parser.push(TToken(TToken::CONTROL, buffer));
102           buffer.erase();
103           state = ACCEPT;
104         }
105       else
106         {
107           parser.push(TToken(TToken::CONTROL, buffer));
108           buffer.erase();
109           if (isspace(ch)) state = IGNORE_SPACE;
110           else transaction(ch, ACCEPT);
111         }
112       break;
113     case IGNORE_SPACE:
114       if (ch == '\\') state = ESCAPE;
115       else if (ch == '#') state = PARAMETER;
116       else if (isspace(ch)) ;
117       else if (ch == '\b') parser.push(TToken(TToken::GDELETE));
118       else if (ch == -1) state = ACCEPT;
119       else transaction(ch, ACCEPT);
120       break;
121     case PARAMETER:
122       if (ch == -1) error();
123       else
124         {
125           parser.push(TToken(TToken::PARAMETER, ch));
126           state = ACCEPT;
127         }
128       break;
129     default:
130       assert(0);
131       break;
132     }
133
134   switch (state)
135     {
136     case ESCAPE: parser.setCursor("\\"); break;
137     case MACRO: parser.setCursor("\\" + buffer); break;
138     case PARAMETER: parser.setCursor("#"); break;
139     default: parser.setCursor("?"); break;
140     }
141 }
142
143 bool
144 TPushLexer::error() const
145 {
146   return false;
147 }