Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Compiler Tools JavaCC > Unary minus
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 8 Topic 477 of 549
Post > Topic >>

Unary minus

by Cesare Zecca <Cesare.Zecca.prof@[EMAIL PROTECTED] > Sep 20, 2007 at 11:05 AM

Let me continue here, the orginal thread "negative floats and unary
minus"  is closed

On 17 Set 2002, 11:39, arsf10 <ars...@[EMAIL PROTECTED]
> wrote:
http://groups.google.com/group/comp.compilers.tools.javacc/browse_thread/thread/3bdfad0d0fe95cf6/f652f4c4c9be54f7?lnk=gst&q=unary+minus&rnum=1#f652f4c4c9be54f7

> eric,
>
> from your comments (and sreeni's), i understand that i should be
handling
> the context of the '-' in the parser and not try to magically have
javacc
> interpret the '-' as a token in 3 different ways, which is impossible

Well, does it mean that the recognition should be faced by the parser.
Right?

> i separated the problem into the lexical states of an unambiguous
negative
> integer, a subtraction operation, and aunaryminusoperation in the
> parser section

To lead the lexer (token manager) in a given lexical states would
require a given, specific prefix...
In the parser section (non terminals) ? I'm confused here between the
parser and the lexer roles.

> and i can parse my cases correctly.

Any example/excerpt of the solution for beginners?


I tried to add the unary minus to my Gpl.jj grammar (derived from
NL_Xlator), following two hints:
1) Theo's tutorial, 1.3.6 Adding parentheses, a unary operator, and
history, p. 20-22
http://www.engr.mun.ca/~theo/JavaCC-Tutorial/

2) the Sreeeny's one
You need to parse unary minus as an operator if you want to  satisfy
all your constraints
http://groups.google.com/group/comp.compilers.tools.javacc/browse_thread/thread/83ed89955106ac0c/e0d44dcd20b6736c?lnk=gst&q=unary+minus&rnum=2#e0d44dcd20b6736c

Well, the result is that the unary minus (now recognized by the
Factor() non terminal) breaks some unit tests: the unary minus
operator wins, per associativity, on the additive, binary minus
operator.
E.g. the expression
	a - b
is tokenized in the "a" and "-b" tokens and then (erroneously) leads
the parser to the following diagnostic

Exception in thread "main" ... ioni.gpl.ParseException: Encountered
"-" at line 1, column 3.
Was expecting one of:
    <ADD_ARITHMETIC_OP> ...
    <MULT_ARITHMETIC_OP> ...
    ";" ...


Currently I have not enabled (nor tested) yet the reg expr for numbers
(the next thing to do!) and the expressions currently involve only
identifiers.
The original six-points list (orginal thread) gets, for Gpl

1. -a (and (-a)) parse as the token -a (between parenthesis); works
fine;
2. -a+b parse as addition of the token -a, the operation 'addition'
and b; works fine. a + -b works fine, as well
3. (exponentiation, not sup****ted)
4. (exponentiation, not sup****ted)
5. a-b to parse as the token -a, the operation 'subtraction', and the
token b  does NOT works anymore (utest regression)
6. a--b to parse as the token a, the  operation 'subtraction', and the
token -b, does NOT works
7. funct(-a), to be implemented, yet

You shall be able (when numbers will be added) to replace identifiers
such as a or b with a well formed numbers (numeric literal constants);
the reg expr has been tem****ary removed for sake of simplicity and I
omit it here.

Instead of alternatively hack as suggested by Eric (see above).
>   expression ::= expression <NEGATIVE_INTEGER>

I would prefer to do (and to learn) the right thing

>  you may need to use lexical states so that
> finding a negative number is only permitted in certain states

Mumble mumble let me try...
When I've just  got a Factor() the "-" token shall be always
recognized as the binary additive minus operator
or, in other terms, the rule to recognize a negated operand (factor)
should be switched off
or in other terms, the rule to recognize a negated operand (factor)
should be switched on only when a factor is expected

But, the problem is that Factor() is a nonterminal (see the grammar
below) i.e. parser's stuff, not lexer's one.
The handling of lexical states, instead, seems to be done
http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-moz.htm#tth_sEc3.11
at.. lexical level i.e. acting on the token manager and its reg
expresssions.

