Another way would be to only use two rules:
"0" [0-9]+
"0" | ( [1-9] [0-9]* )
-
+ A full description of re2c rule syntax can be found in the manual.
*/
#include <stdlib.h>
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
+ DEBUG(printf("+\n"));
return 0;
}
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
+ DEBUG(printf("-\n"));
return 0;
}
-int scan(char *s, int l)
+int scan(char *s)
{
char *p = s;
char *t;
#define YYCTYPE char
#define YYCURSOR p
- if (l > 1 && s[l-2] == '0' && s[l-1] >= '0' && s[l-1] <= '9') return 2;
-
while(!res)
{
t = p;
yych = *YYCURSOR;
goto yy21;
yy3:
-#line 114 "calc_006.s.re"
+#line 105 "calc_006.s.re"
{ continue; }
#line 98 "<stdout>"
yy4:
if((yych = *YYCURSOR) <= '/') goto yy5;
if(yych <= '9') goto yy17;
yy5:
-#line 116 "calc_006.s.re"
+#line 107 "calc_006.s.re"
{ res = push_num(t, p, 10); continue; }
#line 106 "<stdout>"
yy6:
goto yy16;
yy7:
++YYCURSOR;
-#line 117 "calc_006.s.re"
+#line 108 "calc_006.s.re"
{ res = stack_add(); continue; }
#line 114 "<stdout>"
yy9:
++YYCURSOR;
-#line 118 "calc_006.s.re"
+#line 109 "calc_006.s.re"
{ res = stack_sub(); continue; }
#line 119 "<stdout>"
yy11:
++YYCURSOR;
-#line 119 "calc_006.s.re"
+#line 110 "calc_006.s.re"
{ res = depth == 1 ? 0 : 2; continue; }
#line 124 "<stdout>"
yy13:
++YYCURSOR;
-#line 120 "calc_006.s.re"
+#line 111 "calc_006.s.re"
{ res = 1; continue; }
#line 129 "<stdout>"
yy15:
if(yych <= '/') goto yy19;
if(yych <= '9') goto yy17;
yy19:
-#line 115 "calc_006.s.re"
+#line 106 "calc_006.s.re"
{ res = push_num(t, p, 8); continue; }
#line 145 "<stdout>"
yy20:
if(yych == ' ') goto yy20;
goto yy3;
}
-#line 121 "calc_006.s.re"
+#line 112 "calc_006.s.re"
}
return res;
++inp;
len -=2;
}
- res = scan(inp, len);
+ res = scan(inp);
}
switch(res)
{
In the example suppose "0" is passed. The scanner reads the first "0" and
then is in an undecided state. The scanner can earliest decide on the next
char what the token is. In case of a zero the input ends and it was a
- number, 0 to be precise. In case of a didit it is and the next character
- needs to be read. In case of any other character the scanner has found an
- error with the any rule [^].
+ number, 0 to be precise. In case of a digit it is an octal number and the
+ next character needs to be read. In case of any other character the scanner
+ will detect an error with the any rule [^].
- Now the above shows that re2c may read two characters directly. But only if
- the first is a "0". So we could easily check that if the first char is "0"
- another charcter is present.
+ Now the above shows that the scanner may read two characters directly. But
+ only if the first is a "0". So we could easily check that if the first char
+ is "0" and the next char is a digit then yet another charcter is present.
+ But we require our inut to be zero terminated. And that means we do not
+ have to check anything for this scanner.
- if (p[0] == '0' && p[1] == '\0') return 2;
-
- But instead of doing so in every loop we can optimize by taking into
- account what we know from our input analysis. That is a problem can only
- arise when the second last character is a "0" and the last is any digit.
-
- if (l > 1 && s[l-2] == '0' && s[l-1] >= '0' && s[l-1] <= '9') return 2;
-
- However in this example the above check is only necessary if the input is
- not terminated by a trailing zero check. In other words it would be used
- when reading from a file and directly working on the read buffers. For
- zero terminated string input the generated scanner will always find the
- terminating zero.
+ However with other rule sets re2c might read more then one character in a
+ row. In those cases it is normally hard to impossible to avoid YYFILL.
- optimizing the generated code by using -s command line switch of re2c
. This tells re2c to generate code that uses if statements rather
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
+ DEBUG(printf("+\n"));
return 0;
}
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
+ DEBUG(printf("-\n"));
return 0;
}
-int scan(char *s, int l)
+int scan(char *s)
{
char *p = s;
char *t;
#define YYCTYPE char
#define YYCURSOR p
- if (l > 1 && s[l-2] == '0' && s[l-1] >= '0' && s[l-1] <= '9') return 2;
-
while(!res)
{
t = p;
++inp;
len -=2;
}
- res = scan(inp, len);
+ res = scan(inp);
}
switch(res)
{
/* Generated by re2c */
#line 1 "calc_007.b.re"
-/* re2c lesson_001, calc_006, (c) M. Boerger 2006 */
+/* re2c lesson_001, calc_007, (c) M. Boerger 2006 */
#include <stdlib.h>
#include <stdio.h>
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
+ DEBUG(printf("+\n"));
return 0;
}
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
+ DEBUG(printf("+\n"));
return 0;
}
-int scan(char *s, int l)
+int scan(char *s)
{
char *p = s;
char *t;
#define YYCTYPE char
#define YYCURSOR p
- if (l > 1 && s[l-2] == '0' && s[l-1] >= '0' && s[l-1] <= '9') return 2;
-
while(!res)
{
t = p;
++inp;
len -=2;
}
- res = scan(inp, len);
+ res = scan(inp);
}
switch(res)
{
-/* re2c lesson_001, calc_006, (c) M. Boerger 2006 */
+/* re2c lesson_001, calc_007, (c) M. Boerger 2006 */
/*!ignore:re2c
- optimizing the generated code by using -b command line switch of re2c
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
+ DEBUG(printf("+\n"));
return 0;
}
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
+ DEBUG(printf("+\n"));
return 0;
}
-int scan(char *s, int l)
+int scan(char *s)
{
char *p = s;
char *t;
#define YYCTYPE char
#define YYCURSOR p
- if (l > 1 && s[l-2] == '0' && s[l-1] >= '0' && s[l-1] <= '9') return 2;
-
while(!res)
{
t = p;
++inp;
len -=2;
}
- res = scan(inp, len);
+ res = scan(inp);
}
switch(res)
{