C语言写的一个parser 编译没问题 运行不能正常parse 求助!!!
// Grammar// SID a simple C identifier of unlimited length
// STRLIT is a simple C-type literal string string
// IEXPR is an integer expression
// strexpr: SID ( term ) | str
// term: str , term | str | str + str
// str: SID str1 | SID() str1 | STRLIT str1
// str1: [ content ] str1 | epsilon
// content: IEXPR | IEXPR : IEXPR | IEXPR : | : IEXPR
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define isliteral(x) ((x)=='\"')
#define isdigit(x) ((x)>='0'&&(x)<='9')
#define isfirst(x) (((x)>='A'&&(x)<='Z')||((x)>='a'&&(x)<='z')||((x)=='_'))
#define isnext(x) (isfirst(x)||((x)>='0'&&(x)<='9'))
#define isws(x) ((x)==' '||(x)=='\n'||(x)=='\t')
#define SavePosition() spp1 = spp
#define RestorePosition() spp = spp1
int spp;
unsigned long token_ival;
// define token names
#define EOI 0
#define SID 256
#define STRLIT SID+1
#define IEXPR STRLIT+1
#define ERR IEXPR+1
//function Parse
int Parse(char* s){
int token,spp2;
spp=0;
if(!strexpr(s)){
return 0;
}
spp2=spp;
token=NextToken(s);
if(token==ERR){
printf("Error occurred at position %d\n",spp2);
exit(1);
}
if(token!=EOI){
printf("Reduntant stuff at position %d\n",spp2);
exit(1);
}
return 1;
}//end Parse
//strexpr: SID ( term ) | str
int strexpr(char* s){
int spp1,spp2,token;
spp1=0;
SavePosition();
token=NextToken(s);
if(token==SID){
token=NextToken(s);
if (token=='('){
if (!term(s)){
RestorePosition();
return 0;
}
spp2=spp;
if(NextToken(s)!=')'){
printf("Expected token ) at position %d\n",spp2);
exit(1);
}
return 1;
}
RestorePosition();
return 0;
}
RestorePosition();
if(!str(s)){
RestorePosition();
return 0;
}
return 1;
}//end strexpr
// term: str , term | str | str + str
int term(char* s){
int spp1,spp2,token;
spp1=0;
SavePosition();
if(!str(s)){
RestorePosition();
return 0;
}
spp2=spp;
token=NextToken(s);
if(token==','){
if (!term(s)){
RestorePosition();
return 0;
}
return 1;
}
if(token=='+'){
if (!str(s)){
RestorePosition();
return 0;
}
return 1;
}
spp=spp2;
return 1;
}//end term
// str: SID str1 | SID() str1 | STRLIT str1
int str(char* s){
int spp1,spp2,token;
spp2=0;
SavePosition();
token=NextToken(s);
if(token==SID){
spp2=spp;
token=NextToken(s);
if(token=='('){
token=NextToken(s);
if(token==')'){
if(!str1(s)){
RestorePosition();
return 0;
}
return 1;
}
spp=spp2;
return 0;
}
spp=spp2;
if(!str1(s)){
RestorePosition();
return 0;
}
return 1;
}
//RestorePosition();
//token=NextToken(s);
if(token==STRLIT){
if(!str1(s)){
RestorePosition();
return 0;
}
return 1;
}
//RestorePosition();
return 0;
}//end str
// str1: [ content ] str1 | epsilon
int str1(char* s){
int spp1,token;
SavePosition();
token=NextToken(s);
if(token=='['){
if(!content(s)){
RestorePosition();
return 1;
}
token=NextToken(s);
if(token==']'){
if(!str(s)){
RestorePosition();
return 1;
}
return 1;
}
//RestorePosition();
return 1;
}
//RestorePosition();
return 1;
}//end str1
// content: IEXPR | IEXPR : IEXPR | IEXPR : | : IEXPR
int content(char* s){
int spp1,spp2,spp3,spp4,token;
SavePosition();
token=NextToken(s);
if(token==IEXPR){
spp2=spp;
token=NextToken(s);
if(token==':'){
spp3=spp;
token=NextToken(s);
if(token==IEXPR){
return 1;
}
spp=spp3;
return 1;
}
spp=spp2;
return 1;
}
//RestorePosition();
//token=NextToken(s);
if(token==':'){
spp4=spp;
token=NextToken(s);
if(token==IEXPR){
return 1;
}
printf("Expected token IEXPR at position %d\n",spp4);
exit(1);
}
if(token==EOI){
RestorePosition();
return 0;
}
printf("Expected token IEXPR or : at position %d\n",spp1);
exit(1);
}//end content
//function NextToken
int NextToken(char* s){
while(isws(s[spp])){
spp++; } //eat ws
if((s[spp])=='\0'){
spp++;
return EOI;
}else if(s[spp]==','){
spp++;
return ',';
}else if(s[spp]=='['){
spp++;
return '[';
}else if(s[spp]==']'){
spp++;
return ']';
}else if(s[spp]==':'){
spp++;
return ':';
}else if(s[spp]=='('){
spp++;
return '(';
}else if(s[spp]==')'){
spp++;
return ')';
}else if(s[spp]=='+'){
spp++;
return '+';
}else if(isfirst(s[spp])){
spp++; //eat first char
while(isnext(s[spp])){
spp++; //eat all the following char
return SID;
}
}else if(isliteral(s[spp])){
spp++; //eat "
while(isnext(s[spp])){
spp++; //eat all the following char except " in the end
if(isliteral(s[spp])){
spp++; //eat "
return STRLIT;
}
}
}else if(isdigit(s[spp])){
token_ival=(s[spp]-'0');
spp++; //eat first integer
while(isdigit(s[spp])){
token_ival=token_ival*10+(s[spp]-'0');
spp++; //eat all the following integers
}
return IEXPR;
}
return ERR;
}//end NextToken
int main()
{
char string[]="abc";
if (Parse(string)) {
printf("OK\n");
}else
printf("SYNTAX ERROR\n");
return 0;
}