[antlr-interest] Antlr v3 -- Lexing '..' and '1.'
John B. Brodie
jbb at acm.org
Thu Jul 27 18:09:28 PDT 2006
Greetings!
I am trying to construct a lexer under Antlr v3 that will recognize a
RANGE (e.g. '..') operator, FLOAT (e.g. 1.) numbers, and some other stuff.
Here is what I have so far:
//------------------------- begin cut here ---------------------------
grammar Test;
test : .+ EOF ;
DOT : '.' ;
RANGE : '..' ;
ELLIPSIS : '...' ;
NATURAL : UINT ;
FLOAT :
( UINT ('.' ~'.') => ('.' UINT? EXPONENT?) ) /*1*/
| ( UINT EXPONENT )
| ( '.' UINT EXPONENT? )
;
fragment EXPONENT : ( 'e' | 'E' ) ( '+' | '-' )? UINT ;
fragment DIGIT_10 : '0'..'9' ;
fragment UINT : DIGIT_10+ ;
// Whitespace -- ignored
WS : ( ' '
| '\t'
| '\f'
| ( '\r' | '\n' ) // handle newlines
)+
{ channel=99; }
;
//------------------------- end cut here -----------------------------
My problems center around (i think) the line I have labeled /*1*/ above.
I want to recognize a '.' inside a FLOAT if and only if that '.' is not
followed by another '.'
I think the syntactic predicate in /*1*/ does that.
Antlr v3 ignores the predicate.
Can you help me fix this?
(also attached below is a rather tooooo long Java test driver)
This is very similar to a problem in Pascal. Has the v2 Pascal grammar
been ported to v3 yet? If so, just point me to it.
Also I think I saw on the Mantra website that Mantra also is meant to have
floats and a RANGE operator, but I could not find any handling of RANGE in
the grammar contained in the Mantra source tar-ball.
I must have missed something here, please point me in the proper direction.
Thanks in advance!
-jbb
TestDriver.java follows...
//------------------------- begin cut here ---------------------------
import java.io.*;
import java.util.*;
import org.antlr.runtime.*;
public class TestDriver {
private static class Pair {
public String input;
public int[] expected;
public Pair(String i, int[]e) {
input = i;
expected = e;
}
}
private static final Pair[] x = {
new Pair("1",new int[]{Test.NATURAL}),
new Pair(".",new int[]{Test.DOT}),
new Pair("..",new int[]{Test.RANGE}),
new Pair("...",new int[]{Test.ELLIPSIS}),
new Pair(".0",new int[]{Test.FLOAT}),
new Pair(".0e+0",new int[]{Test.FLOAT}),
new Pair("1.0",new int[]{Test.FLOAT}),
new Pair("1.",new int[]{Test.FLOAT}),
new Pair("1.0",new int[]{Test.FLOAT}),
new Pair("1.0e+0",new int[]{Test.FLOAT}),
new Pair("1e1",new int[]{Test.FLOAT}),
new Pair("1e+1",new int[]{Test.FLOAT}),
new Pair("1e-1",new int[]{Test.FLOAT}),
new Pair("1 . 2",new int[]{Test.NATURAL,
Test.WS,
Test.DOT,
Test.WS,
Test.NATURAL}),
new Pair("1 .. 2",new int[]{Test.NATURAL,
Test.WS,
Test.RANGE,
Test.WS,
Test.NATURAL}),
new Pair("1 ... 2",new int[]{Test.NATURAL,
Test.WS,
Test.ELLIPSIS,
Test.WS,
Test.NATURAL}),
new Pair("1. . 2.",new int[]{Test.FLOAT,
Test.WS,
Test.DOT,
Test.WS,
Test.FLOAT}),
new Pair("1. .. 2.",new int[]{Test.FLOAT,
Test.WS,
Test.RANGE,
Test.WS,
Test.FLOAT}),
new Pair("1. ... 2.",new int[]{Test.FLOAT,
Test.WS,
Test.ELLIPSIS,
Test.WS,
Test.FLOAT}),
new Pair("1.1 . 2.2",new int[]{Test.FLOAT,
Test.WS,
Test.DOT,
Test.WS,
Test.FLOAT}),
new Pair("1.1 .. 2.2",new int[]{Test.FLOAT,
Test.WS,
Test.RANGE,
Test.WS,
Test.FLOAT}),
new Pair("1.1 ... 2.2",new int[]{Test.FLOAT,
Test.WS,
Test.ELLIPSIS,
Test.WS,
Test.FLOAT}),
new Pair("1.",new int[]{Test.FLOAT}),
new Pair("1..",new int[]{Test.NATURAL,Test.RANGE}),
new Pair("1...",new int[]{Test.NATURAL,Test.ELLIPSIS}),
new Pair("1.2",new int[]{Test.FLOAT}),
new Pair("1..2",new int[]{Test.NATURAL,
Test.RANGE,
Test.NATURAL}),
new Pair("1...2",new int[]{Test.NATURAL,
Test.ELLIPSIS,
Test.NATURAL})
};
public static void main(String[] args) {
for(int i = 0; i < x.length; ++i) {
try {
System.out.format("testing `%s`: ",x[i].input);
boolean success = true;
CommonTokenStream tokens = new CommonTokenStream
(new TestLexer
(new ANTLRStringStream(x[i].input)));
List l = tokens.getTokens();
if( l.size() == x[i].expected.length ) {
for(int j = 0; j < x[i].expected.length; ++j) {
Token t = (Token)l.get(j);
if (t.getType() != x[i].expected[j]) {
success = false;
System.out.format("token number %s, %s should be %s; ",
j,
Test.tokenNames[t.getType()],
Test.tokenNames[x[i].expected[j]]);
}
}
} else {
success = false;
System.out.format("...wrong number of tokens:%s should be %s; ",
l.size(),x[i].expected.length);
}
if (success) {
System.out.format("OK%n");
} else {
System.out.format("FAIL: ");
if( l.size() == 0 ) {
System.out.format("no tokens found!%n");
} else {
Token t = (Token)l.get(0);
System.out.format("([%s,%s]",
Test.tokenNames[t.getType()],
t.getText());
for(int j = 1; j < l.size(); ++j) {
t = (Token)l.get(j);
System.out.format(", [%s,%s]",
Test.tokenNames[t.getType()],
t.getText());
}
System.out.format(")%n");
}
}
} catch(Exception e) {
System.out.println("exception: "+e);
}
}
}
}
//------------------------- end cut here -----------------------------
More information about the antlr-interest
mailing list