header
{
package nl.tue.win.riaca.parser.univpoly;
import antlr.collections.*;
}
class UnivPolyParser extends Parser;
options
{
k = 3;
codeGenMakeSwitchThreshold = 3;
codeGenBitsetTestThreshold = 4;
buildAST=true;
ASTLabelType = "antlr.CommonAST"; // change default of "AST"
/*
* to tell the lexer to throw exception when find something not
* matching the input.
*/
defaultErrorHandler = false;
}
tokens
{
POLYNOMIAL; /* imaginary token */
ROOT;
MONOMIAL; /* imaginary token */
COEFF; /* imaginary token */
}
/**
* Matches a polynomial
*
*/
expr
: polynomial SEMI!
{
#expr = #([ROOT,"ROOT"],expr);
}
;
polynomial
: ( monomial | leadingterm ) ( monomial )*
;
leadingterm
: coefficient (STAR powerExpression)?
{
#leadingterm = #([MONOMIAL,"MONOMIAL"], leadingterm);
}
| powerExpression
{
#leadingterm = #([MONOMIAL,"MONOMIAL"], leadingterm);
}
;
monomial
: ( MINUS | PLUS ) coefficient (STAR powerExpression)?
{
#monomial = #([MONOMIAL,"MONOMIAL"], monomial);
}
| ( MINUS | PLUS ) (powerExpression)
{
#monomial = #([MONOMIAL,"MONOMIAL"], monomial);
}
;
powerExpression
: ID (POWER INT)?
{
}
;
/**
* Matches coefficient.
*
* @since 1.0
*/
coefficient
: INT
{
#coefficient = #([COEFF, "COEFF"], coefficient);
}
;
/**
* The polynomial Lexer.
*
* It read the imput (that it is suppose to be an univaraite polynomial).
*
* @author Ernesto Reinaldo (ereinald@win.tue.nl).
* @version 1.0
*/
class UnivPolyLexer extends Lexer;
options
{
k = 2;
}
/**
* Reads whitespace and throws it away.
*
* @since 1.0
*/
WS : (' '
| '\t'
| '\n'
| '\r')
{ _ttype = Token.SKIP; }
;
/**
* Reads the semicolon
*
* @since 1.0
*/
SEMI : ';';
/**
* Reads the plus operator.
*
* @since 1.0
*/
PLUS : '+';
/**
* Reads the minus operator.
*
* @since 1.0
*/
MINUS : '-';
/**
* Reads the star operator.
*
* @since 1.0
*/
STAR : '*';
/**
* Reads the divide operator.
*
* @since 1.0
*/
DIV : '/';
/*
* Reads the power operator.
*
* @since 1.0
*/
POWER : '^';
/**
* Reads an escape-sequence.
*
* @since 1.0
*/
protected
ESC : '\\'
( 'n'
| 'r'
| 't'
| 'b'
| 'f'
| '"'
| '\''
| '\\'
| ('0'..'3')
(
options {
warnWhenFollowAmbig = false;
}
: ('0'..'9')
(
options {
warnWhenFollowAmbig = false;
}
: '0'..'9'
)?
)?
| ('4'..'7')
(
options {
warnWhenFollowAmbig = false;
}
: ('0'..'9')
)?
)
;
protected
DIGIT
: '0'..'9'
;
INT
: (DIGIT)+
;
ID
options
{
testLiterals = true;
}
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
;
/**
* Tree walker.
*
* We transform the AST tree bilt by the UnivPolyPaser into an
* OpenMath object representing the univariate polynomial.
*
* @author Ernesto Reinaldo (ereinald@win.tue.nl)
* @version 1.0
*/
class UnivPolyTreeWalker extends TreeParser;
expr returns [String tResult]
{
String tLeft, tRight;
tResult = "";
VarNameClass tVar = new VarNameClass();
}
: tRoot : ROOT
{
tVar.mVarName = "x";
tVar.mIsVarSet = false;
tResult = "\n";
tResult +="\n";
tResult +="\n";
tResult += "\n"
+ "\n"
+ "\n"
+ "\n";
tResult +="\n";
tResult +="\n";
AST tChild = tRoot.getFirstChild();
if ( tChild == null )
throw new RecognitionException("not a polynomial");
while (tChild != null)
{
tResult += this.expr( tChild );
tChild = tChild.getNextSibling();
}
tResult += "\n";
tResult += "" + "\n";
tResult += "\n";
tResult += "\n";
}
| tMonomial: MONOMIAL
{
tResult +="\n";
tResult +="\n";
AST tChild = tMonomial.getFirstChild();
boolean tMinusIsSet = false;
/*
* First test if tChild is not null.
*/
if ( tChild == null )
{
throw new RecognitionException("not a polynomial");
}
/*
* if it is minus or plus take care of the sign
* and go to the next token
*/
if ( tChild.getType() == MINUS )
{
tResult += "\n"
+ "\n";
tChild = tChild.getNextSibling();
tMinusIsSet = true;
}
else if ( tChild.getType() == PLUS )
tChild = tChild.getNextSibling();
tResult += "\n";
/*
* First test if tChild is not null.
*/
if ( tChild == null )
{
throw new RecognitionException("not a polynomial");
}
/*
* Now the token should be either ID or COEFF
* If COEFF get teh coefficient value else put 1.
*/
if ( tChild.getType() == COEFF )
{
tResult += this.expr(tChild);
}
else if ( tChild.getType() == ID )
{
tResult +="1\n";
if ( tVar.mIsVarSet )
{
// Here we test if the polynomial is really an univpoly.
if ( !tVar.mVarName.equals( tChild.getText() ) )
throw new RecognitionException("not a polynomial");
}
else
{
tVar.mIsVarSet = true;
tVar.mVarName = tChild.getText( );
System.out.println("Aquiiiiii-->" + tVar.mVarName );
}
}
tResult += "\n";
if (tMinusIsSet)
tResult += "\n";
AST tChild2 = tChild.getNextSibling();
/* If tChild2 == null that means the expresion was of
* one of the types -coeff, coeff, +coeff, -x, x or +x
* if not either we have child2="^" or child2="*".
*/
if (tChild2 != null)
{
/*
* If "*" then consume the next two tokens.
* If "^" just consume one.
*/
if (tChild2.getType() == STAR )
{
tChild2 = tChild2.getNextSibling();
if ( tChild2 == null )
{
throw new RecognitionException("not a polynomial");
}
/*
* Just to test if the polym]nomial is uvivariate.
*/
if ( tVar.mIsVarSet )
{
if ( !tVar.mVarName.equals( tChild2.getText() ) )
{
throw new RecognitionException("not a polynomial");
}
}
else
{
tVar.mIsVarSet = true;
tVar.mVarName = tChild2.getText();
System.out.println("Hereeee-->" + tChild2.getText());
}
tChild2 = tChild2.getNextSibling();
if ( (tChild2 != null)
&& (tChild2.getType() == POWER) )
{
tChild2 = tChild2.getNextSibling();
}
}
else if ( tChild2.getType() == POWER )
{
tChild2 = tChild2.getNextSibling();
}
tResult += "\n";
/*
* If tChild2 == null that means we had either a*x or x
* else we had a*x^N or x^N.
*/
if ( tChild2 != null )
{
tResult += tChild2.getText() + "\n";
}
else
{
tResult += "1\n";
}
tResult +="\n";
}
else
{
if ( tChild.getType() == COEFF )
{
tResult += "\n0\n\n";
}
else if ( tChild.getType() == ID )
{
tResult += "\n1\n\n";
if ( tVar.mIsVarSet )
{
if ( !tVar.mVarName.equals( tChild.getText() ) )
{
throw new
RecognitionException("not a polynomial");
}
}
else
{
tVar.mIsVarSet = true;
tVar.mVarName = tChild.getText();
}
}
}
tResult +="\n";
}
|tCoeff : COEFF
{
AST tChild = tCoeff.getFirstChild();
tResult += tChild.getText() + "\n";
}
;
exception
catch [RecognitionException tRec]
{
throw tRec;
}