[antlr-interest] Using lexer rules properly
Johannes Luber
JALuber at gmx.de
Wed Jun 18 10:54:26 PDT 2008
> Hello all,
>
> This group has graciously helped me before to use ANTLR in a C# project
> I'm working on. If you remember, I'm parsing strings that denote datetime
> syntax for single or recurring events. So far I've been able to operate
> properly but it seems I'm having a lexer ambiguity causing me some issues.
>
> I've pasted below a sample working except of my current grammar. This
> will accept single datetime ranges in the format: "2008-06-17 14:30:00 lasting
> T30" for an event on 6/17/2008 at 2:30pm lasting 30 seconds. My full
> grammar has many other expression types. I want to add a new one to describe a
> cron syntax as "cron 0 * * * *", which for example would recur at the top
> of every hour.
>
> I decide to add a new lexer rule to parse the individual fields within the
> cron string:
>
> CRON_TERM: '!'? (UINT | '-' | '/' | '*' | '>' | '<')+;
>
> I also labeled UINT as "fragment" since it's used within another lexer
> rule.
>
> This tests out great along with a simple parser rule for the cron
> expression. However, now the rest of my grammar is broken and the original test
> case fails in datetime_p with NoViableAltException and matches nothing.
> There seems to be an ambiguity between UINT and CRON_TERM that's breaking
> anywhere else where I parse a number. It doesn't matter what order I place
> CRON_TERM, I get the same result.
>
> What am I doing wrong?
>
> Thanks in advance.
Adding CRON_TERM results in eating up all those UINT tokens. Try the following:
cron_term: '!'? (UINT | '-' | '/' | '*' | '>' | '<')+;
Johannes
>
> ----- Cut -----
>
> grammar TimeDeftest1;
>
> options {
> language=CSharp;
> output=AST;
> }
>
> once_p returns [OneTimeSchedule value]: (
> start=datetime_p ('lasting' duration=timespan_p)?
> );
>
> //
> // Time units
> //
> datetime_p returns [DateTime value]: (
> (y=year_p '-' mo=month_p '-' d=day_p)?
> h=hour24_p ':' m=minute60_p (':' s=second60_p ('.'
> ms=millisecond1000_p)? )?
> );
>
> year_p returns [int value]: UINT { $value = int.Parse($UINT.text); };
> month_p returns [int value]: UINT { $value = int.Parse($UINT.text); };
> day_p returns [int value]: UINT { $value = int.Parse($UINT.text); };
> hour24_p returns [int value]: UINT { $value = int.Parse($UINT.text); };
> minute60_p returns [int value]: UINT { $value = int.Parse($UINT.text); };
> second60_p returns [int value]: UINT { $value = int.Parse($UINT.text); };
> millisecond1000_p returns [int value]: UINT { $value =
> int.Parse($UINT.text); };
> days_p returns [int value]: int_p { $value = int.Parse($int_p.text); };
>
> timespan_p returns [TimeSpan value]: (
> 'T' (((d=days_p '.')? h=hours_p ':')? m=minutes_p ':')? s=seconds_p
> ('.' ms=milliseconds_p)?
> );
>
> hours_p returns [int value]: int_p { $value = int.Parse($int_p.text); };
> minutes_p returns [int value]: int_p { $value = int.Parse($int_p.text); };
> seconds_p returns [int value]: int_p { $value = int.Parse($int_p.text); };
> milliseconds_p returns [int value]: int_p { $value =
> int.Parse($int_p.text); };
>
> int_p: '-'? UINT;
>
> UINT: ('0'..'9')+;
>
> WS: (' '|'\t'|'\r\n'|'\r')+ { $channel = HIDDEN; };
>
--
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger
More information about the antlr-interest
mailing list