Dynamic PEG for interpreted languages.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

151 lignes
4.5 KiB

#include <stdio.h>
#include <stdlib.h>
void setBit(char *bits, int n)
{
bits[n/8] |= (1 << n%8);
}
int testBit(char *bits, int n)
{
return bits[n/8] & (1 << n%8);
}
int isEscapedChar(char char1, char char2){
if( char1=='\n'){
return 10;
}
if( char1=='\a'){
return 7;
}
if( char1=='\b'){
return 8;
}
if( char1=='\e'){
return 27;
}
if( char1=='\f'){
return 12;
}
if( char1=='\r'){
return 13;
}
else if( char1=='\t'){
return 9;
}
if( char1=='\v'){
return 1;
}
else if( char1=='\\' && char2=='-'){
return 45;
}
else if ( char1=='\\'){
return 92;
}
else return ;
//if(character==92 || character==7 || character==8 || character==27 || character==12 || character==10 || character==13 || character==13
// || character==9 || character==11)
}
char *classify(char *spec)
{
char *class= malloc(32); // 256 bits indicating if character N (bit position N) is in the class or not
int index=0;
while (spec[index] != '\0' ) { //*spec
// go through spec converting each entry in the spec into a set of bits in the class
// test if the next thing is \ .
// or test if you have X-Y (where X or Y might be a character or escaped character)
// \n-\r
if (spec[index]=='-' && index!=0 && !(index==1 && spec[0]=='^') && spec[index+1]!='\0'){
if(spec[index-1]<65 || spec[index+1]>122 || (spec[index-1]>90 && spec[index-1]<97) || (spec[index+1]>90 && spec[index+1]<97)){
//= if(spec[index-1] or spec[index+1] are not letters)
if((spec[index-1]>47 && spec[index-1]<57) || (spec[index+1]>47 && spec[index+1]<57) ){ //if it's a digit range
if(spec[index-1]>spec[index+1]){
printf("Error, first digit greater than the second one\n");
}
else{
for(int j=spec[index-1]; j<=spec[index+1] ; j++){
setBit(class,j);
printf("added digit : %c\n",j);
}
index++;
}
}
else{
printf("Error, bad use of range");
exit(1);
}
}
else{
if(spec[index-1]>spec[index+1]){
printf("Error, first char greater than the second one\n");
exit(1);
}
else if(spec[index-1]>=65 && spec[index-1]<=90 && spec[index+1]>=65 && spec[index+1]<=90 ){
for(int j=spec[index-1]; j<=spec[index+1] ; j++){
setBit(class,j);
printf("added char : %c\n",j);
}
index++;
}
else if( spec[index-1]>=97 && spec[index-1]<=122 && spec[index+1]>=97 && spec[index+1]<=122 ){
for(int j=spec[index-1]; j<=spec[index+1] ; j++){
setBit(class,j);
printf("added char : %c\n",j);
}
index++;
}
else{
printf("Bad use of char range");
exit(1);
}
}
}
else if((spec[index]>=65 && spec[index]<=90) || (spec[index]>=97 && spec[index]<=122)){
setBit(class,spec[index]);
printf("added char : %c\n",spec[index]);
}
else if(isEscapedChar(spec[index],spec[index+1])!=0){
if(isEscapedChar(spec[index],spec[index+1])==45){
index++;
}
setBit(class,isEscapedChar(spec[index],spec[index+1]));
}
printf("%c\n",spec[index]);
printf("%i\n",index);
index++;
}
if (spec[0]=="^") {
for (int i= 0; i < 8; ++i) class[i] ^= 255; // invert all bits in the class
}
return class;
}
int main()
{
char *line=0;
size_t line_max=0;
ssize_t line_len=0;
char a='a';
printf("%i\n",(int)a);
printf("%s",classify("fgmfa\\-c"));
while ((line_len= getline(&line,&line_max,stdin)) >= 0) {
if (line_len>0 && line[line_len-1]=='\n') {
line[line_len-1]=0;
}
char *class= classify(line);
for (int i= 0; i < 256; ++i)
if (testBit(class, i))
printf("%02x is set\n", i);
}
return 0;
}