[antlr-interest] One weird, one (hopefully) simple problem ... from a newbie

jbb at acm.org jbb at acm.org
Fri Jan 24 14:47:02 PST 2003


Mr. Youngman :-

You asked:

Wol>......if I change UNTIL to
Wol>WHILE, it only appears to get as far as the LOOP......
      
This is because of this rule:

wl		: (wle:WLE {System.out.println("WHILE "+wle);});
                       ^^^
                        |
                 should be WHILE (i think)

You also asked:

Wol>......And I'm not getting any
Wol>error messages - it's just that my trace appears to work over the entire
Wol>file with "until", but stop as it hits "while". That's my weird problem.

This is because of this rule:

entry	:	(sl|ig|id|nl|rg|lb|dc|lp|wl|un|rp|assign)+;

which tells your generated parser to simply stop when it sees an input
it does not recognize to be the begining of a phrase in the language
you are trying to parse. If you change this rule to:

entry : (sl|ig|id|nl|rg|lb|dc|lp|wl|un|rp|assign)+ EOF;

then your parser is instructed to correctly process the entire input
file until it sees the end-of-file. thus when an unrecognizable
leading token is seen an error message will be displayed.

And lastly, you asked:

Wol>And as for the simple problem? How do I get the parser to print "MULTIPLY",
Wol>"DIVIDE" or whatever - by the way, it's got to be postfix.

Here is a version of your grammar which accumulates expressions into a
String in postfix form and prints it. You, however, will probably
want to exploit Antlr's capabilities for constructing and traversing a
Abstract Syntax Tree (AST) and not use a string as an intermediate
format for your parse results.

-------------------------
class BASICLexer extends Lexer;

options {
    exportVocab=BASIC;
    k=2;
}

tokens {
    LABEL;
    LOOP; WHILE; UNTIL; REPEAT;
}

{
    // Are we in a statement or expression?
    private final int STATEMENT = 0;
    private final int EXPRESSION = 1;
    int state = STATEMENT;
}

WS  : ( ' '|'\t') { $setType(Token.SKIP); };
EOL : ( "\r\n"|'\r'|'\n' ) { newline(); state = STATEMENT; };

protected ALPHA : ('a'..'z'|'A'..'Z') ;
protected NUMERIC : ('0'..'9') ;
IDENT
    : ( ALPHA ( ALPHA|NUMERIC|'.'|'$'|'%')* )
        {
            if (state == STATEMENT) {
                if (LA(1) == ':' ) {
                    int len=text.length();
                    consume();
                    text.setLength(len);
                    _ttype = LABEL;
                } else {
                    // more stuff here
                    String txt = $getText.toUpperCase();
                    // cant use switch here - it takes int. bummer
                    if (txt.equals("LOOP")) { _ttype =
                        LOOP;}
                    else if (txt.equals("WHILE")) {
                        _ttype = WHILE;}
                    else if (txt.equals("UNTIL")) {
                        _ttype = UNTIL;}
                    else if (txt.equals("REPEAT")) {
                        _ttype = REPEAT;};
                }
            }
        }
    ;

INT     : (NUMERIC)+ ;
DECIMAL : ('.') ;
STRING_LITERAL : '"' ('A'..'Z'|'a'..'z'|'0'..'9')* '"' ;

PLUS    : ('+');
MINUS   : ('-');
DIVIDE  : ('/');
MULTIPLY: ('*');
ASSIGN  : ('=');

class BASICParser extends Parser;

options {
    exportVocab=BASIC;
    buildAST=true;
    k=2;
}

ig returns [String val=null] :
	i:INT
	{
	    System.out.println("Integer "+i);
	    val = i.getText();
	}
    ;

id returns [String ident=null] :
	iden:IDENT
	{
	    System.out.println("Ident "+iden);
	    ident = iden.getText();
	}
    ;

rg    : (r:REAL {System.out.println("Real "+r);});
sl    : (slit:STRING_LITERAL {System.out.println("String "+slit);});
nl    : (EOL {System.out.println("New line");});
lb    : (lbl:LABEL {System.out.println("Label "+lbl);});
dc    : (dcm:DECIMAL {System.out.println("Decimal "+dcm);});
lp    : (loop:LOOP {System.out.println("LOOP "+loop);});
wl    : (wle:WHILE {System.out.println("WHILE "+wle);});
un    : (until:UNTIL {System.out.println("UNTIL "+until);});
rp    : (repeat:REPEAT {System.out.println("REPEAT "+repeat);});

mulOp returns [String op=null] :
	MULTIPLY { op = "MUL"; }
    | DIVIDE { op = "DIV"; }
    ;

addOp returns [String op=null] :
	PLUS { op="ADD"; }
    | MINUS { op="SUB"; }
    ;

atom returns [String a=null] : a=ig | a=id ;

prodExpr returns [String prod=null] :
	prod=atom
	(
	    { String o, r; }
	    o=mulOp r=prodExpr { prod += " " + r + " " + o; }
	)?
    ;

sumExpr returns [String sum=null] :
	sum=prodExpr
	(
	    { String o, r; }
	    o=addOp r=sumExpr { sum += " " + r + " " + o; }
	)?
    ;

expr returns [String e=null] :
	e=sumExpr
    ;

assign :
	{ String ident, e; }
	ident=id ASSIGN e=expr
	{
	    System.out.println(e+" "+ident+" ASG");
	}
    ;

entry :
	(sl|ig|id|nl|rg|lb|dc|lp|wl|un|rp|assign)+ EOF
    ;
-------------------------

Hope this helps...

-- 
	-jbb
----------------+----------------------------
 John B. Brodie | Email : jbrodie at cs.fit.edu
----------------+----------------------------

 

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/ 



More information about the antlr-interest mailing list