tags:

views:

82

answers:

2

I want to accept a decimal number between 0 and 255. This is the best I can come up with:

fragment my_token :
  ('0'..'9') |                    // 0 -> 9
  ('1'..'9' '0'..'9') |           // 0 -> 99
  ('1' '0'..'9' '0'..'9')  |      // 100 -> 199
  ('2' '0'..'4' '0'..'9') |       // 200 -> 249
  ('25' '0'..'5');                // 250 -> 255

but I am just a clueless n00b. Surelry there is a better way?

+9  A: 

You'll have much better results if you relax the lexer and defer the checking to a later time. Lex NUMBER, then when you convert it later you can provide a very specific error message if the value is out of range. If you make the lexer strict and someone enters 256, the error message that results is illegible to anyone that hasn't made a grammar before.

NUMBER
    :    '0'..'9'+
    ;
280Z28
+1. In addition, integer value constraints sealed in such place makes refactoring true pain.
gorsky
Plus, this lets you match "007" as a number. James Bond would appreciate that.
Andrew Dalke
+1  A: 

I up'ed 280Z28's answer - do what was suggested there. But if you want another way to write the pattern you can try:

0|1([0-9][0-9]?)?|2([0-4][0-9]?|5[0-5]?)?|[3-9][0-9]?

It's more me showing off than anything else. It's hard to verify (the first time I wrote this I made a mistake that wasn't caught until I tested it), and not something you should use in your code.

Andrew Dalke