Question

In Alex I have a rule that looks like this

^@ident\:$   {TLabel (init s)}

So, a single line that starts with an identifier followed by a colon and then the end of the line.

This works fine unless the line is the last in the file and there is not a \n at the end. When that happens the $ does not match and the scan fails. What do I need to do to match either the end of the line (\n) or the end of the file?

Was it helpful?

Solution

The easiest solution is to make sure that the input always ends in \n by simply appending one at the end of the input.

Alternatively, you can get the behavior you want by using a predicate instead of $.

^@ident\:/{ eolOrEof }   { ... }

A predicate can examine the input stream surrounding the token and decide if it should match or not. In this case, we simply have to examine the stream after the token to check for \n or EOF.

The exact definition will depend on which wrapper you're using (the definition of the type AlexInput varies between wrappers), but here's one I got to work using the "basic" wrapper.

eolOrEof :: user -> AlexInput -> Int -> AlexInput -> Bool
eolOrEof _ _ _ (_, after) =
  case after of
    []       -> True  -- end-of-file
    ('\n':_) -> True  -- end-of-line
    _        -> False
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top