I'm quite confused
Any clarification&help would be greatly appreciated.
Thanks in advance.

Cesare

Just here below the Gpl.jj grammar

-----------------
options
{
	STATIC = true;
	UNICODE_INPUT = true;
}

PARSER_BEGIN(Gpl)

package it.finmatica.gpj.ec.istruzioni.gpl;

public class Gpl
{
	public static
	void
	main( String args[] ) throws ParseException
	{
		Gpl lParser = new Gpl( System.in );
		lParser.ExpressionList();
	}
} // end class Gpl

PARSER_END(Gpl)

SKIP :
{	" "
|	"\t"
|	"\n"
|	"\r"
}

TOKEN :	// Basics
{	<#LETTER : ["a"-"z", "A"-"Z"] >
|	<#DIGIT : ["0"-"9"] >
|	<PAR_OPEN : ["("] >
|	<PAR_CLOSED : [")"] >
}

/***
TOKEN : // Numeric literal costants
{
	< NUMBER_LITERAL: <FLOAT> >
| 	< #FLOAT
	: <INTEGER>
	| <INTEGER> ( <FRACTIONAL_PART_SEPARATOR> <INTEGER> )?
    >
| 	< #INTEGER: ( <DIGIT> )+ >
|	< #FRACTIONAL_PART_SEPARATOR: "," >
}
***/

TOKEN :	// Additive and multiplicative arithmetic operators, unary
minus
{	<ADD_ARITHMETIC_OP: ["+", "-"] >
|	<MULT_ARITHMETIC_OP: ["*", "/"] >
|	<UNARY_MINUS: ["-"] >
}

TOKEN : // (group) identifiers
{	<GROUP_ID : <ID> ( <GROUP_ID_SEPARATOR> <ID> )* >
|	<#ID : ( <LETTER> | "_" ) ( <LETTER> | "_" | <DIGIT> )* >
|	<GROUP_ID_SEPARATOR : "." >
}

