I know just enough about ANTLR to be dangerous. Like another recent
poster, I've read the book and am trying to get the hang of it, but
think I have this simple grammar messed up.
One of the kinds of statements my grammar, attached, tries to handle is:
REGISTER = avg(REGISTER, REGISTER, REGISTER);
where REGISTER is just a multi-part identifier, with the parts separated
by an '!'. The lexer seems to work ok, judging by the Tokens it returns
in another part of my code. But, at runtime, the parser gets a
NoViableAltException on a statement like that.
Can anybody offer any pointers? Thanks very much.
Bill
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"il-antlr-interest" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/il-antlr-interest?hl=en
-~----------~----~----~----~------~----~------~--~---
grammar SGI;
options {
language = 'CSharp2';
output=AST;
}
@header {
using System.IO;
}
@members {
static Registry registry;
static ArrayList regArray;
static Logger log; // used for logging messages
static Logger regLog; // to log register updates
public Registry Registry
{
set
{
registry = value;
}
}
public ArrayList RegArray
{
get
{
return regArray;
}
set
{
regArray = value;
}
}
public Logger Log
{
set
{
log = value;
}
}
public Logger RegLog
{
set
{
regLog = value;
}
}
// Math functions
public int doMax(ArrayList list)
{
if (list.Count == 0)
return 0;
int max = ((Register)list[0]).ScaledValue;
for (int i = 1; i < list.Count; i++)
{
int v = ((Register)list[i]).ScaledValue;
if (v > max)
max = v;
}
return max;
}
public int doMin(ArrayList list)
{
if (list.Count == 0)
return 0;
int min = ((Register)list[0]).ScaledValue;
for (int i = 1; i < list.Count; i++)
{
int v = ((Register)list[i]).ScaledValue;
if (v < min)
min = v;
}
return min;
}
public int doAvg(ArrayList list)
{
log.writeText("Came to doAvg with list size " + list.Count);
if (list.Count == 0)
return 0;
int total = 0;
foreach (Register r in list)
total += r.ScaledValue;
return total / list.Count;
}
// Utility methods
public Register findRegisterByName(String str)
{
if (str == null)
return null;
foreach (Register reg in regArray)
{
if (reg.FullName.Equals(str))
return reg;
}
return null;
}
}
@parser::namespace { SGIServer }
@lexer::namespace { SGIServer }
prog: (stat SEMI)+ ;
/** Statement */
stat: REGISTER EQUALS expr
{ String regName = $REGISTER.text;
Register reg = findRegisterByName(regName);
if (reg != null)
reg.ScaledValue = $expr.value;
else
log.writeErrText("Parser 'stat' did not find Register " +
regName);
}
;
elist
scope {
ArrayList regList;
}
: regs+=expr (COMMA regs+=expr)* { $elist::regList =
(ArrayList)$regs; };
expr returns [int value]
: e=multdiv {$value = $e.value;}
( '+'^ e=multdiv {$value += $e.value;}
| '-'^ e=multdiv {$value -= $e.value;}
)*
;
multdiv returns [int value]
: e=atom {$value = $e.value;}
( '*'^ e=atom {$value *= $e.value;}
| '/'^ e=atom {if ($e.value != 0)
$value /= $e.value;
else
$value = 0;}
)*
;
atom returns [int value]
: CONSTANT {$value = Convert.ToInt32($CONSTANT.text);}
| REGISTER { Register reg = findRegisterByName($REGISTER.text);
if (reg != null)
$value = reg.ScaledValue;
else
{
log.writeErrText("Parser 'atom' did not
find Register " + $REGISTER.text);
$value = 0;
}
}
| ('avg'^ | 'Avg'^) LPAREN elist RPAREN { $value =
doAvg($elist::regList); }
| ('min'^ | 'Min'^) LPAREN elist RPAREN { $value =
doMin($elist::regList); }
| ('max'^ | 'Max'^) LPAREN elist RPAREN { $value =
doMax($elist::regList); }
| LPAREN expr RPAREN {$value = $expr.value;}
;
WS : (' '
| '\t'
| '\n'
| '\r')
{ $channel = HIDDEN; }
;
LPAREN : '(' ;
RPAREN : ')' ;
STAR : '*' ;
DIV : '/' ;
PLUS : '+' ;
MINUS : '-' ;
SEMI : ';' ;
COMMA : ',' ;
EQUALS : '=' ;
fragment
DIGIT : '0'..'9' ;
fragment
LETTER : 'a'..'z' | 'A'..'Z' | '_' ;
COMMENT : '/*' .* '*/' { $channel = HIDDEN; } ;
LINE_COMMENT: '//' ~('\n' | '\r')* '\r'? '\n' { $channel = HIDDEN; } ;
fragment
INT : (DIGIT)+ ;
FLOAT : INT
| INT '.' INT
| '.' INT
;
CONSTANT: FLOAT
| FLOAT ('e' | 'E') ('+' | '-')? INT
;
EXP : '**' ;
AND : '&' ;
OR : '|' ;
XOR : '^' ;
IDENT : LETTER (LETTER | DIGIT)* ;
REGISTER: IDENT ('!'IDENT)* ;
List: http://www.antlr.org/mailman/listinfo/antlr-interest
Unsubscribe:
http://www.antlr.org/mailman/options/antlr-interest/your-email-address