Parsing an integer and HEX value in Ragel

229 Views Asked by At

I am trying to design a parser using Ragel and C++ as host langauge. There is a particular case where a parameter can be defined in two formats :

a. Integer : eg. SignalValue = 24
b. Hexadecimal : eg. SignalValue = 0x18

I have the below code to parse such a parameter :

INT = ((digit+)$incr_Count) %get_int >!(int_error); #[0-9]
HEX = (([0].'x'.[0-9A-F]+)$incr_Count) %get_hex >!(hex_error); #[hexadecimal]

SIGNAL_VAL = ( INT | HEX ) %/getSignalValue;

However in the above defined parser command, only the integer values(as defined in section a) gets recognized and parsed correctly. If an hexadecimal number(eg. 0x24) is provided, then the number gets stored as ´0´ . There is no error called in case of hexadecimal number. The parser recognizes the hexadecimal, but the value stored is '0'.

I seem to be missing out some minor details with Ragel. Has anyone faced a similar situation?

The remaning part of the code :

 //Global 
int lInt = -1;


action incr_Count {
   iGenrlCount++;
}

action get_int {
  int channel = 0xFF;
  std::stringstream str;  
  while(iGenrlCount > 0)
  {
    str << *(p - iGenrlCount);
    iGenrlCount--;
  }
  str >> lInt; //push the values
  str.clear();
}


action get_hex {
 std::stringstream str; 
 while(iGenrlCount > 0)
 {
  str << std::hex << *(p - iGenrlCount);
  iGenrlCount--;
 }
 str >> lInt; //push the values
}

action getSignalValue {
  cout << "lInt = " << lInt << endl;
}
1

There are 1 best solutions below

0
Roman Khimov On BEST ANSWER

It's not a problem with your FSM (which looks fine for the task you have), it's more of a C++ coding issue. Try this implementation of get_hex():

action get_hex {
 std::stringstream str;
 cout << "get_hex()" << endl;
 while(iGenrlCount > 0)
 {
  str << *(p - iGenrlCount);
  iGenrlCount--;
 }
 str >> std::hex >> lInt; //push the values
}

Notice that it uses str just as a string buffer and applies std::hex to >> from std::stringstream to int. So in the end you get:

$ ./a.out 245
lInt = 245
$ ./a.out 0x245
lInt = 581

Which probably is what you want.