mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +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]);
|
||||||
}
|
}
|
||||||
|
if( lemp->errsym->useCnt ){
|
||||||
fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++;
|
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++;
|
||||||
|
if( lemp->errsym->useCnt ){
|
||||||
fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
|
fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
|
||||||
fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,9 +350,7 @@ static int yy_find_shift_action(
|
||||||
if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
|
if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
|
||||||
return yy_default[stateno];
|
return yy_default[stateno];
|
||||||
}
|
}
|
||||||
if( iLookAhead==YYNOCODE ){
|
assert( iLookAhead!=YYNOCODE );
|
||||||
return YY_NO_ACTION;
|
|
||||||
}
|
|
||||||
i += iLookAhead;
|
i += iLookAhead;
|
||||||
if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
|
if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
|
||||||
if( iLookAhead>0 ){
|
if( iLookAhead>0 ){
|
||||||
|
@ -403,13 +401,18 @@ static int yy_find_reduce_action(
|
||||||
YYCODETYPE iLookAhead /* The look-ahead token */
|
YYCODETYPE iLookAhead /* The look-ahead token */
|
||||||
){
|
){
|
||||||
int i;
|
int i;
|
||||||
assert( stateno<=YY_REDUCE_MAX );
|
if( stateno>YY_REDUCE_MAX ||
|
||||||
i = yy_reduce_ofst[stateno];
|
(i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){
|
||||||
|
return yy_default[stateno];
|
||||||
|
}
|
||||||
assert( i!=YY_REDUCE_USE_DFLT );
|
assert( i!=YY_REDUCE_USE_DFLT );
|
||||||
assert( iLookAhead!=YYNOCODE );
|
assert( iLookAhead!=YYNOCODE );
|
||||||
i += iLookAhead;
|
i += iLookAhead;
|
||||||
assert( i>=0 && i<YY_SZ_ACTTAB );
|
if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
|
||||||
assert( yy_lookahead[i]==iLookAhead );
|
return yy_default[stateno];
|
||||||
|
}else{
|
||||||
|
return yy_action[i];
|
||||||
|
}
|
||||||
return yy_action[i];
|
return yy_action[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +469,7 @@ static void yy_shift(
|
||||||
fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
|
fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
|
||||||
fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
|
fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
|
||||||
for(i=1; i<=yypParser->yyidx; i++)
|
for(i=1; i<=yypParser->yyidx; i++)
|
||||||
fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
|
fprintf(yyTraceFILE," (%d)%s",yypParser->yystack[i].stateno,yyTokenName[yypParser->yystack[i].major]);
|
||||||
fprintf(yyTraceFILE,"\n");
|
fprintf(yyTraceFILE,"\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -679,14 +682,6 @@ void Parse(
|
||||||
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
|
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
|
||||||
yypParser->yyerrcnt--;
|
yypParser->yyerrcnt--;
|
||||||
yymajor = YYNOCODE;
|
yymajor = YYNOCODE;
|
||||||
/* [RH] If we can reduce the stack now, do it. Otherwise, constructs */
|
|
||||||
/* like "include <somefile>" won't work because the next token after */
|
|
||||||
/* the include will be shifted before the include is reduced. Then the */
|
|
||||||
/* parser will act as if that token had been the first one in the */
|
|
||||||
/* included file. */
|
|
||||||
while( yypParser->yyidx>= 0 && (yyact = yy_find_shift_action(yypParser,YYNOCODE)) < YYNSTATE + YYNRULE ){
|
|
||||||
yy_reduce(yypParser,yyact-YYNSTATE);
|
|
||||||
}
|
|
||||||
}else if( yyact < YYNSTATE + YYNRULE ){
|
}else if( yyact < YYNSTATE + YYNRULE ){
|
||||||
yy_reduce(yypParser,yyact-YYNSTATE);
|
yy_reduce(yypParser,yyact-YYNSTATE);
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -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,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.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: actions.cc,v 1.35 2006/02/25 12:57:50 helly Exp $ */
|
/* $Id: actions.cc 608 2006-11-05 00:48:30Z helly $ */
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: code.cc,v 1.74 2006/05/14 13:38:26 helly Exp $ */
|
/* $Id: code.cc 717 2007-04-29 22:29:59Z helly $ */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -331,7 +331,7 @@ static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMark
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o << indent(ind) << "if((YYLIMIT - YYCURSOR) < " << n << ") YYFILL(" << n << ");\n";
|
o << indent(ind) << "if((" << mapCodeName["YYLIMIT"] << " - " << mapCodeName["YYCURSOR"] << ") < " << n << ") " << mapCodeName["YYFILL"];
|
||||||
}
|
}
|
||||||
if (bUseYYFillParam)
|
if (bUseYYFillParam)
|
||||||
{
|
{
|
||||||
|
@ -1763,7 +1763,7 @@ void Scanner::config(const Str& cfg, const Str& val)
|
||||||
}
|
}
|
||||||
else if (cfg.to_string() == "startlabel")
|
else if (cfg.to_string() == "startlabel")
|
||||||
{
|
{
|
||||||
startLabelName = val.to_string();
|
startLabelName = strVal;
|
||||||
bUseStartLabel = !startLabelName.empty();
|
bUseStartLabel = !startLabelName.empty();
|
||||||
}
|
}
|
||||||
else if (cfg.to_string() == "labelprefix")
|
else if (cfg.to_string() == "labelprefix")
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $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
|
||||||
|
|
||||||
|
@ -105,6 +105,11 @@ public:
|
||||||
vFreeList.insert(this);
|
vFreeList.insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Range()
|
||||||
|
{
|
||||||
|
vFreeList.erase(this);
|
||||||
|
}
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream&, const Range&);
|
friend std::ostream& operator<<(std::ostream&, const Range&);
|
||||||
friend std::ostream& operator<<(std::ostream&, const Range*);
|
friend std::ostream& operator<<(std::ostream&, const Range*);
|
||||||
};
|
};
|
||||||
|
@ -125,6 +130,7 @@ public:
|
||||||
public:
|
public:
|
||||||
RegExp() : size(0)
|
RegExp() : size(0)
|
||||||
{
|
{
|
||||||
|
vFreeList.insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~RegExp()
|
virtual ~RegExp()
|
||||||
|
|
|
@ -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,4 +1,4 @@
|
||||||
/* $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>
|
||||||
|
|
|
@ -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