[antlr-interest] Help controlling parser decisions
Thomas Brandon
tbrandonau at gmail.com
Wed Jul 25 02:52:31 PDT 2007
On 7/25/07, Ted Villalba <ted.villalba at gmail.com> wrote:
> Thanks for the responses.
> Seems straight forward enough to create the disambiguating semantic
> predicate, but perhaps Im not starting out with the right assumptions.
>
> If I want to accept near as a term if it begins( or ends) a sentence, then I
> thought I could do something like this:
>
> value : value_ -> ^(VALUE value_) ;
>
> value_ : keyBOOL terms* (operator^ value)*
> | LPAREN! value RPAREN! ( operator^ value)*
> ;
>
> keyBOOL : {input.LT(1).getText().equals("NEAR")}? terms;
>
> terms : WCHAR+ -> ^(TERMS WCHAR+ )
> ;
>
> But when I try to enter SO=(NEAR apples oranges), the parser no likey.
> Still getting:
> line 1:5 no viable alternative at input 'NEAR'.
>
> Am I missing an obvious puzzle piece ?
> I tried instead to assume all booleans were terms and then tested each of
> the terms in a similar approach, but wasn't successful yet at
> differentiating, on demand, the operators from the terms.
The problem in the above rules isn't obvious to me. Looks like it
should work, though you seem to have some uneeded + and *'s given that
term is already WCHAR+, but that shouldn't break it as far as I can
see.
Were you running it under the ANTLRWorks interpreter? That won't do
actions so it won't work there. You need to use the debugger in this
case.
I got the following grammar to parse your example fine as well as to
parse "near=(near apples oranges)", correctly handling the first
"near" as a tag and the second as a keyBool:
grammar WQL;
options{
output=AST;
ASTLabelType=CommonTree;
}
tokens{ TAG; VALUE; TERMS;} //imaginary token types
@header{
import java.util.HashMap ;
}
@members {
HashMap fieldMap = new HashMap();
}
start
:( query
{System.out.println("AST:\n"+$query.tree.toStringTree());}
)+
;
query
: field
;
field
: tag '=' LPAREN value RPAREN -> ^('=' tag value)
| tag '=' terms -> ^('=' tag terms)
| qid
;
value
: keyBOOL terms?
;
keyBOOL
: near
| far
;
terms
: WCHAR+ -> ^(TERMS WCHAR+ )
;
tag : WCHAR
;
qid : '#'! DIGIT
;
near: {input.LT(1).getText().toLowerCase().equals("near")}? WCHAR
;
far : {input.LT(1).getText().toLowerCase().equals("near")}? WCHAR
;
DIGIT : ('0'..'9');
WS : (' '|'\t'|'\r'|'\n')+ {skip();};
LPAREN : '(' ;
RPAREN : ')' ;
QUOTE : '"';
WCHAR : ~('='|'('| ')'|'"'|' '|'\t'|'\n'|'\r'|'#')+;
AFAICT there are no changes to the basic method you gave. I removed
some stuff to simplify putting together the grammar and I cleaned up
some of the unneccessary +s and *s. But no major changes.
Tom.
>
> Thank you for the help,
> Ted
>
>
>
More information about the antlr-interest
mailing list