void
ExpressionList() :
{
	String lString;
}
{
	{
		System.out.println( "Type in an expression followed by a \";\" or ^D
to quit:" );
		System.out.println( "" );
	}

	( lString = Expression() ";"
		{
			System.out.println( lString );
			System.out.println("");
			System.out.println("Type in another expression followed by a \";\"
or ^D to quit:" );
			System.out.println("");
		}
	)*
	<EOF>
} // end Gpl.ExpressionList()

String
Expression() :
{
	java.util.Vector<String> lOpImages = new java.util.Vector<String>();
	java.util.Vector<String> lTermImages = new
java.util.Vector<String>();
	String lResult;
	Token lAddArithmeticOp = null;
}
{
	lResult = Term()
	{
		lTermImages.addElement( lResult );
	}

	( lAddArithmeticOp = <ADD_ARITHMETIC_OP> lResult = Term()
		{
			lOpImages.addElement( lAddArithmeticOp.image );
			lTermImages.addElement( lResult );
		}
	)*

	{
		if ( lTermImages.size() == 1 )
		{
			lResult = lTermImages.elementAt(0);
			return lResult;
		}
		else
		{
			lResult = lTermImages.elementAt(0);
			for ( int i = 1; i < lTermImages.size(); i++ )
			{
				boolean lIsSum = lOpImages.elementAt( i - 1 ).equals( "+" );
				lResult += (lIsSum ? " plus " : " minus ")
						+  lTermImages.elementAt( i )
						;
			}
			return lResult;

		}
	}
} // end Gpl.Expression()

String
Term() :
{
	java.util.Vector<String> lOpImages = new java.util.Vector<String>();
	java.util.Vector<String> lFactorImages = new
java.util.Vector<String>();
	String lResult;
	Token lMultArithmeticOp = null;
}
{
	lResult = Factor()
	{
		lFactorImages.addElement( lResult );
	}
	(
		lMultArithmeticOp = <MULT_ARITHMETIC_OP> lResult = Factor()
		{
			lOpImages.addElement( lMultArithmeticOp.image );
			lFactorImages.addElement( lResult );
		}
	)*
	{
		if ( lFactorImages.size() == 1 )
		{
			lResult = lFactorImages.elementAt(0);
			return lResult;
		}
		else
		{
			lResult = lFactorImages.elementAt(0);
			for ( int i = 1; i < lFactorImages.size(); i++ )
			{
				boolean lIsMult = lOpImages.elementAt( i - 1 ).equals( "*" );
				lResult += (lIsMult ? " times " : " divide ")
						+  lFactorImages.elementAt( i )
						;
			}
			return lResult;
		}
	}
} // end Gpl.Term()

String
Factor() :
{
	Token lParOpenToken, lParClosedToken;
	Token lUnaryMinus;
	String lResult;
}
{
	lResult = Primary()
	{
		return lResult;
	}

|	lParOpenToken = <PAR_OPEN>	lResult = Expression() lParClosedToken =
<PAR_CLOSED>
	{
		lResult = lParOpenToken + " " + lResult + " " + lParClosedToken;
		return lResult;
	}
|	lUnaryMinus = <UNARY_MINUS> lResult = Factor()
	{
		lResult = lUnaryMinus + lResult;
		return lResult;
	}
} // end Gpl.Factor()

// Narrows the accepted input to group identifiers which do NOT
contain any GROUP_ID_SEPARATOR
// see also comp.compilers.tools.javacc, Unit tests for JavaCC tokens
and productions
String
Id() :
{
	Token lToken;
	String lResult;
	disable_tracing();
}
{
	lToken = <GROUP_ID>
	{
		lResult = lToken.image;
		String lQuotedGroupIdSeparator =
GplConstants.tokenImage[GROUP_ID_SEPARATOR];
		int lIndexOfHeadingingQuotes =
lQuotedGroupIdSeparator.indexOf( '"' );
		int lIndexOfTrailingQuotes =
lQuotedGroupIdSeparator.lastIndexOf( '"' );
		String lGroupIdSeparator =
lQuotedGroupIdSeparator.substring( lIndexOfHeadingingQuotes + 1,
lIndexOfTrailingQuotes );
        if ( lResult.indexOf( lGroupIdSeparator ) != -1 )
		{
			throw new ParseException( "\"" + lGroupIdSeparator +
"\" (<GROUP_ID_SEPARATOR>) in identifier: " + lResult );
		}
        return lResult;
	}
} // end Gpl.Id()

String
GroupId() :
{
	Token lToken;
	String lResult;
}
{
	lToken = <GROUP_ID>
	{
		lResult = lToken.image;
		return lResult;
	}
} // end Gpl.GroupId()

String
Primary() :
{
	Token lToken;
	String lResult;
}
{
	lToken = <GROUP_ID>
	{
		lResult = lToken.image;
		return lResult;
	}
} // end Gpl.Primary()

// EOF, in unit testing allows to test a given input and not a prefix
// (see also:
http://groups.google.com/group/comp.compilers.tools.javacc/browse_thread/thread/e33401b7c7c81b66/cede39f37111bc73#cede39f37111bc73)
String
Eof() :
{
	Token lToken;
	String lResult;
}
{
	lToken = <EOF>
	{
		lResult = lToken.image;
		return lResult;
	}

	// <NUMBER_LITERAL> here soon
} // end Gpl.Eof()
 




 8 Posts in Topic:
Unary minus
Cesare Zecca <Cesare.Z  2007-09-20 11:05:37 
Re: Unary minus
AC <user@[EMAIL PROTEC  2007-09-20 08:10:38 
Re: Unary minus
Cesare Zecca <Cesare.Z  2007-09-20 13:49:39 
Re: Unary minus
Cesare Zecca <Cesare.Z  2007-09-21 17:29:53 
Re: Unary minus
AC <user@[EMAIL PROTEC  2007-09-22 07:02:15 
Re: Unary minus
Cesare Zecca <Cesare.Z  2007-09-21 17:37:14 
Re: Unary minus
AC <user@[EMAIL PROTEC  2007-09-22 07:03:32 
Re: Unary minus
Cesare Zecca <Cesare.Z  2007-09-24 07:32:36 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Fri Jul 25 2:16:19 CDT 2008.