-1

I'm trying to create a rule to catch codas in syllables. A coda is some consonant which may or may not follow a nucleus and may never follow an onset; so my rule for coda should have consonant after a negation of onset. Assuming that negation is done in ANTLR with ~, I'm struggling to get it work. Here's my original attempt:

syllable
  : onset? nucleus coda?
  ;
coda
  : ~onset consonant
  ;

The grammar file had been fine until I inserted ~, now it's reutrning me the error message "no viable alternative at input '~onset'". Then I read somewhere that ~ negates all on its right hand side, so I changed it to:

coda
  : ~onset
    consonant
  ;

The problem persists. What am I doing wrong?

Miranda N
  • 65
  • 6

2 Answers2

3

A couple of ideas.

Bart is correct that you can't use negation of a rule match in your grammar definition.

A coupe of thoughts to toss out: (I can't quite make enough of the detail of you grammar out to be able to put an example together).

As I see it, there are two possibilities for this being "invalid":


1 - if you encounter this construct, it's an error, period.

If this is the case then you can simply change the rule to:

bad_coda
  : onset consonant;
coda
  : consonant;

And then, in a Listener or Visitor, if you encounter a bad_coda context, you can throw your own error message.

In this way you're using ANTLR as a "Recognizer" (actually the name of one of the superclasses of Parser for a reason), that "recognizes" this error situation.

Lesson: You're not limited to putting ONLY rules for what is valid in your grammar.


2 - If you encounter this sequence of tokens, you want to not recognize it as a coda, but perhaps there is another rule that would match (so you just need this rule to fail so that another might be attempted). In this case, the previous approach would not work, as bad_coda would match.

In that case, you might get away with making onset optional, and writing a semantic predicate that rejects the rule if the onset is actually present.

coda:
  : onset? { /* predicate that rejects if onset is present */} consonant

(NOTE: not having enough to work with here, I haven't tried this out, but it may be worth a shot.)

Mike Cargal
  • 6,610
  • 3
  • 21
  • 27
1

Inside parser rules, you can only negate tokens, not other parser rules.

See: Negating inside lexer- and parser rules

Bart Kiers
  • 166,582
  • 36
  • 299
  • 288