Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was asked to build a tool that can identify if a string match a pattern.

Example:

{1:20} stuff t(x) {a,b,c}

would match:

  • 1 stuff tx a
  • 20 stuff t c

It is a sort of regex but with a different syntax

  • Parentheses indicate an optional value
  • {1:20} is a interval; I will have to check if the token is a number and if it is between 1 and 20
  • {a,b,c} is just an enumeration; it can be either a or b or c

Right now I implemented this with a regex, and the interval stuff was a pain to do.

On my own time I tried implementing some kind of matcher by hand, but it turns out it's not that easy to do.

By experimenting I ended up with a function that generates a state table from the pattern and a state machine. It worked well until I tried to implement the optional value, and I got stuck and how to generate the state table.

After that I searched how I could do this, and that led me to stuff like LL parser, LALR parser, recursive-descent parser, context-free grammars, etc. I never studied any of this so it's hard to know what is relevant here, but I think this is what I need:

  • A grammar
  • A parser which generates states from the grammar and a pattern
  • A state machine to see if a string match the states

So my first question is: Is this right ? And second question, what do you recommend I read/study to be able to implement this ?

share|improve this question
    
1-20 should just be ((1?\d)|20) –  Peter Smith Oct 20 '12 at 0:25
    
@PeterSmith: That also accepts '0', which is out of range. –  John Bartholomew Oct 20 '12 at 3:35

1 Answer 1

up vote 4 down vote accepted

If the requirements are as described (just matching static text, integers in a set range, optional values and alternation), then your patterns do describe regular languages, so a regular expression is probably the right way to go -- full context-free grammars give you more power than you need here.

If you want to implement a matcher from scratch, you should read up on DFAs, and NFAs. I would also recommend you read Regular Expression Matching Can Be Simple And Fast, which describes how to implement efficient (linear in the length of the text being searched) matching using NFAs and DFAs.

Alternatively, you could just hack something together to turn your patterns into a more common regular expression syntax and use an existing regex engine (I would recommend re2, which was created by the same person who wrote the above description).

To avoid the difficulties of matching integer intervals textually, I would suggest you turn intervals into general integer matching (i.e., match any sequence of digits) and use a separate pass to check whether the value is in the specified interval. If you end up writing your own matcher, you could build this functionality into the core. Note that matching integer intervals textually is entirely possible (they're still regular), but pulling out arbitrary integers and performing a separate range check may be simpler.

share|improve this answer
    
Yes, right now I do this by turning the pattern into a regex and use a second pass to match the intervals. My goal here was to implement a matcher from scratch, so thank you for the pointers, I will look into it. –  Vincent Rischmann Oct 21 '12 at 11:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.