mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 12:11:25 +00:00
- Undid some of the changes from lempar.c v1.30->v1.31, because it broke
error handling. - Fixed: dehsupp/scanner.re defined "}" as the token RPAREN. dehsupp/parse.y also defined action_list_def as needing a RBARCE. I'm surprised it worked at all before. I guess Lemon really was too accepting. - Changed the way that xlatcc handles include statements so that I don't need to modify the logic of lempar.c. I also discovered that the grammar was improperly defined and only accepted the first statement. It worked before because Lemon used to accept multiple times before reaching the EOF token. I have also verified that it is still generating the proper lumps. - Removed some unused wadsrc files from the repository. - Fixed my re2c upgrade. - Updated lemon.c to v1.53. SVN r711 (trunk)
This commit is contained in:
parent
e5572a1c4e
commit
ec17f5a5b9
46 changed files with 9134 additions and 8988 deletions
|
@ -1,4 +1,22 @@
|
||||||
January 25, 2008
|
January 25, 2008
|
||||||
|
- Undid some of the changes from lempar.c v1.30->v1.31, because it broke
|
||||||
|
error handling.
|
||||||
|
- Fixed: dehsupp/scanner.re defined "}" as the token RPAREN. dehsupp/parse.y
|
||||||
|
also defined action_list_def as needing a RBARCE. I'm surprised it worked
|
||||||
|
at all before. I guess Lemon really was too accepting. I have verified that
|
||||||
|
the lump it outputs is unchanged from before.
|
||||||
|
- Changed the way that xlatcc handles include statements so that I don't need
|
||||||
|
to modify the logic of lempar.c. I also discovered that the grammar was
|
||||||
|
improperly defined and only accepted the first statement. It worked before
|
||||||
|
because Lemon used to accept multiple times before reaching the EOF token.
|
||||||
|
I have also verified that it is still generating the proper lumps.
|
||||||
|
- Removed some unused wadsrc files from the repository.
|
||||||
|
- Fixed my re2c upgrade.
|
||||||
|
- Back to lemon.c v1.53 now. The bad change was v1.51: "Changes lemon so
|
||||||
|
that the generated parser does not accept prior to seeing the EOF token."
|
||||||
|
This seems like a valid change, which means I need to rethink my strategy
|
||||||
|
for handling include statements, since this change breaks what I was
|
||||||
|
doing before.
|
||||||
- Lemon is now producing parsers that don't accept anything, so I'm going
|
- Lemon is now producing parsers that don't accept anything, so I'm going
|
||||||
back to v1.43 and trying each intermediate version to see where things
|
back to v1.43 and trying each intermediate version to see where things
|
||||||
went wrong.
|
went wrong.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Generated by re2c 0.10.5 */
|
/* Generated by re2c 0.12.3 */
|
||||||
#line 1 "src/sc_man_scanner.re"
|
#line 1 "src/sc_man_scanner.re"
|
||||||
#define YYCTYPE char
|
#define YYCTYPE char
|
||||||
#define YYCURSOR cursor
|
#define YYCURSOR cursor
|
||||||
|
@ -42,7 +42,7 @@ std2:
|
||||||
|
|
||||||
if((YYLIMIT - YYCURSOR) < 18) YYFILL(18);
|
if((YYLIMIT - YYCURSOR) < 18) YYFILL(18);
|
||||||
yych = *YYCURSOR;
|
yych = *YYCURSOR;
|
||||||
switch(yych){
|
switch(yych) {
|
||||||
case 0x09:
|
case 0x09:
|
||||||
case 0x0B:
|
case 0x0B:
|
||||||
case 0x0C:
|
case 0x0C:
|
||||||
|
@ -181,7 +181,7 @@ yy5:
|
||||||
#line 182 "src/sc_man_scanner.h"
|
#line 182 "src/sc_man_scanner.h"
|
||||||
yy6:
|
yy6:
|
||||||
yych = *++YYCURSOR;
|
yych = *++YYCURSOR;
|
||||||
switch(yych){
|
switch(yych) {
|
||||||
case 'A':
|
case 'A':
|
||||||
case 'a': goto yy536;
|
case 'a': goto yy536;
|
||||||
case 'H':
|
case 'H':
|
||||||
|
@ -309,7 +309,7 @@ yy12:
|
||||||
goto yy174;
|
goto yy174;
|
||||||
yy13:
|
yy13:
|
||||||
yych = *++YYCURSOR;
|
yych = *++YYCURSOR;
|
||||||
switch(yych){
|
switch(yych) {
|
||||||
case 'B':
|
case 'B':
|
||||||
case 'b': goto yy346;
|
case 'b': goto yy346;
|
||||||
case 'E':
|
case 'E':
|
||||||
|
@ -330,7 +330,7 @@ yy13:
|
||||||
}
|
}
|
||||||
yy14:
|
yy14:
|
||||||
yych = *++YYCURSOR;
|
yych = *++YYCURSOR;
|
||||||
switch(yych){
|
switch(yych) {
|
||||||
case 'I':
|
case 'I':
|
||||||
case 'i': goto yy326;
|
case 'i': goto yy326;
|
||||||
case 'L':
|
case 'L':
|
||||||
|
|
|
@ -48,6 +48,9 @@ int main (int argc, char **argv)
|
||||||
printf ("Could not open %s\n", argv[1]);
|
printf ("Could not open %s\n", argv[1]);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
#if !defined(NDEBUG) && 0
|
||||||
|
ParseTrace(fopen("trace.txt", "w"), "");
|
||||||
|
#endif
|
||||||
SourceLine = 1;
|
SourceLine = 1;
|
||||||
yyparse ();
|
yyparse ();
|
||||||
fclose (Source);
|
fclose (Source);
|
||||||
|
|
|
@ -424,7 +424,7 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
Description="Creating scanner.c from scanner.re"
|
Description="Creating scanner.c from scanner.re"
|
||||||
CommandLine="..\re2c\re2c -s -o "scanner.c" "$(InputFileName)"
"
|
CommandLine="..\re2c\re2c -s --no-generation-date -o "scanner.c" "$(InputFileName)"
"
|
||||||
Outputs="$(InputDir)scanner.c"
|
Outputs="$(InputDir)scanner.c"
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
|
@ -444,7 +444,7 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
Description="Creating scanner.c from scanner.re"
|
Description="Creating scanner.c from scanner.re"
|
||||||
CommandLine="..\re2c\re2c -s -o "scanner.c" "$(InputFileName)"
"
|
CommandLine="..\re2c\re2c -s --no-generation-date -o "scanner.c" "$(InputFileName)"
"
|
||||||
Outputs="$(InputDir)scanner.c"
|
Outputs="$(InputDir)scanner.c"
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,14 +21,13 @@
|
||||||
#define SYM 21
|
#define SYM 21
|
||||||
#define OrgHeights 22
|
#define OrgHeights 22
|
||||||
#define ActionList 23
|
#define ActionList 23
|
||||||
#define RBARCE 24
|
#define CodePConv 24
|
||||||
#define CodePConv 25
|
#define OrgSprNames 25
|
||||||
#define OrgSprNames 26
|
#define StateMap 26
|
||||||
#define StateMap 27
|
#define FirstState 27
|
||||||
#define FirstState 28
|
#define SpawnState 28
|
||||||
#define SpawnState 29
|
#define DeathState 29
|
||||||
#define DeathState 30
|
#define SoundMap 30
|
||||||
#define SoundMap 31
|
#define InfoNames 31
|
||||||
#define InfoNames 32
|
#define ThingBits 32
|
||||||
#define ThingBits 33
|
#define RenderStyles 33
|
||||||
#define RenderStyles 34
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
%token_type {struct Token}
|
%token_type {struct Token}
|
||||||
|
|
||||||
|
%syntax_error { yyerror("Syntax error"); }
|
||||||
|
|
||||||
%token_destructor { if ($$.string) free($$.string); }
|
%token_destructor { if ($$.string) free($$.string); }
|
||||||
|
|
||||||
%left OR.
|
%left OR.
|
||||||
|
@ -60,6 +62,7 @@ exp(A) ::= LPAREN exp(B) RPAREN. { A = B; }
|
||||||
|
|
||||||
|
|
||||||
actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON.
|
actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON.
|
||||||
|
actions_def ::= Actions LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
actions_list ::= . /* empty */
|
actions_list ::= . /* empty */
|
||||||
actions_list ::= SYM(A). { AddAction (A.string); }
|
actions_list ::= SYM(A). { AddAction (A.string); }
|
||||||
|
@ -67,13 +70,15 @@ actions_list ::= actions_list COMMA SYM(A). { AddAction (A.string); }
|
||||||
|
|
||||||
|
|
||||||
org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON.
|
org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON.
|
||||||
|
org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
org_heights_list ::= . /* empty */
|
org_heights_list ::= . /* empty */
|
||||||
org_heights_list ::= exp(A). { AddHeight (A); }
|
org_heights_list ::= exp(A). { AddHeight (A); }
|
||||||
org_heights_list ::= org_heights_list COMMA exp(A). { AddHeight (A); }
|
org_heights_list ::= org_heights_list COMMA exp(A). { AddHeight (A); }
|
||||||
|
|
||||||
|
|
||||||
action_list_def ::= ActionList LBRACE action_list_list RBARCE SEMICOLON.
|
action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON.
|
||||||
|
action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
action_list_list ::= . /* empty */
|
action_list_list ::= . /* empty */
|
||||||
action_list_list ::= SYM(A). { AddActionMap (A.string); }
|
action_list_list ::= SYM(A). { AddActionMap (A.string); }
|
||||||
|
@ -81,6 +86,7 @@ action_list_list ::= action_list_list COMMA SYM(A). { AddActionMap (A.string); }
|
||||||
|
|
||||||
|
|
||||||
codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON.
|
codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON.
|
||||||
|
codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
codep_conv_list ::= . /* empty */
|
codep_conv_list ::= . /* empty */
|
||||||
codep_conv_list ::= exp(A). { AddCodeP (A); }
|
codep_conv_list ::= exp(A). { AddCodeP (A); }
|
||||||
|
@ -88,6 +94,7 @@ codep_conv_list ::= codep_conv_list COMMA exp(A). { AddCodeP (A); }
|
||||||
|
|
||||||
|
|
||||||
org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON.
|
org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON.
|
||||||
|
org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
org_spr_names_list ::= . /* empty */
|
org_spr_names_list ::= . /* empty */
|
||||||
org_spr_names_list ::= SYM(A). { AddSpriteName (A.string); }
|
org_spr_names_list ::= SYM(A). { AddSpriteName (A.string); }
|
||||||
|
@ -95,6 +102,7 @@ org_spr_names_list ::= org_spr_names_list COMMA SYM(A). { AddSpriteName (A.strin
|
||||||
|
|
||||||
|
|
||||||
state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON.
|
state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON.
|
||||||
|
state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
state_map_list ::= . /* empty */
|
state_map_list ::= . /* empty */
|
||||||
state_map_list ::= state_map_entry.
|
state_map_list ::= state_map_entry.
|
||||||
|
@ -109,6 +117,7 @@ state_type(A) ::= DeathState. { A = 2; }
|
||||||
|
|
||||||
|
|
||||||
sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON.
|
sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON.
|
||||||
|
sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
sound_map_list ::= . /* empty */
|
sound_map_list ::= . /* empty */
|
||||||
sound_map_list ::= STRING(A). { AddSoundMap (A.string); }
|
sound_map_list ::= STRING(A). { AddSoundMap (A.string); }
|
||||||
|
@ -116,6 +125,7 @@ sound_map_list ::= sound_map_list COMMA STRING(A). { AddSoundMap (A.string); }
|
||||||
|
|
||||||
|
|
||||||
info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON.
|
info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON.
|
||||||
|
info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
info_names_list ::= . /* empty */
|
info_names_list ::= . /* empty */
|
||||||
info_names_list ::= SYM(A). { AddInfoName (A.string); }
|
info_names_list ::= SYM(A). { AddInfoName (A.string); }
|
||||||
|
@ -123,6 +133,7 @@ info_names_list ::= info_names_list COMMA SYM(A). { AddInfoName (A.string); }
|
||||||
|
|
||||||
|
|
||||||
thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON.
|
thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON.
|
||||||
|
thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
thing_bits_list ::= . /* empty */
|
thing_bits_list ::= . /* empty */
|
||||||
thing_bits_list ::= thing_bits_entry.
|
thing_bits_list ::= thing_bits_entry.
|
||||||
|
@ -132,6 +143,7 @@ thing_bits_entry ::= exp(A) COMMA exp(B) COMMA SYM(C). { AddThingBits (C.string,
|
||||||
|
|
||||||
|
|
||||||
render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON.
|
render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON.
|
||||||
|
render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON.
|
||||||
|
|
||||||
render_styles_list ::= . /* empty */
|
render_styles_list ::= . /* empty */
|
||||||
render_styles_list ::= render_styles_entry.
|
render_styles_list ::= render_styles_entry.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -106,7 +106,7 @@ ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
|
||||||
"*" { RET(MULTIPLY); }
|
"*" { RET(MULTIPLY); }
|
||||||
"/" { RET(DIVIDE); }
|
"/" { RET(DIVIDE); }
|
||||||
"(" { RET(LPAREN); }
|
"(" { RET(LPAREN); }
|
||||||
"}" { RET(RPAREN); }
|
")" { RET(RPAREN); }
|
||||||
"," { RET(COMMA); }
|
"," { RET(COMMA); }
|
||||||
"{" { RET(LBRACE); }
|
"{" { RET(LBRACE); }
|
||||||
"}" { RET(RBRACE); }
|
"}" { RET(RBRACE); }
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#ifndef __WIN32__
|
#ifndef __WIN32__
|
||||||
# if defined(_WIN32) || defined(WIN32)
|
# if defined(_WIN32) || defined(WIN32)
|
||||||
|
@ -22,6 +23,12 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WIN32__
|
||||||
|
extern int access();
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* #define PRIVATE static */
|
/* #define PRIVATE static */
|
||||||
#define PRIVATE
|
#define PRIVATE
|
||||||
|
|
||||||
|
@ -31,19 +38,11 @@
|
||||||
#define MAXRHS 1000
|
#define MAXRHS 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *msort(void *list, void *next, int (*cmp)());
|
static void *msort(void *list, void *next, int (*cmp)());
|
||||||
|
|
||||||
/******** From the file "action.h" *************************************/
|
/******** From the file "action.h" *************************************/
|
||||||
struct action *Action_new();
|
static struct action *Action_new(void);
|
||||||
struct action *Action_sort();
|
static struct action *Action_sort(struct action *);
|
||||||
|
|
||||||
/********* From the file "assert.h" ************************************/
|
|
||||||
void myassert();
|
|
||||||
#ifndef NDEBUG
|
|
||||||
# define assert(X) if(!(X))myassert(__FILE__,__LINE__)
|
|
||||||
#else
|
|
||||||
# define assert(X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********** From the file "build.h" ************************************/
|
/********** From the file "build.h" ************************************/
|
||||||
void FindRulePrecedences();
|
void FindRulePrecedences();
|
||||||
|
@ -114,7 +113,7 @@ int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */
|
||||||
** Principal data structures for the LEMON parser generator.
|
** Principal data structures for the LEMON parser generator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum {B_FALSE=0, B_TRUE} Boolean;
|
typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean;
|
||||||
|
|
||||||
/* Symbols (terminals and nonterminals) of the grammar are stored
|
/* Symbols (terminals and nonterminals) of the grammar are stored
|
||||||
** in the following: */
|
** in the following: */
|
||||||
|
@ -137,6 +136,7 @@ struct symbol {
|
||||||
} assoc; /* Associativity if predecence is defined */
|
} assoc; /* Associativity if predecence is defined */
|
||||||
char *firstset; /* First-set for all rules of this symbol */
|
char *firstset; /* First-set for all rules of this symbol */
|
||||||
Boolean lambda; /* True if NT and can generate an empty string */
|
Boolean lambda; /* True if NT and can generate an empty string */
|
||||||
|
int useCnt; /* Number of times used */
|
||||||
char *destructor; /* Code which executes whenever this symbol is
|
char *destructor; /* Code which executes whenever this symbol is
|
||||||
** popped from the stack during error processing */
|
** popped from the stack during error processing */
|
||||||
int destructorln; /* Line number of destructor code */
|
int destructorln; /* Line number of destructor code */
|
||||||
|
@ -155,6 +155,7 @@ struct symbol {
|
||||||
struct rule {
|
struct rule {
|
||||||
struct symbol *lhs; /* Left-hand side of the rule */
|
struct symbol *lhs; /* Left-hand side of the rule */
|
||||||
char *lhsalias; /* Alias for the LHS (NULL if none) */
|
char *lhsalias; /* Alias for the LHS (NULL if none) */
|
||||||
|
int lhsStart; /* True if left-hand side is the start symbol */
|
||||||
int ruleline; /* Line number for the rule */
|
int ruleline; /* Line number for the rule */
|
||||||
int nrhs; /* Number of RHS symbols */
|
int nrhs; /* Number of RHS symbols */
|
||||||
struct symbol **rhs; /* The RHS symbols */
|
struct symbol **rhs; /* The RHS symbols */
|
||||||
|
@ -196,7 +197,9 @@ struct action {
|
||||||
ACCEPT,
|
ACCEPT,
|
||||||
REDUCE,
|
REDUCE,
|
||||||
ERROR,
|
ERROR,
|
||||||
CONFLICT, /* Was a reduce, but part of a conflict */
|
SSCONFLICT, /* A shift/shift conflict */
|
||||||
|
SRCONFLICT, /* Was a reduce, but part of a conflict */
|
||||||
|
RRCONFLICT, /* Was a reduce, but part of a conflict */
|
||||||
SH_RESOLVED, /* Was a shift. Precedence resolved conflict */
|
SH_RESOLVED, /* Was a shift. Precedence resolved conflict */
|
||||||
RD_RESOLVED, /* Was reduce. Precedence resolved conflict */
|
RD_RESOLVED, /* Was reduce. Precedence resolved conflict */
|
||||||
NOT_USED /* Deleted by compression */
|
NOT_USED /* Deleted by compression */
|
||||||
|
@ -335,14 +338,14 @@ void Configtable_clear(/* int(*)(struct config *) */);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Allocate a new parser action */
|
/* Allocate a new parser action */
|
||||||
struct action *Action_new(){
|
static struct action *Action_new(void){
|
||||||
static struct action *freelist = 0;
|
static struct action *freelist = 0;
|
||||||
struct action *new;
|
struct action *new;
|
||||||
|
|
||||||
if( freelist==0 ){
|
if( freelist==0 ){
|
||||||
int i;
|
int i;
|
||||||
int amt = 100;
|
int amt = 100;
|
||||||
freelist = (struct action *)malloc( sizeof(struct action)*amt );
|
freelist = (struct action *)calloc(amt, sizeof(struct action));
|
||||||
if( freelist==0 ){
|
if( freelist==0 ){
|
||||||
fprintf(stderr,"Unable to allocate memory for a new parser action.");
|
fprintf(stderr,"Unable to allocate memory for a new parser action.");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -355,23 +358,27 @@ struct action *Action_new(){
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare two actions */
|
/* Compare two actions for sorting purposes. Return negative, zero, or
|
||||||
|
** positive if the first action is less than, equal to, or greater than
|
||||||
|
** the first
|
||||||
|
*/
|
||||||
static int actioncmp(ap1,ap2)
|
static int actioncmp(ap1,ap2)
|
||||||
struct action *ap1;
|
struct action *ap1;
|
||||||
struct action *ap2;
|
struct action *ap2;
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
rc = ap1->sp->index - ap2->sp->index;
|
rc = ap1->sp->index - ap2->sp->index;
|
||||||
if( rc==0 ) rc = (int)ap1->type - (int)ap2->type;
|
|
||||||
if( rc==0 ){
|
if( rc==0 ){
|
||||||
|
rc = (int)ap1->type - (int)ap2->type;
|
||||||
|
}
|
||||||
|
if( rc==0 && ap1->type==REDUCE ){
|
||||||
rc = ap1->x.rp->index - ap2->x.rp->index;
|
rc = ap1->x.rp->index - ap2->x.rp->index;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sort parser actions */
|
/* Sort parser actions */
|
||||||
struct action *Action_sort(ap)
|
static struct action *Action_sort(struct action *ap)
|
||||||
struct action *ap;
|
|
||||||
{
|
{
|
||||||
ap = (struct action *)msort(ap,&ap->next,actioncmp);
|
ap = (struct action *)msort(ap,&ap->next,actioncmp);
|
||||||
return ap;
|
return ap;
|
||||||
|
@ -438,7 +445,7 @@ void acttab_free(acttab *p){
|
||||||
|
|
||||||
/* Allocate a new acttab structure */
|
/* Allocate a new acttab structure */
|
||||||
acttab *acttab_alloc(void){
|
acttab *acttab_alloc(void){
|
||||||
acttab *p = malloc( sizeof(*p) );
|
acttab *p = calloc( 1, sizeof(*p) );
|
||||||
if( p==0 ){
|
if( p==0 ){
|
||||||
fprintf(stderr,"Unable to allocate memory for a new acttab.");
|
fprintf(stderr,"Unable to allocate memory for a new acttab.");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -559,17 +566,6 @@ int acttab_insert(acttab *p){
|
||||||
return i - p->mnLookahead;
|
return i - p->mnLookahead;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************** From the file "assert.c" ****************************/
|
|
||||||
/*
|
|
||||||
** A more efficient way of handling assertions.
|
|
||||||
*/
|
|
||||||
void myassert(file,line)
|
|
||||||
char *file;
|
|
||||||
int line;
|
|
||||||
{
|
|
||||||
fprintf(stderr,"Assertion failed on line %d of file \"%s\"\n",line,file);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
/********************** From the file "build.c" *****************************/
|
/********************** From the file "build.c" *****************************/
|
||||||
/*
|
/*
|
||||||
** Routines to construction the finite state machine for the LEMON
|
** Routines to construction the finite state machine for the LEMON
|
||||||
|
@ -623,7 +619,7 @@ struct lemon *lemp;
|
||||||
int progress;
|
int progress;
|
||||||
|
|
||||||
for(i=0; i<lemp->nsymbol; i++){
|
for(i=0; i<lemp->nsymbol; i++){
|
||||||
lemp->symbols[i]->lambda = B_FALSE;
|
lemp->symbols[i]->lambda = LEMON_FALSE;
|
||||||
}
|
}
|
||||||
for(i=lemp->nterminal; i<lemp->nsymbol; i++){
|
for(i=lemp->nterminal; i<lemp->nsymbol; i++){
|
||||||
lemp->symbols[i]->firstset = SetNew();
|
lemp->symbols[i]->firstset = SetNew();
|
||||||
|
@ -636,10 +632,10 @@ struct lemon *lemp;
|
||||||
if( rp->lhs->lambda ) continue;
|
if( rp->lhs->lambda ) continue;
|
||||||
for(i=0; i<rp->nrhs; i++){
|
for(i=0; i<rp->nrhs; i++){
|
||||||
struct symbol *sp = rp->rhs[i];
|
struct symbol *sp = rp->rhs[i];
|
||||||
if( sp->type!=TERMINAL || sp->lambda==B_FALSE ) break;
|
if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break;
|
||||||
}
|
}
|
||||||
if( i==rp->nrhs ){
|
if( i==rp->nrhs ){
|
||||||
rp->lhs->lambda = B_TRUE;
|
rp->lhs->lambda = LEMON_TRUE;
|
||||||
progress = 1;
|
progress = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -662,10 +658,10 @@ struct lemon *lemp;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}else if( s1==s2 ){
|
}else if( s1==s2 ){
|
||||||
if( s1->lambda==B_FALSE ) break;
|
if( s1->lambda==LEMON_FALSE ) break;
|
||||||
}else{
|
}else{
|
||||||
progress += SetUnion(s1->firstset,s2->firstset);
|
progress += SetUnion(s1->firstset,s2->firstset);
|
||||||
if( s2->lambda==B_FALSE ) break;
|
if( s2->lambda==LEMON_FALSE ) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -722,6 +718,7 @@ does not work properly.",sp->name);
|
||||||
** left-hand side */
|
** left-hand side */
|
||||||
for(rp=sp->rule; rp; rp=rp->nextlhs){
|
for(rp=sp->rule; rp; rp=rp->nextlhs){
|
||||||
struct config *newcfp;
|
struct config *newcfp;
|
||||||
|
rp->lhsStart = 1;
|
||||||
newcfp = Configlist_addbasis(rp,0);
|
newcfp = Configlist_addbasis(rp,0);
|
||||||
SetAdd(newcfp->fws,0);
|
SetAdd(newcfp->fws,0);
|
||||||
}
|
}
|
||||||
|
@ -973,7 +970,7 @@ struct lemon *lemp;
|
||||||
struct action *ap, *nap;
|
struct action *ap, *nap;
|
||||||
struct state *stp;
|
struct state *stp;
|
||||||
stp = lemp->sorted[i];
|
stp = lemp->sorted[i];
|
||||||
assert( stp->ap );
|
/* assert( stp->ap ); */
|
||||||
stp->ap = Action_sort(stp->ap);
|
stp->ap = Action_sort(stp->ap);
|
||||||
for(ap=stp->ap; ap && ap->next; ap=ap->next){
|
for(ap=stp->ap; ap && ap->next; ap=ap->next){
|
||||||
for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){
|
for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){
|
||||||
|
@ -985,11 +982,11 @@ struct lemon *lemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Report an error for each rule that can never be reduced. */
|
/* Report an error for each rule that can never be reduced. */
|
||||||
for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = B_FALSE;
|
for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE;
|
||||||
for(i=0; i<lemp->nstate; i++){
|
for(i=0; i<lemp->nstate; i++){
|
||||||
struct action *ap;
|
struct action *ap;
|
||||||
for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
|
for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
|
||||||
if( ap->type==REDUCE ) ap->x.rp->canReduce = B_TRUE;
|
if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(rp=lemp->rule; rp; rp=rp->next){
|
for(rp=lemp->rule; rp; rp=rp->next){
|
||||||
|
@ -1021,7 +1018,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
|
||||||
int errcnt = 0;
|
int errcnt = 0;
|
||||||
assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */
|
assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */
|
||||||
if( apx->type==SHIFT && apy->type==SHIFT ){
|
if( apx->type==SHIFT && apy->type==SHIFT ){
|
||||||
apy->type = CONFLICT;
|
apy->type = SSCONFLICT;
|
||||||
errcnt++;
|
errcnt++;
|
||||||
}
|
}
|
||||||
if( apx->type==SHIFT && apy->type==REDUCE ){
|
if( apx->type==SHIFT && apy->type==REDUCE ){
|
||||||
|
@ -1029,7 +1026,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
|
||||||
spy = apy->x.rp->precsym;
|
spy = apy->x.rp->precsym;
|
||||||
if( spy==0 || spx->prec<0 || spy->prec<0 ){
|
if( spy==0 || spx->prec<0 || spy->prec<0 ){
|
||||||
/* Not enough precedence information. */
|
/* Not enough precedence information. */
|
||||||
apy->type = CONFLICT;
|
apy->type = SRCONFLICT;
|
||||||
errcnt++;
|
errcnt++;
|
||||||
}else if( spx->prec>spy->prec ){ /* Lower precedence wins */
|
}else if( spx->prec>spy->prec ){ /* Lower precedence wins */
|
||||||
apy->type = RD_RESOLVED;
|
apy->type = RD_RESOLVED;
|
||||||
|
@ -1041,7 +1038,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
|
||||||
apx->type = SH_RESOLVED;
|
apx->type = SH_RESOLVED;
|
||||||
}else{
|
}else{
|
||||||
assert( spx->prec==spy->prec && spx->assoc==NONE );
|
assert( spx->prec==spy->prec && spx->assoc==NONE );
|
||||||
apy->type = CONFLICT;
|
apy->type = SRCONFLICT;
|
||||||
errcnt++;
|
errcnt++;
|
||||||
}
|
}
|
||||||
}else if( apx->type==REDUCE && apy->type==REDUCE ){
|
}else if( apx->type==REDUCE && apy->type==REDUCE ){
|
||||||
|
@ -1049,7 +1046,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
|
||||||
spy = apy->x.rp->precsym;
|
spy = apy->x.rp->precsym;
|
||||||
if( spx==0 || spy==0 || spx->prec<0 ||
|
if( spx==0 || spy==0 || spx->prec<0 ||
|
||||||
spy->prec<0 || spx->prec==spy->prec ){
|
spy->prec<0 || spx->prec==spy->prec ){
|
||||||
apy->type = CONFLICT;
|
apy->type = RRCONFLICT;
|
||||||
errcnt++;
|
errcnt++;
|
||||||
}else if( spx->prec>spy->prec ){
|
}else if( spx->prec>spy->prec ){
|
||||||
apy->type = RD_RESOLVED;
|
apy->type = RD_RESOLVED;
|
||||||
|
@ -1060,10 +1057,14 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
|
||||||
assert(
|
assert(
|
||||||
apx->type==SH_RESOLVED ||
|
apx->type==SH_RESOLVED ||
|
||||||
apx->type==RD_RESOLVED ||
|
apx->type==RD_RESOLVED ||
|
||||||
apx->type==CONFLICT ||
|
apx->type==SSCONFLICT ||
|
||||||
|
apx->type==SRCONFLICT ||
|
||||||
|
apx->type==RRCONFLICT ||
|
||||||
apy->type==SH_RESOLVED ||
|
apy->type==SH_RESOLVED ||
|
||||||
apy->type==RD_RESOLVED ||
|
apy->type==RD_RESOLVED ||
|
||||||
apy->type==CONFLICT
|
apy->type==SSCONFLICT ||
|
||||||
|
apy->type==SRCONFLICT ||
|
||||||
|
apy->type==RRCONFLICT
|
||||||
);
|
);
|
||||||
/* The REDUCE/SHIFT case cannot happen because SHIFTs come before
|
/* The REDUCE/SHIFT case cannot happen because SHIFTs come before
|
||||||
** REDUCEs on the list. If we reach this point it must be because
|
** REDUCEs on the list. If we reach this point it must be because
|
||||||
|
@ -1089,7 +1090,7 @@ PRIVATE struct config *newconfig(){
|
||||||
if( freelist==0 ){
|
if( freelist==0 ){
|
||||||
int i;
|
int i;
|
||||||
int amt = 3;
|
int amt = 3;
|
||||||
freelist = (struct config *)malloc( sizeof(struct config)*amt );
|
freelist = (struct config *)calloc( amt, sizeof(struct config) );
|
||||||
if( freelist==0 ){
|
if( freelist==0 ){
|
||||||
fprintf(stderr,"Unable to allocate memory for a new configuration.");
|
fprintf(stderr,"Unable to allocate memory for a new configuration.");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -1223,7 +1224,7 @@ struct lemon *lemp;
|
||||||
break;
|
break;
|
||||||
}else{
|
}else{
|
||||||
SetUnion(newcfp->fws,xsp->firstset);
|
SetUnion(newcfp->fws,xsp->firstset);
|
||||||
if( xsp->lambda==B_FALSE ) break;
|
if( xsp->lambda==LEMON_FALSE ) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
|
if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
|
||||||
|
@ -1452,6 +1453,7 @@ char **argv;
|
||||||
lem.basisflag = basisflag;
|
lem.basisflag = basisflag;
|
||||||
Symbol_new("$");
|
Symbol_new("$");
|
||||||
lem.errsym = Symbol_new("error");
|
lem.errsym = Symbol_new("error");
|
||||||
|
lem.errsym->useCnt = 0;
|
||||||
|
|
||||||
/* Parse the input file */
|
/* Parse the input file */
|
||||||
Parse(&lem);
|
Parse(&lem);
|
||||||
|
@ -1477,7 +1479,7 @@ char **argv;
|
||||||
Reprint(&lem);
|
Reprint(&lem);
|
||||||
}else{
|
}else{
|
||||||
/* Initialize the size for all follow and first sets */
|
/* Initialize the size for all follow and first sets */
|
||||||
SetSize(lem.nterminal);
|
SetSize(lem.nterminal+1);
|
||||||
|
|
||||||
/* Find the precedence for every production rule (that has one) */
|
/* Find the precedence for every production rule (that has one) */
|
||||||
FindRulePrecedences(&lem);
|
FindRulePrecedences(&lem);
|
||||||
|
@ -1623,7 +1625,7 @@ static void *merge(void *a,void *b,int (*cmp)(),size_t offset)
|
||||||
** The "next" pointers for elements in list are changed.
|
** The "next" pointers for elements in list are changed.
|
||||||
*/
|
*/
|
||||||
#define LISTSIZE 30
|
#define LISTSIZE 30
|
||||||
void *msort(void *list,void *next,int (*cmp)())
|
static void *msort(void *list,void *next,int (*cmp)())
|
||||||
{
|
{
|
||||||
size_t offset;
|
size_t offset;
|
||||||
char *ep;
|
char *ep;
|
||||||
|
@ -2108,8 +2110,8 @@ to follow the previous rule.");
|
||||||
case IN_RHS:
|
case IN_RHS:
|
||||||
if( x[0]=='.' ){
|
if( x[0]=='.' ){
|
||||||
struct rule *rp;
|
struct rule *rp;
|
||||||
rp = (struct rule *)malloc( sizeof(struct rule) +
|
rp = (struct rule *)calloc( sizeof(struct rule) +
|
||||||
sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs );
|
sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1);
|
||||||
if( rp==0 ){
|
if( rp==0 ){
|
||||||
ErrorMsg(psp->filename,psp->tokenlineno,
|
ErrorMsg(psp->filename,psp->tokenlineno,
|
||||||
"Can't allocate enough memory for this rule.");
|
"Can't allocate enough memory for this rule.");
|
||||||
|
@ -2145,7 +2147,7 @@ to follow the previous rule.");
|
||||||
}else if( isalpha(x[0]) ){
|
}else if( isalpha(x[0]) ){
|
||||||
if( psp->nrhs>=MAXRHS ){
|
if( psp->nrhs>=MAXRHS ){
|
||||||
ErrorMsg(psp->filename,psp->tokenlineno,
|
ErrorMsg(psp->filename,psp->tokenlineno,
|
||||||
"Too many symbols on RHS or rule beginning at \"%s\".",
|
"Too many symbols on RHS of rule beginning at \"%s\".",
|
||||||
x);
|
x);
|
||||||
psp->errorcnt++;
|
psp->errorcnt++;
|
||||||
psp->state = RESYNC_AFTER_RULE_ERROR;
|
psp->state = RESYNC_AFTER_RULE_ERROR;
|
||||||
|
@ -2158,11 +2160,10 @@ to follow the previous rule.");
|
||||||
struct symbol *msp = psp->rhs[psp->nrhs-1];
|
struct symbol *msp = psp->rhs[psp->nrhs-1];
|
||||||
if( msp->type!=MULTITERMINAL ){
|
if( msp->type!=MULTITERMINAL ){
|
||||||
struct symbol *origsp = msp;
|
struct symbol *origsp = msp;
|
||||||
msp = malloc(sizeof(*msp));
|
msp = calloc(1,sizeof(*msp));
|
||||||
memset(msp, 0, sizeof(*msp));
|
|
||||||
msp->type = MULTITERMINAL;
|
msp->type = MULTITERMINAL;
|
||||||
msp->nsubsym = 1;
|
msp->nsubsym = 1;
|
||||||
msp->subsym = malloc(sizeof(struct symbol*));
|
msp->subsym = calloc(1,sizeof(struct symbol*));
|
||||||
msp->subsym[0] = origsp;
|
msp->subsym[0] = origsp;
|
||||||
msp->name = origsp->name;
|
msp->name = origsp->name;
|
||||||
psp->rhs[psp->nrhs-1] = msp;
|
psp->rhs[psp->nrhs-1] = msp;
|
||||||
|
@ -2407,7 +2408,7 @@ to follow the previous rule.");
|
||||||
static void preprocess_input(char *z){
|
static void preprocess_input(char *z){
|
||||||
int i, j, k, n;
|
int i, j, k, n;
|
||||||
int exclude = 0;
|
int exclude = 0;
|
||||||
int start = 1;
|
int start = 0;
|
||||||
int lineno = 1;
|
int lineno = 1;
|
||||||
int start_lineno = 1;
|
int start_lineno = 1;
|
||||||
for(i=0; z[i]; i++){
|
for(i=0; z[i]; i++){
|
||||||
|
@ -2484,7 +2485,7 @@ struct lemon *gp;
|
||||||
char *cp, *nextcp;
|
char *cp, *nextcp;
|
||||||
int startline = 0;
|
int startline = 0;
|
||||||
|
|
||||||
memset(&ps, 0, sizeof ps);
|
memset(&ps, '\0', sizeof(ps));
|
||||||
ps.gp = gp;
|
ps.gp = gp;
|
||||||
ps.filename = gp->filename;
|
ps.filename = gp->filename;
|
||||||
ps.errorcnt = 0;
|
ps.errorcnt = 0;
|
||||||
|
@ -2633,7 +2634,7 @@ struct plink *Plink_new(){
|
||||||
if( plink_freelist==0 ){
|
if( plink_freelist==0 ){
|
||||||
int i;
|
int i;
|
||||||
int amt = 100;
|
int amt = 100;
|
||||||
plink_freelist = (struct plink *)malloc( sizeof(struct plink)*amt );
|
plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) );
|
||||||
if( plink_freelist==0 ){
|
if( plink_freelist==0 ){
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Unable to allocate memory for a new follow-set propagation link.\n");
|
"Unable to allocate memory for a new follow-set propagation link.\n");
|
||||||
|
@ -2859,10 +2860,15 @@ int PrintAction(struct action *ap, FILE *fp, int indent){
|
||||||
case ERROR:
|
case ERROR:
|
||||||
fprintf(fp,"%*s error",indent,ap->sp->name);
|
fprintf(fp,"%*s error",indent,ap->sp->name);
|
||||||
break;
|
break;
|
||||||
case CONFLICT:
|
case SRCONFLICT:
|
||||||
|
case RRCONFLICT:
|
||||||
fprintf(fp,"%*s reduce %-3d ** Parsing conflict **",
|
fprintf(fp,"%*s reduce %-3d ** Parsing conflict **",
|
||||||
indent,ap->sp->name,ap->x.rp->index);
|
indent,ap->sp->name,ap->x.rp->index);
|
||||||
break;
|
break;
|
||||||
|
case SSCONFLICT:
|
||||||
|
fprintf(fp,"%*s shift %d ** Parsing conflict **",
|
||||||
|
indent,ap->sp->name,ap->x.stp->statenum);
|
||||||
|
break;
|
||||||
case SH_RESOLVED:
|
case SH_RESOLVED:
|
||||||
case RD_RESOLVED:
|
case RD_RESOLVED:
|
||||||
case NOT_USED:
|
case NOT_USED:
|
||||||
|
@ -2884,7 +2890,6 @@ struct lemon *lemp;
|
||||||
|
|
||||||
fp = file_open(lemp,".out","wb");
|
fp = file_open(lemp,".out","wb");
|
||||||
if( fp==0 ) return;
|
if( fp==0 ) return;
|
||||||
fprintf(fp," \b");
|
|
||||||
for(i=0; i<lemp->nstate; i++){
|
for(i=0; i<lemp->nstate; i++){
|
||||||
stp = lemp->sorted[i];
|
stp = lemp->sorted[i];
|
||||||
fprintf(fp,"State %d:\n",stp->statenum);
|
fprintf(fp,"State %d:\n",stp->statenum);
|
||||||
|
@ -2914,6 +2919,27 @@ struct lemon *lemp;
|
||||||
}
|
}
|
||||||
fprintf(fp,"\n");
|
fprintf(fp,"\n");
|
||||||
}
|
}
|
||||||
|
fprintf(fp, "----------------------------------------------------\n");
|
||||||
|
fprintf(fp, "Symbols:\n");
|
||||||
|
for(i=0; i<lemp->nsymbol; i++){
|
||||||
|
int j;
|
||||||
|
struct symbol *sp;
|
||||||
|
|
||||||
|
sp = lemp->symbols[i];
|
||||||
|
fprintf(fp, " %3d: %s", i, sp->name);
|
||||||
|
if( sp->type==NONTERMINAL ){
|
||||||
|
fprintf(fp, ":");
|
||||||
|
if( sp->lambda ){
|
||||||
|
fprintf(fp, " <lambda>");
|
||||||
|
}
|
||||||
|
for(j=0; j<lemp->nterminal; j++){
|
||||||
|
if( sp->firstset && SetFind(sp->firstset, j) ){
|
||||||
|
fprintf(fp, " %s", lemp->symbols[j]->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2928,7 +2954,6 @@ int modemask;
|
||||||
char *pathlist;
|
char *pathlist;
|
||||||
char *path,*cp;
|
char *path,*cp;
|
||||||
char c;
|
char c;
|
||||||
extern int access();
|
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
for (cp = argv0 + strlen(argv0); cp-- > argv0; )
|
for (cp = argv0 + strlen(argv0); cp-- > argv0; )
|
||||||
|
@ -3229,8 +3254,13 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
|
||||||
for(i=0; i<rp->nrhs; i++) used[i] = 0;
|
for(i=0; i<rp->nrhs; i++) used[i] = 0;
|
||||||
lhsused = 0;
|
lhsused = 0;
|
||||||
|
|
||||||
|
if( rp->code==0 ){
|
||||||
|
rp->code = "\n";
|
||||||
|
rp->line = rp->ruleline;
|
||||||
|
}
|
||||||
|
|
||||||
append_str(0,0,0,0,0);
|
append_str(0,0,0,0,0);
|
||||||
for(cp=(rp->code?rp->code:""); *cp; cp++){
|
for(cp=rp->code; *cp; cp++){
|
||||||
if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){
|
if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){
|
||||||
char saved;
|
char saved;
|
||||||
for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++);
|
for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++);
|
||||||
|
@ -3351,8 +3381,7 @@ int mhflag; /* True if generating makeheaders output */
|
||||||
|
|
||||||
/* Allocate and initialize types[] and allocate stddt[] */
|
/* Allocate and initialize types[] and allocate stddt[] */
|
||||||
arraysize = lemp->nsymbol * 2;
|
arraysize = lemp->nsymbol * 2;
|
||||||
types = (char**)malloc( arraysize * sizeof(char*) );
|
types = (char**)calloc( arraysize, sizeof(char*) );
|
||||||
for(i=0; i<arraysize; i++) types[i] = 0;
|
|
||||||
maxdtlength = 0;
|
maxdtlength = 0;
|
||||||
if( lemp->vartype ){
|
if( lemp->vartype ){
|
||||||
maxdtlength = (int)strlen(lemp->vartype);
|
maxdtlength = (int)strlen(lemp->vartype);
|
||||||
|
@ -3432,7 +3461,9 @@ int mhflag; /* True if generating makeheaders output */
|
||||||
fprintf(out," %s yy%d;\n",types[i],i+1); lineno++;
|
fprintf(out," %s yy%d;\n",types[i],i+1); lineno++;
|
||||||
free(types[i]);
|
free(types[i]);
|
||||||
}
|
}
|
||||||
fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++;
|
if( lemp->errsym->useCnt ){
|
||||||
|
fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++;
|
||||||
|
}
|
||||||
free(stddt);
|
free(stddt);
|
||||||
free(types);
|
free(types);
|
||||||
fprintf(out,"} YYMINORTYPE;\n"); lineno++;
|
fprintf(out,"} YYMINORTYPE;\n"); lineno++;
|
||||||
|
@ -3482,6 +3513,25 @@ static int axset_compare(const void *a, const void *b){
|
||||||
return p2->nAction - p1->nAction;
|
return p2->nAction - p1->nAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Write text on "out" that describes the rule "rp".
|
||||||
|
*/
|
||||||
|
static void writeRuleText(FILE *out, struct rule *rp){
|
||||||
|
int j;
|
||||||
|
fprintf(out,"%s ::=", rp->lhs->name);
|
||||||
|
for(j=0; j<rp->nrhs; j++){
|
||||||
|
struct symbol *sp = rp->rhs[j];
|
||||||
|
fprintf(out," %s", sp->name);
|
||||||
|
if( sp->type==MULTITERMINAL ){
|
||||||
|
int k;
|
||||||
|
for(k=1; k<sp->nsubsym; k++){
|
||||||
|
fprintf(out,"|%s",sp->subsym[k]->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Generate C source code for the parser */
|
/* Generate C source code for the parser */
|
||||||
void ReportTable(lemp, mhflag)
|
void ReportTable(lemp, mhflag)
|
||||||
struct lemon *lemp;
|
struct lemon *lemp;
|
||||||
|
@ -3544,18 +3594,13 @@ int mhflag; /* Output in makeheaders format if true */
|
||||||
lemp->wildcard->index); lineno++;
|
lemp->wildcard->index); lineno++;
|
||||||
}
|
}
|
||||||
print_stack_union(out,lemp,&lineno,mhflag);
|
print_stack_union(out,lemp,&lineno,mhflag);
|
||||||
|
fprintf(out, "#ifndef YYSTACKDEPTH\n"); lineno++;
|
||||||
if( lemp->stacksize ){
|
if( lemp->stacksize ){
|
||||||
if( atoi(lemp->stacksize)<=0 ){
|
|
||||||
ErrorMsg(lemp->filename,0,
|
|
||||||
"Illegal stack size: [%s]. The stack size should be an integer constant.",
|
|
||||||
lemp->stacksize);
|
|
||||||
lemp->errorcnt++;
|
|
||||||
lemp->stacksize = "100";
|
|
||||||
}
|
|
||||||
fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++;
|
fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++;
|
||||||
}else{
|
}else{
|
||||||
fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++;
|
fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++;
|
||||||
}
|
}
|
||||||
|
fprintf(out, "#endif\n"); lineno++;
|
||||||
if( mhflag ){
|
if( mhflag ){
|
||||||
fprintf(out,"#if INTERFACE\n"); lineno++;
|
fprintf(out,"#if INTERFACE\n"); lineno++;
|
||||||
}
|
}
|
||||||
|
@ -3582,8 +3627,10 @@ int mhflag; /* Output in makeheaders format if true */
|
||||||
}
|
}
|
||||||
fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++;
|
fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++;
|
||||||
fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++;
|
fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++;
|
||||||
fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
|
if( lemp->errsym->useCnt ){
|
||||||
fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++;
|
fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
|
||||||
|
fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++;
|
||||||
|
}
|
||||||
if( lemp->has_fallback ){
|
if( lemp->has_fallback ){
|
||||||
fprintf(out,"#define YYFALLBACK 1\n"); lineno++;
|
fprintf(out,"#define YYFALLBACK 1\n"); lineno++;
|
||||||
}
|
}
|
||||||
|
@ -3602,7 +3649,7 @@ int mhflag; /* Output in makeheaders format if true */
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Compute the actions on all states and count them up */
|
/* Compute the actions on all states and count them up */
|
||||||
ax = malloc( sizeof(ax[0])*lemp->nstate*2 );
|
ax = calloc(lemp->nstate*2 , sizeof(ax[0]));
|
||||||
if( ax==0 ){
|
if( ax==0 ){
|
||||||
fprintf(stderr,"malloc failed\n");
|
fprintf(stderr,"malloc failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -3782,17 +3829,8 @@ int mhflag; /* Output in makeheaders format if true */
|
||||||
*/
|
*/
|
||||||
for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
|
for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
|
||||||
assert( rp->index==i );
|
assert( rp->index==i );
|
||||||
fprintf(out," /* %3d */ \"%s ::=", i, rp->lhs->name);
|
fprintf(out," /* %3d */ \"", i);
|
||||||
for(j=0; j<rp->nrhs; j++){
|
writeRuleText(out, rp);
|
||||||
struct symbol *sp = rp->rhs[j];
|
|
||||||
fprintf(out," %s", sp->name);
|
|
||||||
if( sp->type==MULTITERMINAL ){
|
|
||||||
int k;
|
|
||||||
for(k=1; k<sp->nsubsym; k++){
|
|
||||||
fprintf(out,"|%s",sp->subsym[k]->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(out,"\",\n"); lineno++;
|
fprintf(out,"\",\n"); lineno++;
|
||||||
}
|
}
|
||||||
tplt_xfer(lemp->name,in,out,&lineno);
|
tplt_xfer(lemp->name,in,out,&lineno);
|
||||||
|
@ -3805,7 +3843,8 @@ int mhflag; /* Output in makeheaders format if true */
|
||||||
for(i=0; i<lemp->nsymbol; i++){
|
for(i=0; i<lemp->nsymbol; i++){
|
||||||
struct symbol *sp = lemp->symbols[i];
|
struct symbol *sp = lemp->symbols[i];
|
||||||
if( sp==0 || sp->type!=TERMINAL ) continue;
|
if( sp==0 || sp->type!=TERMINAL ) continue;
|
||||||
fprintf(out," case %d:\n",sp->index); lineno++;
|
fprintf(out," case %d: /* %s */\n",
|
||||||
|
sp->index, sp->name); lineno++;
|
||||||
}
|
}
|
||||||
for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++);
|
for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++);
|
||||||
if( i<lemp->nsymbol ){
|
if( i<lemp->nsymbol ){
|
||||||
|
@ -3819,7 +3858,8 @@ int mhflag; /* Output in makeheaders format if true */
|
||||||
struct symbol *sp = lemp->symbols[i];
|
struct symbol *sp = lemp->symbols[i];
|
||||||
if( sp==0 || sp->type==TERMINAL ||
|
if( sp==0 || sp->type==TERMINAL ||
|
||||||
sp->index<=0 || sp->destructor!=0 ) continue;
|
sp->index<=0 || sp->destructor!=0 ) continue;
|
||||||
fprintf(out," case %d:\n",sp->index); lineno++;
|
fprintf(out," case %d: /* %s */\n",
|
||||||
|
sp->index, sp->name); lineno++;
|
||||||
dflt_sp = sp;
|
dflt_sp = sp;
|
||||||
}
|
}
|
||||||
if( dflt_sp!=0 ){
|
if( dflt_sp!=0 ){
|
||||||
|
@ -3830,7 +3870,8 @@ int mhflag; /* Output in makeheaders format if true */
|
||||||
for(i=0; i<lemp->nsymbol; i++){
|
for(i=0; i<lemp->nsymbol; i++){
|
||||||
struct symbol *sp = lemp->symbols[i];
|
struct symbol *sp = lemp->symbols[i];
|
||||||
if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue;
|
if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue;
|
||||||
fprintf(out," case %d:\n",sp->index); lineno++;
|
fprintf(out," case %d: /* %s */\n",
|
||||||
|
sp->index, sp->name); lineno++;
|
||||||
|
|
||||||
/* Combine duplicate destructors into a single case */
|
/* Combine duplicate destructors into a single case */
|
||||||
for(j=i+1; j<lemp->nsymbol; j++){
|
for(j=i+1; j<lemp->nsymbol; j++){
|
||||||
|
@ -3838,7 +3879,8 @@ int mhflag; /* Output in makeheaders format if true */
|
||||||
if( sp2 && sp2->type!=TERMINAL && sp2->destructor
|
if( sp2 && sp2->type!=TERMINAL && sp2->destructor
|
||||||
&& sp2->dtnum==sp->dtnum
|
&& sp2->dtnum==sp->dtnum
|
||||||
&& strcmp(sp->destructor,sp2->destructor)==0 ){
|
&& strcmp(sp->destructor,sp2->destructor)==0 ){
|
||||||
fprintf(out," case %d:\n",sp2->index); lineno++;
|
fprintf(out," case %d: /* %s */\n",
|
||||||
|
sp2->index, sp2->name); lineno++;
|
||||||
sp2->destructor = 0;
|
sp2->destructor = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3869,10 +3911,14 @@ int mhflag; /* Output in makeheaders format if true */
|
||||||
for(rp=lemp->rule; rp; rp=rp->next){
|
for(rp=lemp->rule; rp; rp=rp->next){
|
||||||
struct rule *rp2;
|
struct rule *rp2;
|
||||||
if( rp->code==0 ) continue;
|
if( rp->code==0 ) continue;
|
||||||
fprintf(out," case %d:\n",rp->index); lineno++;
|
fprintf(out," case %d: /* ",rp->index);
|
||||||
|
writeRuleText(out, rp);
|
||||||
|
fprintf(out, " */\n"); lineno++;
|
||||||
for(rp2=rp->next; rp2; rp2=rp2->next){
|
for(rp2=rp->next; rp2; rp2=rp2->next){
|
||||||
if( rp2->code==rp->code ){
|
if( rp2->code==rp->code ){
|
||||||
fprintf(out," case %d:\n",rp2->index); lineno++;
|
fprintf(out," case %d: /*",rp2->index);
|
||||||
|
writeRuleText(out, rp2);
|
||||||
|
fprintf(out," */\n"); lineno++;
|
||||||
rp2->code = 0;
|
rp2->code = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3964,6 +4010,7 @@ struct lemon *lemp;
|
||||||
}
|
}
|
||||||
if( ap->type!=REDUCE ) continue;
|
if( ap->type!=REDUCE ) continue;
|
||||||
rp = ap->x.rp;
|
rp = ap->x.rp;
|
||||||
|
if( rp->lhsStart ) continue;
|
||||||
if( rp==rbest ) continue;
|
if( rp==rbest ) continue;
|
||||||
n = 1;
|
n = 1;
|
||||||
for(ap2=ap->next; ap2; ap2=ap2->next){
|
for(ap2=ap->next; ap2; ap2=ap2->next){
|
||||||
|
@ -4072,13 +4119,11 @@ int n;
|
||||||
/* Allocate a new set */
|
/* Allocate a new set */
|
||||||
char *SetNew(){
|
char *SetNew(){
|
||||||
char *s;
|
char *s;
|
||||||
int i;
|
s = (char*)calloc( size, 1);
|
||||||
s = (char*)malloc( size );
|
|
||||||
if( s==0 ){
|
if( s==0 ){
|
||||||
extern void memory_error();
|
extern void memory_error();
|
||||||
memory_error();
|
memory_error();
|
||||||
}
|
}
|
||||||
for(i=0; i<size; i++) s[i] = 0;
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4096,6 +4141,7 @@ char *s;
|
||||||
int e;
|
int e;
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
assert( e>=0 && e<size );
|
||||||
rv = s[e];
|
rv = s[e];
|
||||||
s[e] = 1;
|
s[e] = 1;
|
||||||
return !rv;
|
return !rv;
|
||||||
|
@ -4285,7 +4331,7 @@ char *x;
|
||||||
|
|
||||||
sp = Symbol_find(x);
|
sp = Symbol_find(x);
|
||||||
if( sp==0 ){
|
if( sp==0 ){
|
||||||
sp = (struct symbol *)malloc( sizeof(struct symbol) );
|
sp = (struct symbol *)calloc(1, sizeof(struct symbol) );
|
||||||
MemoryCheck(sp);
|
MemoryCheck(sp);
|
||||||
sp->name = Strsafe(x);
|
sp->name = Strsafe(x);
|
||||||
sp->type = isupper(*x) ? TERMINAL : NONTERMINAL;
|
sp->type = isupper(*x) ? TERMINAL : NONTERMINAL;
|
||||||
|
@ -4294,11 +4340,13 @@ char *x;
|
||||||
sp->prec = -1;
|
sp->prec = -1;
|
||||||
sp->assoc = UNK;
|
sp->assoc = UNK;
|
||||||
sp->firstset = 0;
|
sp->firstset = 0;
|
||||||
sp->lambda = B_FALSE;
|
sp->lambda = LEMON_FALSE;
|
||||||
sp->destructor = 0;
|
sp->destructor = 0;
|
||||||
sp->datatype = 0;
|
sp->datatype = 0;
|
||||||
|
sp->useCnt = 0;
|
||||||
Symbol_insert(sp,sp->name);
|
Symbol_insert(sp,sp->name);
|
||||||
}
|
}
|
||||||
|
sp->useCnt++;
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4468,7 +4516,7 @@ struct symbol **Symbol_arrayof()
|
||||||
int i,size;
|
int i,size;
|
||||||
if( x2a==0 ) return 0;
|
if( x2a==0 ) return 0;
|
||||||
size = x2a->count;
|
size = x2a->count;
|
||||||
array = (struct symbol **)malloc( sizeof(struct symbol *)*size );
|
array = (struct symbol **)calloc(size, sizeof(struct symbol *));
|
||||||
if( array ){
|
if( array ){
|
||||||
for(i=0; i<size; i++) array[i] = x2a->tbl[i].data;
|
for(i=0; i<size; i++) array[i] = x2a->tbl[i].data;
|
||||||
}
|
}
|
||||||
|
@ -4519,7 +4567,7 @@ struct config *a;
|
||||||
struct state *State_new()
|
struct state *State_new()
|
||||||
{
|
{
|
||||||
struct state *new;
|
struct state *new;
|
||||||
new = (struct state *)malloc( sizeof(struct state) );
|
new = (struct state *)calloc(1, sizeof(struct state) );
|
||||||
MemoryCheck(new);
|
MemoryCheck(new);
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
1555
tools/lemon/lempar.c
1555
tools/lemon/lempar.c
File diff suppressed because it is too large
Load diff
|
@ -1,3 +1,57 @@
|
||||||
|
Version 0.12.3 (2007-08-24)
|
||||||
|
---------------------------
|
||||||
|
- Fixed issue with some compilers.
|
||||||
|
- Fixed #1776177 Build on AIX.
|
||||||
|
- Fixed #1743180 fwrite with 0 length crashes on OS X.
|
||||||
|
|
||||||
|
Version 0.12.2 (2007-06-26)
|
||||||
|
---------------------------
|
||||||
|
- Fixed #1743180 fwrite with 0 length crashes on OS X.
|
||||||
|
|
||||||
|
Version 0.12.1 (2007-05-23)
|
||||||
|
---------------------------
|
||||||
|
- Fixed #1711240 problem with '"' and 7F on EBCDIC plattforms.
|
||||||
|
|
||||||
|
Version 0.12.0 (2007-05-01)
|
||||||
|
---------------------------
|
||||||
|
- Re-release of 0.11.3 as new stable branch.
|
||||||
|
- Fixed issue with short form of switches and parameter if not first switch.
|
||||||
|
- Fixed #1708378 segfault in actions.cc.
|
||||||
|
|
||||||
|
Version 0.11.3 (2007-04-01)
|
||||||
|
---------------------------
|
||||||
|
- Added support for underscores in named definitions.
|
||||||
|
- Added new option --no-generation-date.
|
||||||
|
- Fixed issue with long form of switches.
|
||||||
|
|
||||||
|
Version 0.11.2 (2007-03-01)
|
||||||
|
---------------------------
|
||||||
|
- Added inplace configuration 're2c:yyfill:parameter'.
|
||||||
|
- Added inplace configuration 're2c:yych:conversion'.
|
||||||
|
- Fixed -u switch code generation.
|
||||||
|
- Added ability to avoid defines and overwrite variable and label names.
|
||||||
|
|
||||||
|
Version 0.11.1 (2007-02-20)
|
||||||
|
---------------------------
|
||||||
|
- Applied #1647875 add const to yybm vector.
|
||||||
|
|
||||||
|
Version 0.11.0 (2007-01-01)
|
||||||
|
---------------------------
|
||||||
|
- Added -u switch to support unicode.
|
||||||
|
|
||||||
|
Version 0.10.8 (2007-04-01)
|
||||||
|
---------------------------
|
||||||
|
- Fixed issue with long form of switches.
|
||||||
|
|
||||||
|
Version 0.10.7 (2007-02-20)
|
||||||
|
---------------------------
|
||||||
|
- Applied #1647875 add const to yybm vector.
|
||||||
|
|
||||||
|
Version 0.10.6 (2006-08-05)
|
||||||
|
---------------------------
|
||||||
|
- Fixed #1529351 Segv bug on unterminated code blocks.
|
||||||
|
- Fixed #1528269 Invalid code generation.
|
||||||
|
|
||||||
Version 0.10.5 (2006-06-11)
|
Version 0.10.5 (2006-06-11)
|
||||||
---------------------------
|
---------------------------
|
||||||
- Fixed long form of -1 switch to --single-pass as noted in man page and help.
|
- Fixed long form of -1 switch to --single-pass as noted in man page and help.
|
||||||
|
@ -20,7 +74,7 @@ Version 0.10.2 (2006-05-01)
|
||||||
- Fixed -i switch.
|
- Fixed -i switch.
|
||||||
- Added configuration 'yyfill:enable' to allow suppression of YYFILL() blocks.
|
- Added configuration 'yyfill:enable' to allow suppression of YYFILL() blocks.
|
||||||
- Added tutorial like lessons to re2c.
|
- Added tutorial like lessons to re2c.
|
||||||
- Added /*!ignore!re2c */ to support documenting of re2c source.
|
- Added /*!ignore:re2c */ to support documenting of re2c source.
|
||||||
- Fixed issue with multiline re2c comments (/*!max:re2c ... */ and alike).
|
- Fixed issue with multiline re2c comments (/*!max:re2c ... */ and alike).
|
||||||
- Fixed generation of YYDEBUG() when using -d switch.
|
- Fixed generation of YYDEBUG() when using -d switch.
|
||||||
- Added /*!getstate:re2c */ which triggers generation of the YYGETSTATE() block.
|
- Added /*!getstate:re2c */ which triggers generation of the YYGETSTATE() block.
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
ifeq (Windows_NT,$(OS))
|
ifeq (Windows_NT,$(OS))
|
||||||
WIN=1
|
WIN=1
|
||||||
WINCMD=1
|
WINCMD=1
|
||||||
endif
|
endif
|
||||||
ifeq (msys,$(OSTYPE))
|
ifeq (msys,$(OSTYPE))
|
||||||
WIN=1
|
WIN=1
|
||||||
WINCMD=0
|
WINCMD=0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (1,$(WIN))
|
ifeq (1,$(WIN))
|
||||||
EXE = re2c.exe
|
EXE = re2c.exe
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
re2c Version 0.10.5
|
re2c Version 0.12.3
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Originally written by Peter Bumbulis (peter@csg.uwaterloo.ca)
|
Originally written by Peter Bumbulis (peter@csg.uwaterloo.ca)
|
||||||
|
@ -17,7 +17,7 @@ platforms in 32 bit and 64 bit mode:
|
||||||
- GCC 3.3 ... 4.1
|
- GCC 3.3 ... 4.1
|
||||||
- Microsoft VC 7, 7.1, 8
|
- Microsoft VC 7, 7.1, 8
|
||||||
- Intel 9.0
|
- Intel 9.0
|
||||||
- Sun C++ 5.8 (CXXFLAGS='-compat5 -library=stlport4')
|
- Sun C++ 5.8 (CXXFLAGS='-library=stlport4')
|
||||||
- MIPSpro Compilers: Version 7.4.4m
|
- MIPSpro Compilers: Version 7.4.4m
|
||||||
|
|
||||||
GCC 2.x and Microsoft VC 6 are not capable of compiling re2c.
|
GCC 2.x and Microsoft VC 6 are not capable of compiling re2c.
|
||||||
|
@ -41,7 +41,7 @@ re2c) you need the following steps:
|
||||||
Or you can create a rpm package and install it by the following commands:
|
Or you can create a rpm package and install it by the following commands:
|
||||||
./configure
|
./configure
|
||||||
make rpm
|
make rpm
|
||||||
rpm -Uhv <packagedir>/re2c-0.10.5-1.rpm
|
rpm -Uhv <packagedir>/re2c-0.12.3-1.rpm
|
||||||
|
|
||||||
If you want to build from CVS then the first thing you should do is
|
If you want to build from CVS then the first thing you should do is
|
||||||
regenerating all build files using the following command:
|
regenerating all build files using the following command:
|
||||||
|
@ -51,7 +51,7 @@ need to generate RPM packages for cvs builds use these commands:
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
./configure
|
./configure
|
||||||
./makerpm <release>
|
./makerpm <release>
|
||||||
rpm -Uhv <packagedir>/re2c-0.10.5-<release>.rpm
|
rpm -Uhv <packagedir>/re2c-0.12.3-<release>.rpm
|
||||||
|
|
||||||
Here <realease> should be a number like 1. And <packagedir> must equal
|
Here <realease> should be a number like 1. And <packagedir> must equal
|
||||||
the directory where the makerpm step has written the generated rpm to.
|
the directory where the makerpm step has written the generated rpm to.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: basics.h,v 1.6 2005/12/29 14:32:09 helly Exp $ */
|
/* $Id: basics.h 520 2006-05-25 13:31:06Z helly $ */
|
||||||
#ifndef _basics_h
|
#ifndef _basics_h
|
||||||
#define _basics_h
|
#define _basics_h
|
||||||
|
|
||||||
|
|
3298
tools/re2c/code.cc
3298
tools/re2c/code.cc
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: code.h,v 1.7 2006/01/21 15:51:02 helly Exp $ */
|
/* $Id: code.h 525 2006-05-25 13:32:49Z helly $ */
|
||||||
#ifndef _code_h
|
#ifndef _code_h
|
||||||
#define _code_h
|
#define _code_h
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: dfa.h,v 1.23 2006/05/14 13:38:26 helly Exp $ */
|
/* $Id: dfa.h 569 2006-06-05 22:14:00Z helly $ */
|
||||||
#ifndef _dfa_h
|
#ifndef _dfa_h
|
||||||
#define _dfa_h
|
#define _dfa_h
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: globals.h,v 1.31 2006/05/14 13:38:26 helly Exp $ */
|
/* $Id: globals.h 713 2007-04-29 15:33:47Z helly $ */
|
||||||
#ifndef _globals_h
|
#ifndef _globals_h
|
||||||
#define _globals_h
|
#define _globals_h
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: ins.h,v 1.7 2006/01/03 11:40:38 helly Exp $ */
|
/* $Id: ins.h 535 2006-05-25 13:36:14Z helly $ */
|
||||||
#ifndef _ins_h
|
#ifndef _ins_h
|
||||||
#define _ins_h
|
#define _ins_h
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: main.cc,v 1.53 2006/05/14 13:38:26 helly Exp $ */
|
/* $Id: main.cc 691 2007-04-22 15:07:39Z helly $ */
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
@ -139,7 +139,7 @@ static void usage()
|
||||||
" with -f and disables YYMAXFILL generation prior to last\n"
|
" with -f and disables YYMAXFILL generation prior to last\n"
|
||||||
" re2c block.\n"
|
" re2c block.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"--no-generation-date Suppress the date output in the generated output so that it\n"
|
"--no-generation-date Suppress date output in the generated output so that it\n"
|
||||||
" only shows the re2c version.\n"
|
" only shows the re2c version.\n"
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Author: Marcus Boerger <helly@users.sourceforge.net>
|
Author: Marcus Boerger <helly@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: mbo_getopt.cc,v 1.5 2006/04/17 19:28:47 helly Exp $ */
|
/* $Id: mbo_getopt.cc 698 2007-04-23 21:06:56Z helly $ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Author: Marcus Boerger <helly@users.sourceforge.net>
|
Author: Marcus Boerger <helly@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: mbo_getopt.h,v 1.5 2006/04/17 19:28:47 helly Exp $ */
|
/* $Id: mbo_getopt.h 539 2006-05-25 13:37:38Z helly $ */
|
||||||
|
|
||||||
/* Define structure for one recognized option (both single char and long name).
|
/* Define structure for one recognized option (both single char and long name).
|
||||||
* If short_open is '-' this is the last option.
|
* If short_open is '-' this is the last option.
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
#line 1 "./parser.y"
|
#line 1 "./parser.y"
|
||||||
|
|
||||||
|
|
||||||
/* $Id: parser.y,v 1.20 2006/04/16 15:15:46 helly Exp $ */
|
/* $Id: parser.y 674 2007-04-16 21:39:11Z helly $ */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: parser.h,v 1.10 2006/01/21 15:51:02 helly Exp $ */
|
/* $Id: parser.h 565 2006-06-05 22:07:13Z helly $ */
|
||||||
#ifndef _parser_h
|
#ifndef _parser_h
|
||||||
#define _parser_h
|
#define _parser_h
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
%{
|
%{
|
||||||
|
|
||||||
/* $Id: parser.y,v 1.20 2006/04/16 15:15:46 helly Exp $ */
|
/* $Id: parser.y 674 2007-04-16 21:39:11Z helly $ */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
898
tools/re2c/re.h
898
tools/re2c/re.h
|
@ -1,16 +1,16 @@
|
||||||
/* $Id: re.h,v 1.17 2006/04/09 00:06:33 helly Exp $ */
|
/* $Id: re.h 775 2007-07-10 19:33:17Z helly $ */
|
||||||
#ifndef _re_h
|
#ifndef _re_h
|
||||||
#define _re_h
|
#define _re_h
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "ins.h"
|
#include "ins.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
namespace re2c
|
namespace re2c
|
||||||
{
|
{
|
||||||
|
|
||||||
template<class _Ty>
|
template<class _Ty>
|
||||||
class free_list: protected std::set<_Ty>
|
class free_list: protected std::set<_Ty>
|
||||||
{
|
{
|
||||||
|
@ -55,436 +55,442 @@ public:
|
||||||
protected:
|
protected:
|
||||||
bool in_clear;
|
bool in_clear;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct extop
|
typedef struct extop
|
||||||
{
|
{
|
||||||
char op;
|
char op;
|
||||||
int minsize;
|
int minsize;
|
||||||
int maxsize;
|
int maxsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtOp;
|
ExtOp;
|
||||||
|
|
||||||
struct CharPtn
|
struct CharPtn
|
||||||
{
|
{
|
||||||
uint card;
|
uint card;
|
||||||
CharPtn *fix;
|
CharPtn *fix;
|
||||||
CharPtn *nxt;
|
CharPtn *nxt;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef CharPtn *CharPtr;
|
typedef CharPtn *CharPtr;
|
||||||
|
|
||||||
struct CharSet
|
struct CharSet
|
||||||
{
|
{
|
||||||
CharSet();
|
CharSet();
|
||||||
~CharSet();
|
~CharSet();
|
||||||
|
|
||||||
CharPtn *fix;
|
CharPtn *fix;
|
||||||
CharPtn *freeHead, **freeTail;
|
CharPtn *freeHead, **freeTail;
|
||||||
CharPtr *rep;
|
CharPtr *rep;
|
||||||
CharPtn *ptn;
|
CharPtn *ptn;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Range
|
class Range
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Range *next;
|
Range *next;
|
||||||
uint lb, ub; // [lb,ub)
|
uint lb, ub; // [lb,ub)
|
||||||
|
|
||||||
static free_list<Range*> vFreeList;
|
static free_list<Range*> vFreeList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Range(uint l, uint u) : next(NULL), lb(l), ub(u)
|
Range(uint l, uint u) : next(NULL), lb(l), ub(u)
|
||||||
{
|
{
|
||||||
vFreeList.insert(this);
|
vFreeList.insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub)
|
Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub)
|
||||||
{
|
{
|
||||||
vFreeList.insert(this);
|
vFreeList.insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream&, const Range&);
|
~Range()
|
||||||
friend std::ostream& operator<<(std::ostream&, const Range*);
|
{
|
||||||
};
|
vFreeList.erase(this);
|
||||||
|
}
|
||||||
inline std::ostream& operator<<(std::ostream &o, const Range *r)
|
|
||||||
{
|
friend std::ostream& operator<<(std::ostream&, const Range&);
|
||||||
return r ? o << *r : o;
|
friend std::ostream& operator<<(std::ostream&, const Range*);
|
||||||
}
|
};
|
||||||
|
|
||||||
class RegExp
|
inline std::ostream& operator<<(std::ostream &o, const Range *r)
|
||||||
{
|
{
|
||||||
|
return r ? o << *r : o;
|
||||||
public:
|
}
|
||||||
uint size;
|
|
||||||
|
class RegExp
|
||||||
static free_list<RegExp*> vFreeList;
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegExp() : size(0)
|
uint size;
|
||||||
{
|
|
||||||
}
|
static free_list<RegExp*> vFreeList;
|
||||||
|
|
||||||
virtual ~RegExp()
|
public:
|
||||||
{
|
RegExp() : size(0)
|
||||||
vFreeList.erase(this);
|
{
|
||||||
}
|
vFreeList.insert(this);
|
||||||
|
}
|
||||||
virtual const char *typeOf() = 0;
|
|
||||||
RegExp *isA(const char *t)
|
virtual ~RegExp()
|
||||||
{
|
{
|
||||||
return typeOf() == t ? this : NULL;
|
vFreeList.erase(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void split(CharSet&) = 0;
|
virtual const char *typeOf() = 0;
|
||||||
virtual void calcSize(Char*) = 0;
|
RegExp *isA(const char *t)
|
||||||
virtual uint fixedLength();
|
{
|
||||||
virtual void compile(Char*, Ins*) = 0;
|
return typeOf() == t ? this : NULL;
|
||||||
virtual void display(std::ostream&) const = 0;
|
}
|
||||||
friend std::ostream& operator<<(std::ostream&, const RegExp&);
|
|
||||||
friend std::ostream& operator<<(std::ostream&, const RegExp*);
|
virtual void split(CharSet&) = 0;
|
||||||
};
|
virtual void calcSize(Char*) = 0;
|
||||||
|
virtual uint fixedLength();
|
||||||
inline std::ostream& operator<<(std::ostream &o, const RegExp &re)
|
virtual void compile(Char*, Ins*) = 0;
|
||||||
{
|
virtual void display(std::ostream&) const = 0;
|
||||||
re.display(o);
|
friend std::ostream& operator<<(std::ostream&, const RegExp&);
|
||||||
return o;
|
friend std::ostream& operator<<(std::ostream&, const RegExp*);
|
||||||
}
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream &o, const RegExp *re)
|
inline std::ostream& operator<<(std::ostream &o, const RegExp &re)
|
||||||
{
|
{
|
||||||
return o << *re;
|
re.display(o);
|
||||||
}
|
return o;
|
||||||
|
}
|
||||||
class NullOp: public RegExp
|
|
||||||
{
|
inline std::ostream& operator<<(std::ostream &o, const RegExp *re)
|
||||||
|
{
|
||||||
public:
|
return o << *re;
|
||||||
static const char *type;
|
}
|
||||||
|
|
||||||
public:
|
class NullOp: public RegExp
|
||||||
const char *typeOf()
|
{
|
||||||
{
|
|
||||||
return type;
|
public:
|
||||||
}
|
static const char *type;
|
||||||
|
|
||||||
void split(CharSet&);
|
public:
|
||||||
void calcSize(Char*);
|
const char *typeOf()
|
||||||
uint fixedLength();
|
{
|
||||||
void compile(Char*, Ins*);
|
return type;
|
||||||
void display(std::ostream &o) const
|
}
|
||||||
{
|
|
||||||
o << "_";
|
void split(CharSet&);
|
||||||
}
|
void calcSize(Char*);
|
||||||
};
|
uint fixedLength();
|
||||||
|
void compile(Char*, Ins*);
|
||||||
class MatchOp: public RegExp
|
void display(std::ostream &o) const
|
||||||
{
|
{
|
||||||
|
o << "_";
|
||||||
public:
|
}
|
||||||
static const char *type;
|
};
|
||||||
Range *match;
|
|
||||||
|
class MatchOp: public RegExp
|
||||||
public:
|
{
|
||||||
MatchOp(Range *m) : match(m)
|
|
||||||
{
|
public:
|
||||||
}
|
static const char *type;
|
||||||
|
Range *match;
|
||||||
const char *typeOf()
|
|
||||||
{
|
public:
|
||||||
return type;
|
MatchOp(Range *m) : match(m)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
void split(CharSet&);
|
|
||||||
void calcSize(Char*);
|
const char *typeOf()
|
||||||
uint fixedLength();
|
{
|
||||||
void compile(Char*, Ins*);
|
return type;
|
||||||
void display(std::ostream&) const;
|
}
|
||||||
|
|
||||||
#ifdef PEDANTIC
|
void split(CharSet&);
|
||||||
private:
|
void calcSize(Char*);
|
||||||
MatchOp(const MatchOp& oth)
|
uint fixedLength();
|
||||||
: RegExp(oth)
|
void compile(Char*, Ins*);
|
||||||
, match(oth.match)
|
void display(std::ostream&) const;
|
||||||
{
|
|
||||||
}
|
#ifdef PEDANTIC
|
||||||
|
private:
|
||||||
MatchOp& operator = (const MatchOp& oth)
|
MatchOp(const MatchOp& oth)
|
||||||
{
|
: RegExp(oth)
|
||||||
new(this) MatchOp(oth);
|
, match(oth.match)
|
||||||
return *this;
|
{
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
};
|
MatchOp& operator = (const MatchOp& oth)
|
||||||
|
{
|
||||||
class RuleOp: public RegExp
|
new(this) MatchOp(oth);
|
||||||
{
|
return *this;
|
||||||
public:
|
}
|
||||||
static const char *type;
|
#endif
|
||||||
|
};
|
||||||
private:
|
|
||||||
RegExp *exp;
|
class RuleOp: public RegExp
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
RegExp *ctx;
|
static const char *type;
|
||||||
Ins *ins;
|
|
||||||
uint accept;
|
private:
|
||||||
Token *code;
|
RegExp *exp;
|
||||||
uint line;
|
|
||||||
|
public:
|
||||||
public:
|
RegExp *ctx;
|
||||||
RuleOp(RegExp*, RegExp*, Token*, uint);
|
Ins *ins;
|
||||||
|
uint accept;
|
||||||
~RuleOp()
|
Token *code;
|
||||||
{
|
uint line;
|
||||||
delete code;
|
|
||||||
}
|
public:
|
||||||
|
RuleOp(RegExp*, RegExp*, Token*, uint);
|
||||||
const char *typeOf()
|
|
||||||
{
|
~RuleOp()
|
||||||
return type;
|
{
|
||||||
}
|
delete code;
|
||||||
|
}
|
||||||
void split(CharSet&);
|
|
||||||
void calcSize(Char*);
|
const char *typeOf()
|
||||||
void compile(Char*, Ins*);
|
{
|
||||||
void display(std::ostream &o) const
|
return type;
|
||||||
{
|
}
|
||||||
o << exp << "/" << ctx << ";";
|
|
||||||
}
|
void split(CharSet&);
|
||||||
|
void calcSize(Char*);
|
||||||
#ifdef PEDANTIC
|
void compile(Char*, Ins*);
|
||||||
private:
|
void display(std::ostream &o) const
|
||||||
RuleOp(const RuleOp& oth)
|
{
|
||||||
: RegExp(oth)
|
o << exp << "/" << ctx << ";";
|
||||||
, exp(oth.exp)
|
}
|
||||||
, ctx(oth.ctx)
|
|
||||||
, ins(oth.ins)
|
#ifdef PEDANTIC
|
||||||
, accept(oth.accept)
|
private:
|
||||||
, code(oth.code)
|
RuleOp(const RuleOp& oth)
|
||||||
, line(oth.line)
|
: RegExp(oth)
|
||||||
{
|
, exp(oth.exp)
|
||||||
}
|
, ctx(oth.ctx)
|
||||||
RuleOp& operator = (const RuleOp& oth)
|
, ins(oth.ins)
|
||||||
{
|
, accept(oth.accept)
|
||||||
new(this) RuleOp(oth);
|
, code(oth.code)
|
||||||
return *this;
|
, line(oth.line)
|
||||||
}
|
{
|
||||||
#endif
|
}
|
||||||
};
|
RuleOp& operator = (const RuleOp& oth)
|
||||||
|
{
|
||||||
class RuleLine: public line_number
|
new(this) RuleOp(oth);
|
||||||
{
|
return *this;
|
||||||
public:
|
}
|
||||||
|
#endif
|
||||||
RuleLine(const RuleOp& _op)
|
};
|
||||||
: op(_op)
|
|
||||||
{
|
class RuleLine: public line_number
|
||||||
}
|
{
|
||||||
|
public:
|
||||||
uint get_line() const
|
|
||||||
{
|
RuleLine(const RuleOp& _op)
|
||||||
return op.code->line;
|
: op(_op)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
const RuleOp& op;
|
|
||||||
};
|
uint get_line() const
|
||||||
|
{
|
||||||
RegExp *mkAlt(RegExp*, RegExp*);
|
return op.code->line;
|
||||||
|
}
|
||||||
class AltOp: public RegExp
|
|
||||||
{
|
const RuleOp& op;
|
||||||
|
};
|
||||||
private:
|
|
||||||
RegExp *exp1, *exp2;
|
RegExp *mkAlt(RegExp*, RegExp*);
|
||||||
|
|
||||||
public:
|
class AltOp: public RegExp
|
||||||
static const char *type;
|
{
|
||||||
|
|
||||||
public:
|
private:
|
||||||
AltOp(RegExp *e1, RegExp *e2)
|
RegExp *exp1, *exp2;
|
||||||
: exp1(e1)
|
|
||||||
, exp2(e2)
|
public:
|
||||||
{
|
static const char *type;
|
||||||
}
|
|
||||||
|
public:
|
||||||
const char *typeOf()
|
AltOp(RegExp *e1, RegExp *e2)
|
||||||
{
|
: exp1(e1)
|
||||||
return type;
|
, exp2(e2)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
void split(CharSet&);
|
|
||||||
void calcSize(Char*);
|
const char *typeOf()
|
||||||
uint fixedLength();
|
{
|
||||||
void compile(Char*, Ins*);
|
return type;
|
||||||
void display(std::ostream &o) const
|
}
|
||||||
{
|
|
||||||
o << exp1 << "|" << exp2;
|
void split(CharSet&);
|
||||||
}
|
void calcSize(Char*);
|
||||||
|
uint fixedLength();
|
||||||
friend RegExp *mkAlt(RegExp*, RegExp*);
|
void compile(Char*, Ins*);
|
||||||
|
void display(std::ostream &o) const
|
||||||
#ifdef PEDANTIC
|
{
|
||||||
private:
|
o << exp1 << "|" << exp2;
|
||||||
AltOp(const AltOp& oth)
|
}
|
||||||
: RegExp(oth)
|
|
||||||
, exp1(oth.exp1)
|
friend RegExp *mkAlt(RegExp*, RegExp*);
|
||||||
, exp2(oth.exp2)
|
|
||||||
{
|
#ifdef PEDANTIC
|
||||||
}
|
private:
|
||||||
AltOp& operator = (const AltOp& oth)
|
AltOp(const AltOp& oth)
|
||||||
{
|
: RegExp(oth)
|
||||||
new(this) AltOp(oth);
|
, exp1(oth.exp1)
|
||||||
return *this;
|
, exp2(oth.exp2)
|
||||||
}
|
{
|
||||||
#endif
|
}
|
||||||
};
|
AltOp& operator = (const AltOp& oth)
|
||||||
|
{
|
||||||
class CatOp: public RegExp
|
new(this) AltOp(oth);
|
||||||
{
|
return *this;
|
||||||
|
}
|
||||||
private:
|
#endif
|
||||||
RegExp *exp1, *exp2;
|
};
|
||||||
|
|
||||||
public:
|
class CatOp: public RegExp
|
||||||
static const char *type;
|
{
|
||||||
|
|
||||||
public:
|
private:
|
||||||
CatOp(RegExp *e1, RegExp *e2)
|
RegExp *exp1, *exp2;
|
||||||
: exp1(e1)
|
|
||||||
, exp2(e2)
|
public:
|
||||||
{
|
static const char *type;
|
||||||
}
|
|
||||||
|
public:
|
||||||
const char *typeOf()
|
CatOp(RegExp *e1, RegExp *e2)
|
||||||
{
|
: exp1(e1)
|
||||||
return type;
|
, exp2(e2)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
void split(CharSet&);
|
|
||||||
void calcSize(Char*);
|
const char *typeOf()
|
||||||
uint fixedLength();
|
{
|
||||||
void compile(Char*, Ins*);
|
return type;
|
||||||
void display(std::ostream &o) const
|
}
|
||||||
{
|
|
||||||
o << exp1 << exp2;
|
void split(CharSet&);
|
||||||
}
|
void calcSize(Char*);
|
||||||
|
uint fixedLength();
|
||||||
#ifdef PEDANTIC
|
void compile(Char*, Ins*);
|
||||||
private:
|
void display(std::ostream &o) const
|
||||||
CatOp(const CatOp& oth)
|
{
|
||||||
: RegExp(oth)
|
o << exp1 << exp2;
|
||||||
, exp1(oth.exp1)
|
}
|
||||||
, exp2(oth.exp2)
|
|
||||||
{
|
#ifdef PEDANTIC
|
||||||
}
|
private:
|
||||||
CatOp& operator = (const CatOp& oth)
|
CatOp(const CatOp& oth)
|
||||||
{
|
: RegExp(oth)
|
||||||
new(this) CatOp(oth);
|
, exp1(oth.exp1)
|
||||||
return *this;
|
, exp2(oth.exp2)
|
||||||
}
|
{
|
||||||
#endif
|
}
|
||||||
};
|
CatOp& operator = (const CatOp& oth)
|
||||||
|
{
|
||||||
class CloseOp: public RegExp
|
new(this) CatOp(oth);
|
||||||
{
|
return *this;
|
||||||
|
}
|
||||||
private:
|
#endif
|
||||||
RegExp *exp;
|
};
|
||||||
|
|
||||||
public:
|
class CloseOp: public RegExp
|
||||||
static const char *type;
|
{
|
||||||
|
|
||||||
public:
|
private:
|
||||||
CloseOp(RegExp *e)
|
RegExp *exp;
|
||||||
: exp(e)
|
|
||||||
{
|
public:
|
||||||
}
|
static const char *type;
|
||||||
|
|
||||||
const char *typeOf()
|
public:
|
||||||
{
|
CloseOp(RegExp *e)
|
||||||
return type;
|
: exp(e)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
void split(CharSet&);
|
|
||||||
void calcSize(Char*);
|
const char *typeOf()
|
||||||
void compile(Char*, Ins*);
|
{
|
||||||
void display(std::ostream &o) const
|
return type;
|
||||||
{
|
}
|
||||||
o << exp << "+";
|
|
||||||
}
|
void split(CharSet&);
|
||||||
|
void calcSize(Char*);
|
||||||
#ifdef PEDANTIC
|
void compile(Char*, Ins*);
|
||||||
private:
|
void display(std::ostream &o) const
|
||||||
CloseOp(const CloseOp& oth)
|
{
|
||||||
: RegExp(oth)
|
o << exp << "+";
|
||||||
, exp(oth.exp)
|
}
|
||||||
{
|
|
||||||
}
|
#ifdef PEDANTIC
|
||||||
CloseOp& operator = (const CloseOp& oth)
|
private:
|
||||||
{
|
CloseOp(const CloseOp& oth)
|
||||||
new(this) CloseOp(oth);
|
: RegExp(oth)
|
||||||
return *this;
|
, exp(oth.exp)
|
||||||
}
|
{
|
||||||
#endif
|
}
|
||||||
};
|
CloseOp& operator = (const CloseOp& oth)
|
||||||
|
{
|
||||||
class CloseVOp: public RegExp
|
new(this) CloseOp(oth);
|
||||||
{
|
return *this;
|
||||||
|
}
|
||||||
private:
|
#endif
|
||||||
RegExp *exp;
|
};
|
||||||
int min;
|
|
||||||
int max;
|
class CloseVOp: public RegExp
|
||||||
|
{
|
||||||
public:
|
|
||||||
static const char *type;
|
private:
|
||||||
|
RegExp *exp;
|
||||||
public:
|
int min;
|
||||||
CloseVOp(RegExp *e, int lb, int ub)
|
int max;
|
||||||
: exp(e)
|
|
||||||
, min(lb)
|
public:
|
||||||
, max(ub)
|
static const char *type;
|
||||||
{
|
|
||||||
}
|
public:
|
||||||
|
CloseVOp(RegExp *e, int lb, int ub)
|
||||||
const char *typeOf()
|
: exp(e)
|
||||||
{
|
, min(lb)
|
||||||
return type;
|
, max(ub)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
void split(CharSet&);
|
|
||||||
void calcSize(Char*);
|
const char *typeOf()
|
||||||
void compile(Char*, Ins*);
|
{
|
||||||
void display(std::ostream &o) const
|
return type;
|
||||||
{
|
}
|
||||||
o << exp << "+";
|
|
||||||
}
|
void split(CharSet&);
|
||||||
#ifdef PEDANTIC
|
void calcSize(Char*);
|
||||||
private:
|
void compile(Char*, Ins*);
|
||||||
CloseVOp(const CloseVOp& oth)
|
void display(std::ostream &o) const
|
||||||
: RegExp(oth)
|
{
|
||||||
, exp(oth.exp)
|
o << exp << "+";
|
||||||
, min(oth.min)
|
}
|
||||||
, max(oth.max)
|
#ifdef PEDANTIC
|
||||||
{
|
private:
|
||||||
}
|
CloseVOp(const CloseVOp& oth)
|
||||||
CloseVOp& operator = (const CloseVOp& oth)
|
: RegExp(oth)
|
||||||
{
|
, exp(oth.exp)
|
||||||
new(this) CloseVOp(oth);
|
, min(oth.min)
|
||||||
return *this;
|
, max(oth.max)
|
||||||
}
|
{
|
||||||
#endif
|
}
|
||||||
};
|
CloseVOp& operator = (const CloseVOp& oth)
|
||||||
|
{
|
||||||
extern void genCode(std::ostream&, RegExp*);
|
new(this) CloseVOp(oth);
|
||||||
extern void genCode(std::ostream&, uint, RegExp*);
|
return *this;
|
||||||
extern void genGetState(std::ostream&, uint&, uint);
|
}
|
||||||
extern RegExp *mkDiff(RegExp*, RegExp*);
|
#endif
|
||||||
extern RegExp *mkAlt(RegExp*, RegExp*);
|
};
|
||||||
|
|
||||||
} // end namespace re2c
|
extern void genCode(std::ostream&, RegExp*);
|
||||||
|
extern void genCode(std::ostream&, uint, RegExp*);
|
||||||
#endif
|
extern void genGetState(std::ostream&, uint&, uint);
|
||||||
|
extern RegExp *mkDiff(RegExp*, RegExp*);
|
||||||
|
extern RegExp *mkAlt(RegExp*, RegExp*);
|
||||||
|
|
||||||
|
} // end namespace re2c
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
./"
|
./"
|
||||||
./" $Id: re2c.1.in 523 2006-05-25 13:32:09Z helly $
|
./" $Id: re2c.1.in 663 2007-04-01 11:22:15Z helly $
|
||||||
./"
|
./"
|
||||||
.TH RE2C 1 "22 April 2005" "Version 0.10.5"
|
.TH RE2C 1 "22 April 2005" "Version 0.12.3"
|
||||||
.ds re \fBre2c\fP
|
.ds re \fBre2c\fP
|
||||||
.ds le \fBlex\fP
|
.ds le \fBlex\fP
|
||||||
.ds rx regular expression
|
.ds rx regular expression
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
re2c \- convert regular expressions to C/C++
|
re2c \- convert regular expressions to C/C++
|
||||||
|
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
\*(re [\fB-bdefghisvVw1\fP] [\fB-o output\fP] file\fP
|
\*(re [\fB-bdefghisuvVw1\fP] [\fB-o output\fP] file\fP
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\*(re is a preprocessor that generates C-based recognizers from regular
|
\*(re is a preprocessor that generates C-based recognizers from regular
|
||||||
|
@ -26,61 +26,51 @@ For example, given the following code
|
||||||
|
|
||||||
.in +3
|
.in +3
|
||||||
.nf
|
.nf
|
||||||
#define NULL ((char*) 0)
|
|
||||||
char *scan(char *p)
|
char *scan(char *p)
|
||||||
{
|
{
|
||||||
#define YYCTYPE char
|
|
||||||
#define YYCURSOR p
|
|
||||||
#define YYLIMIT p
|
|
||||||
#define YYFILL(n)
|
|
||||||
/*!re2c
|
/*!re2c
|
||||||
[0-9]+ {return YYCURSOR;}
|
re2c:define:YYCTYPE = "unsigned char";
|
||||||
[\\000-\\377] {return NULL;}
|
re2c:define:YYCURSOR = p;
|
||||||
|
re2c:yyfill:enable = 0;
|
||||||
|
re2c:yych:conversion = 1;
|
||||||
|
re2c:indent:top = 1;
|
||||||
|
[0-9]+ {return p;}
|
||||||
|
[\000-\377] {return (char*)0;}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
.fi
|
.fi
|
||||||
.in -3
|
.in -3
|
||||||
|
|
||||||
\*(re will generate
|
\*(re -is will generate
|
||||||
|
|
||||||
.in +3
|
.in +3
|
||||||
.nf
|
.nf
|
||||||
/* Generated by re2c on Sat Apr 16 11:40:58 1994 */
|
/* Generated by re2c on Sat Apr 16 11:40:58 1994 */
|
||||||
#line 1 "simple.re"
|
|
||||||
#define NULL ((char*) 0)
|
|
||||||
char *scan(char *p)
|
char *scan(char *p)
|
||||||
{
|
{
|
||||||
#define YYCTYPE char
|
{
|
||||||
#define YYCURSOR p
|
unsigned char yych;
|
||||||
#define YYLIMIT p
|
|
||||||
#define YYFILL(n)
|
yych = (unsigned char)*p;
|
||||||
{
|
if(yych <= '/') goto yy4;
|
||||||
YYCTYPE yych;
|
if(yych >= ':') goto yy4;
|
||||||
unsigned int yyaccept;
|
++p;
|
||||||
goto yy0;
|
yych = (unsigned char)*p;
|
||||||
yy1: ++YYCURSOR;
|
|
||||||
yy0:
|
|
||||||
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
|
|
||||||
yych = *YYCURSOR;
|
|
||||||
if(yych <= '/') goto yy4;
|
|
||||||
if(yych >= ':') goto yy4;
|
|
||||||
yy2: yych = *++YYCURSOR;
|
|
||||||
goto yy7;
|
goto yy7;
|
||||||
yy3:
|
yy3:
|
||||||
#line 9
|
{return p;}
|
||||||
{return YYCURSOR;}
|
yy4:
|
||||||
yy4: yych = *++YYCURSOR;
|
++p;
|
||||||
yy5:
|
yych = (unsigned char)*p;
|
||||||
#line 10
|
{return char*)0;}
|
||||||
{return NULL;}
|
yy6:
|
||||||
yy6: ++YYCURSOR;
|
++p;
|
||||||
if(YYLIMIT == YYCURSOR) YYFILL(1);
|
yych = (unsigned char)*p;
|
||||||
yych = *YYCURSOR;
|
yy7:
|
||||||
yy7: if(yych <= '/') goto yy3;
|
if(yych <= '/') goto yy3;
|
||||||
if(yych <= '9') goto yy6;
|
if(yych <= '9') goto yy6;
|
||||||
goto yy3;
|
goto yy3;
|
||||||
}
|
}
|
||||||
#line 11
|
|
||||||
|
|
||||||
}
|
}
|
||||||
.fi
|
.fi
|
||||||
|
@ -123,7 +113,7 @@ Generate a scanner with support for storable state.
|
||||||
For details see below at \fBSCANNER WITH STORABLE STATES\fP.
|
For details see below at \fBSCANNER WITH STORABLE STATES\fP.
|
||||||
.TP
|
.TP
|
||||||
\fB-g\fP
|
\fB-g\fP
|
||||||
Generate a scanner that utilizes GCC's computed goto feature. That is re2c
|
Generate a scanner that utilizes GCC's computed goto feature. That is \*(re
|
||||||
generates jump tables whenever a decision is of a certain complexity (e.g. a
|
generates jump tables whenever a decision is of a certain complexity (e.g. a
|
||||||
lot of if conditions are otherwise necessary). This is only useable with GCC
|
lot of if conditions are otherwise necessary). This is only useable with GCC
|
||||||
and produces output that cannot be compiled with any other compiler. Note that
|
and produces output that cannot be compiled with any other compiler. Note that
|
||||||
|
@ -132,8 +122,8 @@ inplace configuration "cgoto:threshold".
|
||||||
.TP
|
.TP
|
||||||
\fB-i\fP
|
\fB-i\fP
|
||||||
Do not output #line information. This is usefull when you want use a CMS tool
|
Do not output #line information. This is usefull when you want use a CMS tool
|
||||||
with the re2c output which you might want if you do not require your users to
|
with the \*(re output which you might want if you do not require your users to
|
||||||
have re2c themselves when building from your source.
|
have \*(re themselves when building from your source.
|
||||||
\fB-o output\fP
|
\fB-o output\fP
|
||||||
Specify the output file.
|
Specify the output file.
|
||||||
.TP
|
.TP
|
||||||
|
@ -141,6 +131,12 @@ Specify the output file.
|
||||||
Generate nested \fCif\fPs for some \fCswitch\fPes. Many compilers need this
|
Generate nested \fCif\fPs for some \fCswitch\fPes. Many compilers need this
|
||||||
assist to generate better code.
|
assist to generate better code.
|
||||||
.TP
|
.TP
|
||||||
|
\fB-u\fP
|
||||||
|
Generate a parser that supports Unicode chars (UTF-32). This means the
|
||||||
|
generated code can deal with any valid Unicode character up to 0x10FFFF. When
|
||||||
|
UTF-8 or UTF-16 needs to be supported you need to convert the incoming stream
|
||||||
|
to UTF-32 upon input yourself.
|
||||||
|
.TP
|
||||||
\fB-v\fP
|
\fB-v\fP
|
||||||
Show version information.
|
Show version information.
|
||||||
.TP
|
.TP
|
||||||
|
@ -153,11 +149,16 @@ cannot be used together with \fB-e\fP switch.
|
||||||
.TP
|
.TP
|
||||||
\fB-1\fP
|
\fB-1\fP
|
||||||
Force single pass generation, this cannot be combined with -f and disables
|
Force single pass generation, this cannot be combined with -f and disables
|
||||||
YYMAXFILL generation prior to last re2c block.
|
YYMAXFILL generation prior to last \*(re block.
|
||||||
|
.TP
|
||||||
|
\fb--no-generation-date\fP
|
||||||
|
Suppress date output in the generated output so that it only shows the re2c
|
||||||
|
version.
|
||||||
.SH "INTERFACE CODE"
|
.SH "INTERFACE CODE"
|
||||||
Unlike other scanner generators, \*(re does not generate complete scanners:
|
Unlike other scanner generators, \*(re does not generate complete scanners:
|
||||||
the user must supply some interface code.
|
the user must supply some interface code.
|
||||||
In particular, the user must define the following macros:
|
In particular, the user must define the following macros or use the
|
||||||
|
corresponding inplace configurations:
|
||||||
.TP
|
.TP
|
||||||
\fCYYCTYPE\fP
|
\fCYYCTYPE\fP
|
||||||
Type used to hold an input symbol.
|
Type used to hold an input symbol.
|
||||||
|
@ -187,26 +188,27 @@ The generated code saves trailing context backtracking information in \fCYYCTXMA
|
||||||
The user only needs to define this macro if a scanner specification uses trailing
|
The user only needs to define this macro if a scanner specification uses trailing
|
||||||
context in one or more of its regular expressions.
|
context in one or more of its regular expressions.
|
||||||
.TP
|
.TP
|
||||||
\fCYYFILL(\fP\fIn\fP\fC)\fP
|
\fCYYFILL\fP(\fIn\fP\fC\fP)
|
||||||
The generated code "calls" \fCYYFILL\fP(n) when the buffer needs
|
The generated code "calls" \fCYYFILL\fP(n) when the buffer needs
|
||||||
(re)filling: at least \fIn\fP additional characters should
|
(re)filling: at least \fIn\fP additional characters should
|
||||||
be provided. \fCYYFILL\fP(n) should adjust \fCYYCURSOR\fP, \fCYYLIMIT\fP,
|
be provided. \fCYYFILL\fP(n) should adjust \fCYYCURSOR\fP, \fCYYLIMIT\fP,
|
||||||
\fCYYMARKER\fP and \fCYYCTXMARKER\fP as needed. Note that for typical
|
\fCYYMARKER\fP and \fCYYCTXMARKER\fP as needed. Note that for typical
|
||||||
programming languages \fIn\fP will be the length of the longest keyword plus one.
|
programming languages \fIn\fP will be the length of the longest keyword plus one.
|
||||||
The user can place a comment of the form \fC/*!max:re2c */\fP once to insert
|
The user can place a comment of the form \fC/*!max:re2c */\fP once to insert
|
||||||
a \fCYYMAXFILL\fP definition that is set to the maximum length value. If -1
|
a \fCYYMAXFILL\fP(n) definition that is set to the maximum length value. If -1
|
||||||
switch is used then YYMAXFILL can be triggered once after the last \fC/*!re2c */\fP
|
switch is used then \fCYYMAXFILL\fP can be triggered only once after the
|
||||||
|
last \fC/*!re2c */\fP
|
||||||
block.
|
block.
|
||||||
.TP
|
.TP
|
||||||
\fCYYGETSTATE()\fP
|
\fCYYGETSTATE\fP()
|
||||||
The user only needs to define this macro if the \fB-f\fP flag was specified.
|
The user only needs to define this macro if the \fB-f\fP flag was specified.
|
||||||
In that case, the generated code "calls" \fCYYGETSTATE\fP at the very beginning
|
In that case, the generated code "calls" \fCYYGETSTATE\fP() at the very beginning
|
||||||
of the scanner in order to obtain the saved state. YYGETSTATE must return a signed
|
of the scanner in order to obtain the saved state. \fCYYGETSTATE\fP() must return a signed
|
||||||
integer. The value must be either -1, indicating that the scanner is entered for the
|
integer. The value must be either -1, indicating that the scanner is entered for the
|
||||||
first time, or a value previously saved by \fCYYSETSTATE\fP. In the second case, the
|
first time, or a value previously saved by \fCYYSETSTATE\fP(s). In the second case, the
|
||||||
scanner will resume operations right after where the last \fCYYFILL\fP(n) was called.
|
scanner will resume operations right after where the last \fCYYFILL\fP(n) was called.
|
||||||
.TP
|
.TP
|
||||||
\fCYYSETSTATE(\fP\fIn\fP\fC)\fP
|
\fCYYSETSTATE(\fP\fIs\fP\fC)\fP
|
||||||
The user only needs to define this macro if the \fB-f\fP flag was specified.
|
The user only needs to define this macro if the \fB-f\fP flag was specified.
|
||||||
In that case, the generated code "calls" \fCYYSETSTATE\fP just before calling
|
In that case, the generated code "calls" \fCYYSETSTATE\fP just before calling
|
||||||
\fCYYFILL\fP(n). The parameter to \fCYYSETSTATE\fP is a signed integer that uniquely
|
\fCYYFILL\fP(n). The parameter to \fCYYSETSTATE\fP is a signed integer that uniquely
|
||||||
|
@ -214,7 +216,9 @@ identifies the specific instance of \fCYYFILL\fP(n) that is about to be called.
|
||||||
Should the user wish to save the state of the scanner and have \fCYYFILL\fP(n) return
|
Should the user wish to save the state of the scanner and have \fCYYFILL\fP(n) return
|
||||||
to the caller, all he has to do is store that unique identifer in a variable.
|
to the caller, all he has to do is store that unique identifer in a variable.
|
||||||
Later, when the scannered is called again, it will call \fCYYGETSTATE()\fP and
|
Later, when the scannered is called again, it will call \fCYYGETSTATE()\fP and
|
||||||
resume execution right where it left off.
|
resume execution right where it left off. The generated code will contain
|
||||||
|
both \fCYYSETSTATE\fP(s) and \fCYYGETSTATE\fP even if \fCYYFILL\fP(n) is being
|
||||||
|
disabled.
|
||||||
.TP
|
.TP
|
||||||
\fCYYDEBUG(\fP\fIstate\fP,\fIcurrent\fC)\fP
|
\fCYYDEBUG(\fP\fIstate\fP,\fIcurrent\fC)\fP
|
||||||
This is only needed if the \fB-d\fP flag was specified. It allows to easily debug
|
This is only needed if the \fB-d\fP flag was specified. It allows to easily debug
|
||||||
|
@ -227,11 +231,11 @@ input at the current cursor.
|
||||||
This will be automatically defined by \fC/*!max:re2c */\fP blocks as explained above.
|
This will be automatically defined by \fC/*!max:re2c */\fP blocks as explained above.
|
||||||
|
|
||||||
.SH "SCANNER WITH STORABLE STATES"
|
.SH "SCANNER WITH STORABLE STATES"
|
||||||
When the \fB-f\fP flag is specified, re2c generates a scanner that
|
When the \fB-f\fP flag is specified, \*(re generates a scanner that
|
||||||
can store its current state, return to the caller, and later resume
|
can store its current state, return to the caller, and later resume
|
||||||
operations exactly where it left off.
|
operations exactly where it left off.
|
||||||
|
|
||||||
The default operation of re2c is a "pull" model, where the scanner asks
|
The default operation of \*(re is a "pull" model, where the scanner asks
|
||||||
for extra input whenever it needs it. However, this mode of operation
|
for extra input whenever it needs it. However, this mode of operation
|
||||||
assumes that the scanner is the "owner" the parsing loop, and that may
|
assumes that the scanner is the "owner" the parsing loop, and that may
|
||||||
not always be convenient.
|
not always be convenient.
|
||||||
|
@ -246,9 +250,9 @@ chunk by chunk. When the scanner runs out of data to consume, it just stores
|
||||||
its state, and return to the caller. When more input data is fed to the scanner,
|
its state, and return to the caller. When more input data is fed to the scanner,
|
||||||
it resumes operations exactly where it left off.
|
it resumes operations exactly where it left off.
|
||||||
|
|
||||||
When using the -f option re2c does not accept stdin because it has to do the
|
When using the -f option \*(re does not accept stdin because it has to do the
|
||||||
full generation process twice which means it has to read the input twice. That
|
full generation process twice which means it has to read the input twice. That
|
||||||
means re2c would fail in case it cannot open the input twice or reading the
|
means \*(re would fail in case it cannot open the input twice or reading the
|
||||||
input for the first time influences the second read attempt.
|
input for the first time influences the second read attempt.
|
||||||
|
|
||||||
Changes needed compared to the "pull" model.
|
Changes needed compared to the "pull" model.
|
||||||
|
@ -286,7 +290,7 @@ Please see examples/push.re for push-model scanner. The generated code can be
|
||||||
tweaked using inplace configurations "\fBstate:abort\fP" and "\fBstate:nextlabel\fP".
|
tweaked using inplace configurations "\fBstate:abort\fP" and "\fBstate:nextlabel\fP".
|
||||||
|
|
||||||
.SH "SCANNER SPECIFICATIONS"
|
.SH "SCANNER SPECIFICATIONS"
|
||||||
Each scanner specification consists of a set of \fIrules\fP, \fIname
|
Each scanner specification consists of a set of \fIrules\fP, \fInamed
|
||||||
definitions\fP and \fIconfigurations\fP.
|
definitions\fP and \fIconfigurations\fP.
|
||||||
.LP
|
.LP
|
||||||
\fIRules\fP consist of a regular expression along with a block of C/C++ code that
|
\fIRules\fP consist of a regular expression along with a block of C/C++ code that
|
||||||
|
@ -302,12 +306,15 @@ Named definitions are of the form:
|
||||||
\fIname\fP \fC=\fP \fIregular expression\fP\fC;\fP
|
\fIname\fP \fC=\fP \fIregular expression\fP\fC;\fP
|
||||||
.RE
|
.RE
|
||||||
.LP
|
.LP
|
||||||
Configurations look like name definitions whose names start
|
Configurations look like named definitions whose names start
|
||||||
with "\fBre2c:\fP":
|
with "\fBre2c:\fP":
|
||||||
.P
|
.P
|
||||||
.RS
|
.RS
|
||||||
\fCre2c:\fP\fIname\fP \fC=\fP \fIvalue\fP\fC;\fP
|
\fCre2c:\fP\fIname\fP \fC=\fP \fIvalue\fP\fC;\fP
|
||||||
.RE
|
.RE
|
||||||
|
.RS
|
||||||
|
\fCre2c:\fP\fIname\fP \fC=\fP \fB"\fP\fIvalue\fP\fB"\fP\fC;\fP
|
||||||
|
.RE
|
||||||
|
|
||||||
.SH "SUMMARY OF RE2C REGULAR EXPRESSIONS"
|
.SH "SUMMARY OF RE2C REGULAR EXPRESSIONS"
|
||||||
.TP
|
.TP
|
||||||
|
@ -345,7 +352,7 @@ one or more \fIr\fP's
|
||||||
zero or one \fIr\fP's (that is, "an optional \fIr\fP")
|
zero or one \fIr\fP's (that is, "an optional \fIr\fP")
|
||||||
.TP
|
.TP
|
||||||
name
|
name
|
||||||
the expansion of the "name" definition (see above)
|
the expansion of the "named definition" (see above)
|
||||||
.TP
|
.TP
|
||||||
\fC(\fP\fIr\fP\fC)\fP
|
\fC(\fP\fIr\fP\fC)\fP
|
||||||
an \fIr\fP; parentheses are used to override precedence
|
an \fIr\fP; parentheses are used to override precedence
|
||||||
|
@ -385,12 +392,10 @@ and a hexadecimal character is defined by backslash, a lower cased '\fBx\fP'
|
||||||
and its two hexadecimal digits or a backslash, an upper cased \fBX\fP and its
|
and its two hexadecimal digits or a backslash, an upper cased \fBX\fP and its
|
||||||
four hexadecimal digits.
|
four hexadecimal digits.
|
||||||
.LP
|
.LP
|
||||||
re2c
|
\*(re further more supports the c/c++ unicode notation. That is a backslash followed
|
||||||
further more supports the c/c++ unicode notation. That is a backslash followed
|
|
||||||
by either a lowercased \fBu\fP and its four hexadecimal digits or an uppercased
|
by either a lowercased \fBu\fP and its four hexadecimal digits or an uppercased
|
||||||
\fBU\fP and its eight hexadecimal digits. However using the U notation it is
|
\fBU\fP and its eight hexadecimal digits. However only in \fB-u\fP mode the
|
||||||
not possible to support characters greater \fB\\U0000FFFF\fP due to an internal
|
generated code can deal with any valid Unicode character up to 0x10FFFF.
|
||||||
limitation of re2c.
|
|
||||||
.LP
|
.LP
|
||||||
Since characters greater \fB\\X00FF\fP are not allowed in non unicode mode, the
|
Since characters greater \fB\\X00FF\fP are not allowed in non unicode mode, the
|
||||||
only portable "\fBany\fP" rules are \fB(.|"\\n")\fP and \fB[^]\fP.
|
only portable "\fBany\fP" rules are \fB(.|"\\n")\fP and \fB[^]\fP.
|
||||||
|
@ -401,7 +406,7 @@ Those grouped together have equal precedence.
|
||||||
|
|
||||||
.SH "INPLACE CONFIGURATION"
|
.SH "INPLACE CONFIGURATION"
|
||||||
.LP
|
.LP
|
||||||
It is possible to configure code generation inside re2c blocks. The following
|
It is possible to configure code generation inside \*(re blocks. The following
|
||||||
lists the available configurations:
|
lists the available configurations:
|
||||||
.TP
|
.TP
|
||||||
\fIre2c:indent:top\fP \fB=\fP 0 \fB;\fP
|
\fIre2c:indent:top\fP \fB=\fP 0 \fB;\fP
|
||||||
|
@ -423,6 +428,12 @@ Set this to zero to suppress generation of YYFILL(n). When using this be sure
|
||||||
to verify that the generated scanner does not read behind input. Allowing
|
to verify that the generated scanner does not read behind input. Allowing
|
||||||
this behavior might introduce sever security issues to you programs.
|
this behavior might introduce sever security issues to you programs.
|
||||||
.TP
|
.TP
|
||||||
|
\fIre2c:yyfill:parameter\fP \fB=\fP 1 \fB;\fP
|
||||||
|
Allows to suppress parameter passing to \fBYYFILL\fP calls. If set to zero
|
||||||
|
then no parameter is passed to \fBYYFILL\fP. If set to a non zero value then
|
||||||
|
\fBYYFILL\fP usage will be followed by the number of requested characters in
|
||||||
|
braces.
|
||||||
|
.TP
|
||||||
\fIre2c:startlabel\fP \fB=\fP 0 \fB;\fP
|
\fIre2c:startlabel\fP \fB=\fP 0 \fB;\fP
|
||||||
If set to a non zero integer then the start label of the next scanner blocks
|
If set to a non zero integer then the start label of the next scanner blocks
|
||||||
will be generated even if not used by the scanner itself. Otherwise the normal
|
will be generated even if not used by the scanner itself. Otherwise the normal
|
||||||
|
@ -431,6 +442,10 @@ value then a label with that text will be generated regardless of whether the
|
||||||
normal start label is being used or not. This setting is being reset to \fB0\fP
|
normal start label is being used or not. This setting is being reset to \fB0\fP
|
||||||
after a start label has been generated.
|
after a start label has been generated.
|
||||||
.TP
|
.TP
|
||||||
|
\fIre2c:labelprefix\fP \fB=\fP yy \fB;\fP
|
||||||
|
Allows to change the prefix of numbered labels. The default is \fByy\fP and
|
||||||
|
can be set any string that is a valid label.
|
||||||
|
.TP
|
||||||
\fIre2c:state:abort\fP \fB=\fP 0 \fB;\fP
|
\fIre2c:state:abort\fP \fB=\fP 0 \fB;\fP
|
||||||
When not zero and switch -f is active then the \fCYYGETSTATE\fP block will
|
When not zero and switch -f is active then the \fCYYGETSTATE\fP block will
|
||||||
contain a default case that aborts and a -1 case is used for initialization.
|
contain a default case that aborts and a -1 case is used for initialization.
|
||||||
|
@ -448,11 +463,77 @@ When -g is active this value specifies the complexity threshold that triggers
|
||||||
generation of jump tables rather than using nested if's and decision bitfields.
|
generation of jump tables rather than using nested if's and decision bitfields.
|
||||||
The threshold is compared against a calculated estimation of if-s needed where
|
The threshold is compared against a calculated estimation of if-s needed where
|
||||||
every used bitmap divides the threshold by 2.
|
every used bitmap divides the threshold by 2.
|
||||||
|
.TP
|
||||||
|
\fIre2c:yych:conversion\fP \fB=\fP 0 \fB;\fP
|
||||||
|
When the input uses signed characters and \fB-s\fP or \fB-b\fP switches are
|
||||||
|
in effect re2c allows to automatically convert to the unsigned character type
|
||||||
|
that is then necessary for its internal single character. When this setting
|
||||||
|
is zero or an empty string the conversion is disabled. Using a non zero number
|
||||||
|
the conversion is taken from \fBYYCTYPE\fP. If that is given by an inplace
|
||||||
|
configuration that value is being used. Otherwise it will be \fB(YYCTYPE)\fP
|
||||||
|
and changes to that configuration are no longer possible. When this setting is
|
||||||
|
a string the braces must be specified. Now assuming your input is a \fBchar*\fP
|
||||||
|
buffer and you are using above mentioned switches you can set \fBYYCTYPE\fP to
|
||||||
|
\fBunsigned char\fP and this setting to either \fB1\fP or \fB"(unsigned char)"\fP.
|
||||||
|
.TP
|
||||||
|
\fIre2c:define:YYCTXMARKER\fP \fB=\fP YYCTXMARKER \fB;\fP
|
||||||
|
Allows to overwrite the define YYCTXMARKER and thus avoiding it by setting the
|
||||||
|
value to the actual code needed.
|
||||||
|
.TP
|
||||||
|
\fIre2c:define:YYCTYPE\fP \fB=\fP YYCTYPE \fB;\fP
|
||||||
|
Allows to overwrite the define YYCTYPE and thus avoiding it by setting the
|
||||||
|
value to the actual code needed.
|
||||||
|
.TP
|
||||||
|
\fIre2c:define:YYCURSOR\fP \fB=\fP YYCURSOR \fB;\fP
|
||||||
|
Allows to overwrite the define YYCURSOR and thus avoiding it by setting the
|
||||||
|
value to the actual code needed.
|
||||||
|
.TP
|
||||||
|
\fIre2c:define:YYDEBUG\fP \fB=\fP YYDEBUG \fB;\fP
|
||||||
|
Allows to overwrite the define YYDEBUG and thus avoiding it by setting the
|
||||||
|
value to the actual code needed.
|
||||||
|
.TP
|
||||||
|
\fIre2c:define:YYFILL\fP \fB=\fP YYFILL \fB;\fP
|
||||||
|
Allows to overwrite the define YYFILL and thus avoiding it by setting the
|
||||||
|
value to the actual code needed.
|
||||||
|
.TP
|
||||||
|
\fIre2c:define:YYGETSTATE\fP \fB=\fP YYGETSTATE \fB;\fP
|
||||||
|
Allows to overwrite the define YYGETSTATE and thus avoiding it by setting the
|
||||||
|
value to the actual code needed.
|
||||||
|
.TP
|
||||||
|
\fIre2c:define:YYLIMIT\fP \fB=\fP YYLIMIT \fB;\fP
|
||||||
|
Allows to overwrite the define YYLIMIT and thus avoiding it by setting the
|
||||||
|
value to the actual code needed.
|
||||||
|
.TP
|
||||||
|
\fIre2c:define:YYMARKER\fP \fB=\fP YYMARKER \fB;\fP
|
||||||
|
Allows to overwrite the define YYMARKER and thus avoiding it by setting the
|
||||||
|
value to the actual code needed.
|
||||||
|
.TP
|
||||||
|
\fIre2c:define:YYSETSTATE\fP \fB=\fP YYSETSTATE \fB;\fP
|
||||||
|
Allows to overwrite the define YYSETSTATE and thus avoiding it by setting the
|
||||||
|
value to the actual code needed.
|
||||||
|
.TP
|
||||||
|
\fIre2c:label:yyFillLabel\fP \fB=\fP yyFillLabel \fB;\fP
|
||||||
|
Allows to overwrite the name of the label yyFillLabel.
|
||||||
|
.TP
|
||||||
|
\fIre2c:label:yyNext\fP \fB=\fP yyNext \fB;\fP
|
||||||
|
Allows to overwrite the name of the label yyNext.
|
||||||
|
.TP
|
||||||
|
\fIre2c:variable:yyaccept\fP \fB=\fP yyaccept \fB;\fP
|
||||||
|
Allows to overwrite the name of the variable yyaccept.
|
||||||
|
.TP
|
||||||
|
\fIre2c:variable:yybm\fP \fB=\fP yybm \fB;\fP
|
||||||
|
Allows to overwrite the name of the variable yybm.
|
||||||
|
.TP
|
||||||
|
\fIre2c:variable:yych\fP \fB=\fP yych \fB;\fP
|
||||||
|
Allows to overwrite the name of the variable yych.
|
||||||
|
.TP
|
||||||
|
\fIre2c:variable:yytarget\fP \fB=\fP yytarget \fB;\fP
|
||||||
|
Allows to overwrite the name of the variable yytarget.
|
||||||
|
|
||||||
.SH "UNDERSTANDING RE2C"
|
.SH "UNDERSTANDING RE2C"
|
||||||
.LP
|
.LP
|
||||||
The subdirectory lessons of the re2c distribution contains a few step by step
|
The subdirectory lessons of the \*(re distribution contains a few step by step
|
||||||
lessons to get you started with re2c. All examples in the lessons subdirectory
|
lessons to get you started with \*(re. All examples in the lessons subdirectory
|
||||||
can be compiled and actually work.
|
can be compiled and actually work.
|
||||||
|
|
||||||
.SH FEATURES
|
.SH FEATURES
|
||||||
|
@ -487,10 +568,10 @@ The \*(re internal algorithms need documentation.
|
||||||
.LP
|
.LP
|
||||||
flex(1), lex(1).
|
flex(1), lex(1).
|
||||||
.P
|
.P
|
||||||
More information on \fBre2c\fP can be found here:
|
More information on \*(re can be found here:
|
||||||
.PD 0
|
.PD 0
|
||||||
.P
|
.P
|
||||||
.B http://sourceforge.net/projects/re2c/
|
.B http://re2c.org/
|
||||||
.PD 1
|
.PD 1
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
|
@ -511,6 +592,6 @@ Emmanuel Mogenet <mgix@mgix.com> added storable state
|
||||||
.PD 1
|
.PD 1
|
||||||
|
|
||||||
.SH VERSION INFORMATION
|
.SH VERSION INFORMATION
|
||||||
This manpage describes \fBre2c\fP, version 0.10.5.
|
This manpage describes \*(re, version 0.12.3.
|
||||||
|
|
||||||
.fi
|
.fi
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,373 +1,373 @@
|
||||||
/* $Id:$ */
|
/* $Id: scanner.re 663 2007-04-01 11:22:15Z helly $ */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "y.tab.h"
|
#include "y.tab.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "dfa.h"
|
#include "dfa.h"
|
||||||
|
|
||||||
extern YYSTYPE yylval;
|
extern YYSTYPE yylval;
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BSIZE 8192
|
#define BSIZE 8192
|
||||||
|
|
||||||
#define YYCTYPE unsigned char
|
#define YYCTYPE unsigned char
|
||||||
#define YYCURSOR cursor
|
#define YYCURSOR cursor
|
||||||
#define YYLIMIT lim
|
#define YYLIMIT lim
|
||||||
#define YYMARKER ptr
|
#define YYMARKER ptr
|
||||||
#define YYFILL(n) {cursor = fill(cursor);}
|
#define YYFILL(n) {cursor = fill(cursor);}
|
||||||
|
|
||||||
#define RETURN(i) {cur = cursor; return i;}
|
#define RETURN(i) {cur = cursor; return i;}
|
||||||
|
|
||||||
namespace re2c
|
namespace re2c
|
||||||
{
|
{
|
||||||
|
|
||||||
Scanner::Scanner(const char *fn, std::istream& i, std::ostream& o)
|
Scanner::Scanner(const char *fn, std::istream& i, std::ostream& o)
|
||||||
: in(i)
|
: in(i)
|
||||||
, out(o)
|
, out(o)
|
||||||
, bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL)
|
, bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL)
|
||||||
, top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0), filename(fn)
|
, top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0), filename(fn)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *Scanner::fill(char *cursor)
|
char *Scanner::fill(char *cursor)
|
||||||
{
|
{
|
||||||
if(!eof)
|
if(!eof)
|
||||||
{
|
{
|
||||||
uint cnt = tok - bot;
|
uint cnt = tok - bot;
|
||||||
if(cnt)
|
if(cnt)
|
||||||
{
|
{
|
||||||
memcpy(bot, tok, lim - tok);
|
memcpy(bot, tok, lim - tok);
|
||||||
tok = bot;
|
tok = bot;
|
||||||
ptr -= cnt;
|
ptr -= cnt;
|
||||||
cursor -= cnt;
|
cursor -= cnt;
|
||||||
pos -= cnt;
|
pos -= cnt;
|
||||||
lim -= cnt;
|
lim -= cnt;
|
||||||
}
|
}
|
||||||
if((top - lim) < BSIZE)
|
if((top - lim) < BSIZE)
|
||||||
{
|
{
|
||||||
char *buf = new char[(lim - bot) + BSIZE];
|
char *buf = new char[(lim - bot) + BSIZE];
|
||||||
memcpy(buf, tok, lim - tok);
|
memcpy(buf, tok, lim - tok);
|
||||||
tok = buf;
|
tok = buf;
|
||||||
ptr = &buf[ptr - bot];
|
ptr = &buf[ptr - bot];
|
||||||
cursor = &buf[cursor - bot];
|
cursor = &buf[cursor - bot];
|
||||||
pos = &buf[pos - bot];
|
pos = &buf[pos - bot];
|
||||||
lim = &buf[lim - bot];
|
lim = &buf[lim - bot];
|
||||||
top = &lim[BSIZE];
|
top = &lim[BSIZE];
|
||||||
delete [] bot;
|
delete [] bot;
|
||||||
bot = buf;
|
bot = buf;
|
||||||
}
|
}
|
||||||
in.read(lim, BSIZE);
|
in.read(lim, BSIZE);
|
||||||
if ((cnt = in.gcount()) != BSIZE )
|
if ((cnt = in.gcount()) != BSIZE )
|
||||||
{
|
{
|
||||||
eof = &lim[cnt]; *eof++ = '\0';
|
eof = &lim[cnt]; *eof++ = '\0';
|
||||||
}
|
}
|
||||||
lim += cnt;
|
lim += cnt;
|
||||||
}
|
}
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!re2c
|
/*!re2c
|
||||||
zero = "\000";
|
zero = "\000";
|
||||||
any = [\000-\377];
|
any = [\000-\377];
|
||||||
dot = any \ [\n];
|
dot = any \ [\n];
|
||||||
esc = dot \ [\\];
|
esc = dot \ [\\];
|
||||||
istring = "[" "^" ((esc \ [\]]) | "\\" dot)* "]" ;
|
istring = "[" "^" ((esc \ [\]]) | "\\" dot)* "]" ;
|
||||||
cstring = "[" ((esc \ [\]]) | "\\" dot)* "]" ;
|
cstring = "[" ((esc \ [\]]) | "\\" dot)* "]" ;
|
||||||
dstring = "\"" ((esc \ ["] ) | "\\" dot)* "\"";
|
dstring = "\"" ((esc \ ["] ) | "\\" dot)* "\"";
|
||||||
sstring = "'" ((esc \ ['] ) | "\\" dot)* "'" ;
|
sstring = "'" ((esc \ ['] ) | "\\" dot)* "'" ;
|
||||||
letter = [a-zA-Z];
|
letter = [a-zA-Z];
|
||||||
digit = [0-9];
|
digit = [0-9];
|
||||||
number = "0" | ("-"? [1-9] digit*);
|
number = "0" | ("-"? [1-9] digit*);
|
||||||
name = (letter|"_") (letter|digit|"_")*;
|
name = (letter|"_") (letter|digit|"_")*;
|
||||||
cname = ":" name;
|
cname = ":" name;
|
||||||
space = [ \t];
|
space = [ \t];
|
||||||
eol = ("\r\n" | "\n");
|
eol = ("\r\n" | "\n");
|
||||||
config = "re2c" cname+;
|
config = "re2c" cname+;
|
||||||
value = [^\r\n; \t]* | dstring | sstring;
|
value = [^\r\n; \t]* | dstring | sstring;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Scanner::echo()
|
int Scanner::echo()
|
||||||
{
|
{
|
||||||
char *cursor = cur;
|
char *cursor = cur;
|
||||||
bool ignore_eoc = false;
|
bool ignore_eoc = false;
|
||||||
int ignore_cnt = 0;
|
int ignore_cnt = 0;
|
||||||
|
|
||||||
if (eof && cursor == eof) // Catch EOF
|
if (eof && cursor == eof) // Catch EOF
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tok = cursor;
|
tok = cursor;
|
||||||
echo:
|
echo:
|
||||||
/*!re2c
|
/*!re2c
|
||||||
"/*!re2c" {
|
"/*!re2c" {
|
||||||
if (bUsedYYMaxFill && bSinglePass) {
|
if (bUsedYYMaxFill && bSinglePass) {
|
||||||
fatal("found scanner block after YYMAXFILL declaration");
|
fatal("found scanner block after YYMAXFILL declaration");
|
||||||
}
|
}
|
||||||
out.write((const char*)(tok), (const char*)(&cursor[-7]) - (const char*)(tok));
|
out.write((const char*)(tok), (const char*)(&cursor[-7]) - (const char*)(tok));
|
||||||
tok = cursor;
|
tok = cursor;
|
||||||
RETURN(1);
|
RETURN(1);
|
||||||
}
|
}
|
||||||
"/*!max:re2c" {
|
"/*!max:re2c" {
|
||||||
if (bUsedYYMaxFill) {
|
if (bUsedYYMaxFill) {
|
||||||
fatal("cannot generate YYMAXFILL twice");
|
fatal("cannot generate YYMAXFILL twice");
|
||||||
}
|
}
|
||||||
out << "#define YYMAXFILL " << maxFill << std::endl;
|
out << "#define YYMAXFILL " << maxFill << std::endl;
|
||||||
tok = pos = cursor;
|
tok = pos = cursor;
|
||||||
ignore_eoc = true;
|
ignore_eoc = true;
|
||||||
bUsedYYMaxFill = true;
|
bUsedYYMaxFill = true;
|
||||||
goto echo;
|
goto echo;
|
||||||
}
|
}
|
||||||
"/*!getstate:re2c" {
|
"/*!getstate:re2c" {
|
||||||
tok = pos = cursor;
|
tok = pos = cursor;
|
||||||
genGetState(out, topIndent, 0);
|
genGetState(out, topIndent, 0);
|
||||||
ignore_eoc = true;
|
ignore_eoc = true;
|
||||||
goto echo;
|
goto echo;
|
||||||
}
|
}
|
||||||
"/*!ignore:re2c" {
|
"/*!ignore:re2c" {
|
||||||
tok = pos = cursor;
|
tok = pos = cursor;
|
||||||
ignore_eoc = true;
|
ignore_eoc = true;
|
||||||
goto echo;
|
goto echo;
|
||||||
}
|
}
|
||||||
"*" "/" "\r"? "\n" {
|
"*" "/" "\r"? "\n" {
|
||||||
cline++;
|
cline++;
|
||||||
if (ignore_eoc) {
|
if (ignore_eoc) {
|
||||||
if (ignore_cnt) {
|
if (ignore_cnt) {
|
||||||
out << sourceFileInfo;
|
out << sourceFileInfo;
|
||||||
}
|
}
|
||||||
ignore_eoc = false;
|
ignore_eoc = false;
|
||||||
ignore_cnt = 0;
|
ignore_cnt = 0;
|
||||||
} else {
|
} else {
|
||||||
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
|
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
|
||||||
}
|
}
|
||||||
tok = pos = cursor;
|
tok = pos = cursor;
|
||||||
goto echo;
|
goto echo;
|
||||||
}
|
}
|
||||||
"*" "/" {
|
"*" "/" {
|
||||||
if (ignore_eoc) {
|
if (ignore_eoc) {
|
||||||
if (ignore_cnt) {
|
if (ignore_cnt) {
|
||||||
out << "\n" << sourceFileInfo;
|
out << "\n" << sourceFileInfo;
|
||||||
}
|
}
|
||||||
ignore_eoc = false;
|
ignore_eoc = false;
|
||||||
ignore_cnt = 0;
|
ignore_cnt = 0;
|
||||||
} else {
|
} else {
|
||||||
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
|
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
|
||||||
}
|
}
|
||||||
tok = pos = cursor;
|
tok = pos = cursor;
|
||||||
goto echo;
|
goto echo;
|
||||||
}
|
}
|
||||||
"\n" {
|
"\n" {
|
||||||
if (ignore_eoc) {
|
if (ignore_eoc) {
|
||||||
ignore_cnt++;
|
ignore_cnt++;
|
||||||
} else {
|
} else {
|
||||||
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
|
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
|
||||||
}
|
}
|
||||||
tok = pos = cursor; cline++;
|
tok = pos = cursor; cline++;
|
||||||
goto echo;
|
goto echo;
|
||||||
}
|
}
|
||||||
zero {
|
zero {
|
||||||
if (!ignore_eoc) {
|
if (!ignore_eoc) {
|
||||||
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok) - 1); // -1 so we don't write out the \0
|
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok) - 1); // -1 so we don't write out the \0
|
||||||
}
|
}
|
||||||
if(cursor == eof) {
|
if(cursor == eof) {
|
||||||
RETURN(0);
|
RETURN(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
any {
|
any {
|
||||||
goto echo;
|
goto echo;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Scanner::scan()
|
int Scanner::scan()
|
||||||
{
|
{
|
||||||
char *cursor = cur;
|
char *cursor = cur;
|
||||||
uint depth;
|
uint depth;
|
||||||
|
|
||||||
scan:
|
scan:
|
||||||
tchar = cursor - pos;
|
tchar = cursor - pos;
|
||||||
tline = cline;
|
tline = cline;
|
||||||
tok = cursor;
|
tok = cursor;
|
||||||
if (iscfg == 1)
|
if (iscfg == 1)
|
||||||
{
|
{
|
||||||
goto config;
|
goto config;
|
||||||
}
|
}
|
||||||
else if (iscfg == 2)
|
else if (iscfg == 2)
|
||||||
{
|
{
|
||||||
goto value;
|
goto value;
|
||||||
}
|
}
|
||||||
/*!re2c
|
/*!re2c
|
||||||
"{" { depth = 1;
|
"{" { depth = 1;
|
||||||
goto code;
|
goto code;
|
||||||
}
|
}
|
||||||
"/*" { depth = 1;
|
"/*" { depth = 1;
|
||||||
goto comment; }
|
goto comment; }
|
||||||
|
|
||||||
"*/" { tok = cursor;
|
"*/" { tok = cursor;
|
||||||
RETURN(0); }
|
RETURN(0); }
|
||||||
|
|
||||||
dstring { cur = cursor;
|
dstring { cur = cursor;
|
||||||
yylval.regexp = strToRE(token());
|
yylval.regexp = strToRE(token());
|
||||||
return STRING; }
|
return STRING; }
|
||||||
|
|
||||||
sstring { cur = cursor;
|
sstring { cur = cursor;
|
||||||
yylval.regexp = strToCaseInsensitiveRE(token());
|
yylval.regexp = strToCaseInsensitiveRE(token());
|
||||||
return STRING; }
|
return STRING; }
|
||||||
|
|
||||||
"\"" { fatal("unterminated string constant (missing \")"); }
|
"\"" { fatal("unterminated string constant (missing \")"); }
|
||||||
"'" { fatal("unterminated string constant (missing ')"); }
|
"'" { fatal("unterminated string constant (missing ')"); }
|
||||||
|
|
||||||
istring { cur = cursor;
|
istring { cur = cursor;
|
||||||
yylval.regexp = invToRE(token());
|
yylval.regexp = invToRE(token());
|
||||||
return RANGE; }
|
return RANGE; }
|
||||||
|
|
||||||
cstring { cur = cursor;
|
cstring { cur = cursor;
|
||||||
yylval.regexp = ranToRE(token());
|
yylval.regexp = ranToRE(token());
|
||||||
return RANGE; }
|
return RANGE; }
|
||||||
|
|
||||||
"[" { fatal("unterminated range (missing ])"); }
|
"[" { fatal("unterminated range (missing ])"); }
|
||||||
|
|
||||||
[()|=;/\\] { RETURN(*tok); }
|
[()|=;/\\] { RETURN(*tok); }
|
||||||
|
|
||||||
[*+?] { yylval.op = *tok;
|
[*+?] { yylval.op = *tok;
|
||||||
RETURN(CLOSE); }
|
RETURN(CLOSE); }
|
||||||
|
|
||||||
"{0,}" { yylval.op = '*';
|
"{0,}" { yylval.op = '*';
|
||||||
RETURN(CLOSE); }
|
RETURN(CLOSE); }
|
||||||
|
|
||||||
"{" [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
|
"{" [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
|
||||||
yylval.extop.maxsize = atoi((char *)tok+1);
|
yylval.extop.maxsize = atoi((char *)tok+1);
|
||||||
RETURN(CLOSESIZE); }
|
RETURN(CLOSESIZE); }
|
||||||
|
|
||||||
"{" [0-9]+ "," [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
|
"{" [0-9]+ "," [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
|
||||||
yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
|
yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
|
||||||
RETURN(CLOSESIZE); }
|
RETURN(CLOSESIZE); }
|
||||||
|
|
||||||
"{" [0-9]+ ",}" { yylval.extop.minsize = atoi((char *)tok+1);
|
"{" [0-9]+ ",}" { yylval.extop.minsize = atoi((char *)tok+1);
|
||||||
yylval.extop.maxsize = -1;
|
yylval.extop.maxsize = -1;
|
||||||
RETURN(CLOSESIZE); }
|
RETURN(CLOSESIZE); }
|
||||||
|
|
||||||
"{" [0-9]* "," { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); }
|
"{" [0-9]* "," { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); }
|
||||||
|
|
||||||
config { cur = cursor;
|
config { cur = cursor;
|
||||||
tok+= 5; /* skip "re2c:" */
|
tok+= 5; /* skip "re2c:" */
|
||||||
iscfg = 1;
|
iscfg = 1;
|
||||||
yylval.str = new Str(token());
|
yylval.str = new Str(token());
|
||||||
return CONFIG;
|
return CONFIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
name { cur = cursor;
|
name { cur = cursor;
|
||||||
yylval.symbol = Symbol::find(token());
|
yylval.symbol = Symbol::find(token());
|
||||||
return ID; }
|
return ID; }
|
||||||
|
|
||||||
"." { cur = cursor;
|
"." { cur = cursor;
|
||||||
yylval.regexp = mkDot();
|
yylval.regexp = mkDot();
|
||||||
return RANGE;
|
return RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
space+ { goto scan; }
|
space+ { goto scan; }
|
||||||
|
|
||||||
eol { if(cursor == eof) RETURN(0);
|
eol { if(cursor == eof) RETURN(0);
|
||||||
pos = cursor; cline++;
|
pos = cursor; cline++;
|
||||||
goto scan;
|
goto scan;
|
||||||
}
|
}
|
||||||
|
|
||||||
any { std::ostringstream msg;
|
any { std::ostringstream msg;
|
||||||
msg << "unexpected character: ";
|
msg << "unexpected character: ";
|
||||||
prtChOrHex(msg, *tok);
|
prtChOrHex(msg, *tok);
|
||||||
fatal(msg.str().c_str());
|
fatal(msg.str().c_str());
|
||||||
goto scan;
|
goto scan;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
code:
|
code:
|
||||||
/*!re2c
|
/*!re2c
|
||||||
"}" { if(--depth == 0){
|
"}" { if(--depth == 0){
|
||||||
cur = cursor;
|
cur = cursor;
|
||||||
yylval.token = new Token(token(), tline);
|
yylval.token = new Token(token(), tline);
|
||||||
return CODE;
|
return CODE;
|
||||||
}
|
}
|
||||||
goto code; }
|
goto code; }
|
||||||
"{" { ++depth;
|
"{" { ++depth;
|
||||||
goto code; }
|
goto code; }
|
||||||
"\n" { if(cursor == eof) fatal("missing '}'");
|
"\n" { if(cursor == eof) fatal("missing '}'");
|
||||||
pos = cursor; cline++;
|
pos = cursor; cline++;
|
||||||
goto code;
|
goto code;
|
||||||
}
|
}
|
||||||
zero { if(cursor == eof) {
|
zero { if(cursor == eof) {
|
||||||
if (depth) fatal("missing '}'");
|
if (depth) fatal("missing '}'");
|
||||||
RETURN(0);
|
RETURN(0);
|
||||||
}
|
}
|
||||||
goto code;
|
goto code;
|
||||||
}
|
}
|
||||||
dstring | sstring | any { goto code; }
|
dstring | sstring | any { goto code; }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
comment:
|
comment:
|
||||||
/*!re2c
|
/*!re2c
|
||||||
"*/" { if(--depth == 0)
|
"*/" { if(--depth == 0)
|
||||||
goto scan;
|
goto scan;
|
||||||
else
|
else
|
||||||
goto comment; }
|
goto comment; }
|
||||||
"/*" { ++depth;
|
"/*" { ++depth;
|
||||||
fatal("ambiguous /* found");
|
fatal("ambiguous /* found");
|
||||||
goto comment; }
|
goto comment; }
|
||||||
"\n" { if(cursor == eof) RETURN(0);
|
"\n" { if(cursor == eof) RETURN(0);
|
||||||
tok = pos = cursor; cline++;
|
tok = pos = cursor; cline++;
|
||||||
goto comment;
|
goto comment;
|
||||||
}
|
}
|
||||||
any { if(cursor == eof) RETURN(0);
|
any { if(cursor == eof) RETURN(0);
|
||||||
goto comment; }
|
goto comment; }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
config:
|
config:
|
||||||
/*!re2c
|
/*!re2c
|
||||||
space+ { goto config; }
|
space+ { goto config; }
|
||||||
"=" space* { iscfg = 2;
|
"=" space* { iscfg = 2;
|
||||||
cur = cursor;
|
cur = cursor;
|
||||||
RETURN('=');
|
RETURN('=');
|
||||||
}
|
}
|
||||||
any { fatal("missing '='"); }
|
any { fatal("missing '='"); }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
value:
|
value:
|
||||||
/*!re2c
|
/*!re2c
|
||||||
number { cur = cursor;
|
number { cur = cursor;
|
||||||
yylval.number = atoi(token().to_string().c_str());
|
yylval.number = atoi(token().to_string().c_str());
|
||||||
iscfg = 0;
|
iscfg = 0;
|
||||||
return NUMBER;
|
return NUMBER;
|
||||||
}
|
}
|
||||||
value { cur = cursor;
|
value { cur = cursor;
|
||||||
yylval.str = new Str(token());
|
yylval.str = new Str(token());
|
||||||
iscfg = 0;
|
iscfg = 0;
|
||||||
return VALUE;
|
return VALUE;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scanner::fatal(uint ofs, const char *msg) const
|
void Scanner::fatal(uint ofs, const char *msg) const
|
||||||
{
|
{
|
||||||
out.flush();
|
out.flush();
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
std::cerr << filename << "(" << tline << "): error : "
|
std::cerr << filename << "(" << tline << "): error : "
|
||||||
<< "column " << (tchar + ofs + 1) << ": "
|
<< "column " << (tchar + ofs + 1) << ": "
|
||||||
<< msg << std::endl;
|
<< msg << std::endl;
|
||||||
#else
|
#else
|
||||||
std::cerr << "re2c: error: "
|
std::cerr << "re2c: error: "
|
||||||
<< "line " << tline << ", column " << (tchar + ofs + 1) << ": "
|
<< "line " << tline << ", column " << (tchar + ofs + 1) << ": "
|
||||||
<< msg << std::endl;
|
<< msg << std::endl;
|
||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scanner::~Scanner()
|
Scanner::~Scanner()
|
||||||
{
|
{
|
||||||
|
@ -376,6 +376,6 @@ Scanner::~Scanner()
|
||||||
delete [] bot;
|
delete [] bot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace re2c
|
} // end namespace re2c
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Author: Marcus Boerger <helly@users.sourceforge.net>
|
Author: Marcus Boerger <helly@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: stream_lc.h,v 1.10 2006/02/26 20:36:09 helly Exp $ */
|
/* $Id: stream_lc.h 767 2007-06-26 15:21:10Z helly $ */
|
||||||
|
|
||||||
#ifndef _stream_lc_h
|
#ifndef _stream_lc_h
|
||||||
#define _stream_lc_h
|
#define _stream_lc_h
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: substr.cc,v 1.11 2006/02/26 20:30:54 helly Exp $ */
|
/* $Id: substr.cc 546 2006-05-25 13:40:14Z helly $ */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "substr.h"
|
#include "substr.h"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: substr.h,v 1.10 2006/01/01 13:42:10 helly Exp $ */
|
/* $Id: substr.h 530 2006-05-25 13:34:33Z helly $ */
|
||||||
#ifndef _substr_h
|
#ifndef _substr_h
|
||||||
#define _substr_h
|
#define _substr_h
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: token.h,v 1.4 2004/11/01 04:35:57 nuffer Exp $ */
|
/* $Id: token.h 547 2006-05-25 13:40:35Z helly $ */
|
||||||
#ifndef _token_h
|
#ifndef _token_h
|
||||||
#define _token_h
|
#define _token_h
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: translate.cc,v 1.5 2005/12/28 18:33:37 helly Exp $ */
|
/* $Id: translate.cc 713 2007-04-29 15:33:47Z helly $ */
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
namespace re2c
|
namespace re2c
|
||||||
|
|
|
@ -250,7 +250,7 @@ int main (int argc, char **argv)
|
||||||
printf ("Usage: %s <source file> <output file>\n", argv[0]);
|
printf ("Usage: %s <source file> <output file>\n", argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#if !defined(NDEBUG) && 1
|
#if !defined(NDEBUG) && 0
|
||||||
ParseTrace(fopen("trace.txt", "w"), ":");
|
ParseTrace(fopen("trace.txt", "w"), ":");
|
||||||
#endif
|
#endif
|
||||||
IncludeFile (argv[1]);
|
IncludeFile (argv[1]);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,27 +10,28 @@
|
||||||
#define SYMNUM 10
|
#define SYMNUM 10
|
||||||
#define LPAREN 11
|
#define LPAREN 11
|
||||||
#define RPAREN 12
|
#define RPAREN 12
|
||||||
#define PRINT 13
|
#define NOP 13
|
||||||
#define COMMA 14
|
#define PRINT 14
|
||||||
#define STRING 15
|
#define COMMA 15
|
||||||
#define ENDL 16
|
#define STRING 16
|
||||||
#define DEFINE 17
|
#define ENDL 17
|
||||||
#define SYM 18
|
#define DEFINE 18
|
||||||
#define INCLUDE 19
|
#define SYM 19
|
||||||
#define RBRACE 20
|
#define INCLUDE 20
|
||||||
#define ENUM 21
|
#define RBRACE 21
|
||||||
#define LBRACE 22
|
#define ENUM 22
|
||||||
#define EQUALS 23
|
#define LBRACE 23
|
||||||
#define SPECIAL 24
|
#define EQUALS 24
|
||||||
#define SEMICOLON 25
|
#define SPECIAL 25
|
||||||
#define COLON 26
|
#define SEMICOLON 26
|
||||||
#define LBRACKET 27
|
#define COLON 27
|
||||||
#define RBRACKET 28
|
#define LBRACKET 28
|
||||||
#define FLAGS 29
|
#define RBRACKET 29
|
||||||
#define ARG2 30
|
#define FLAGS 30
|
||||||
#define ARG3 31
|
#define ARG2 31
|
||||||
#define ARG4 32
|
#define ARG3 32
|
||||||
#define ARG5 33
|
#define ARG4 33
|
||||||
#define OR_EQUAL 34
|
#define ARG5 34
|
||||||
#define TAG 35
|
#define OR_EQUAL 35
|
||||||
#define LINEID 36
|
#define TAG 36
|
||||||
|
#define LINEID 37
|
||||||
|
|
|
@ -243,10 +243,33 @@ void yyparse (void)
|
||||||
void *pParser = ParseAlloc (malloc);
|
void *pParser = ParseAlloc (malloc);
|
||||||
YYSTYPE token;
|
YYSTYPE token;
|
||||||
int tokentype;
|
int tokentype;
|
||||||
|
int include_state = 0;
|
||||||
|
|
||||||
while ((tokentype = yylex(&token)) != 0)
|
while ((tokentype = yylex(&token)) != 0)
|
||||||
{
|
{
|
||||||
|
/* Whenever the sequence INCLUDE STRING is encountered in the token
|
||||||
|
* stream, feed a dummy NOP token to the parser so that it will
|
||||||
|
* reduce the include_statement before grabbing any more tokens
|
||||||
|
* from the current file.
|
||||||
|
*/
|
||||||
|
if (tokentype == INCLUDE && include_state == 0)
|
||||||
|
{
|
||||||
|
include_state = 1;
|
||||||
|
}
|
||||||
|
else if (tokentype == STRING && include_state == 1)
|
||||||
|
{
|
||||||
|
include_state = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
include_state = 0;
|
||||||
|
}
|
||||||
Parse (pParser, tokentype, token);
|
Parse (pParser, tokentype, token);
|
||||||
|
if (include_state == 2)
|
||||||
|
{
|
||||||
|
include_state = 0;
|
||||||
|
Parse (pParser, NOP, token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memset (&token, 0, sizeof(token));
|
memset (&token, 0, sizeof(token));
|
||||||
Parse (pParser, 0, token);
|
Parse (pParser, 0, token);
|
||||||
|
@ -354,7 +377,7 @@ exp(A) ::= MINUS exp(B). [NEG] { A = -B; }
|
||||||
exp(A) ::= LPAREN exp(B) RPAREN. { A = B; }
|
exp(A) ::= LPAREN exp(B) RPAREN. { A = B; }
|
||||||
|
|
||||||
translation_unit ::= . /* empty */
|
translation_unit ::= . /* empty */
|
||||||
translation_unit ::= external_declaration.
|
translation_unit ::= translation_unit external_declaration.
|
||||||
|
|
||||||
external_declaration ::= define_statement.
|
external_declaration ::= define_statement.
|
||||||
external_declaration ::= include_statement.
|
external_declaration ::= include_statement.
|
||||||
|
@ -363,6 +386,7 @@ external_declaration ::= enum_statement.
|
||||||
external_declaration ::= linetype_declaration.
|
external_declaration ::= linetype_declaration.
|
||||||
external_declaration ::= boom_declaration.
|
external_declaration ::= boom_declaration.
|
||||||
external_declaration ::= special_declaration.
|
external_declaration ::= special_declaration.
|
||||||
|
external_declaration ::= NOP.
|
||||||
|
|
||||||
print_statement ::= PRINT LPAREN print_list RPAREN.
|
print_statement ::= PRINT LPAREN print_list RPAREN.
|
||||||
{
|
{
|
||||||
|
|
Binary file not shown.
BIN
wadsrc/doomx.lmp
BIN
wadsrc/doomx.lmp
Binary file not shown.
BIN
wadsrc/foo
BIN
wadsrc/foo
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3696,7 +3696,7 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
Description="Creating $(InputName).h from src/$(InputFileName)"
|
Description="Creating $(InputName).h from src/$(InputFileName)"
|
||||||
CommandLine="tools\re2c\re2c -s -o "src/$(InputName).h" "src/$(InputFileName)"
"
|
CommandLine="tools\re2c\re2c --no-generation-date -s -o "src/$(InputName).h" "src/$(InputFileName)"
"
|
||||||
Outputs=""src/$(InputName).h""
|
Outputs=""src/$(InputName).h""
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
|
@ -3716,7 +3716,7 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
Description="Creating $(InputName).h from src/$(InputFileName)"
|
Description="Creating $(InputName).h from src/$(InputFileName)"
|
||||||
CommandLine="tools\re2c\re2c -s -o "src/$(InputName).h" "src/$(InputFileName)"
"
|
CommandLine="tools\re2c\re2c --no-generation-date -s -o "src/$(InputName).h" "src/$(InputFileName)"
"
|
||||||
Outputs=""src/$(InputName).h""
|
Outputs=""src/$(InputName).h""
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
|
|
Loading…
Reference in a new issue