An other question about jep (grammar)

112 views
Skip to first unread message

guillau...@gmail.com

unread,
Aug 14, 2008, 4:43:15 AM8/14/08
to JEP Users
Hi,
I follow the integration of your API in my application,
but I meet some new problems in my expressions.
This time I got a conditionnal expression a bit more complicate,
I can't format this one like the parser want, this is my expression :

A_N_E =
if (CT == 1,
(L_c / L_u) -1,
if (CT == 2,
if (TP == 1,
0.46,
if (TP == 2,
(84/(L * PE(81/(L + 0.5)))) -1,
if (TP == 3,
(81/(L * PE(78/(L + 0.5)))) -1,
if (CT == 3,
if (TP == 1 || 2,
0.46,
if (TP == 3,
1- L_c/ (PE(L_B/(L + 0,5)) * L ),
0))))))))

The parser launch me an error :
com.singularsys.jep.ParseException: Encountered "," at line 1, column
409.

Some help needed, thank's you in advance .
Guillaume

Richard Morris

unread,
Aug 14, 2008, 7:30:29 AM8/14/08
to jep-...@googlegroups.com

Last but one line has
> (L + 0,5),
You want
> (L + 0.5),

BTW you may find it easier to break the input into multiple lines
that way its easier to use the error message to identify the bug

String eqn = "A_N_E =\n"+
" if (CT == 1,\n"+
" (L_c / L_u) -1,\n"+
" if (CT == 2,\n"+
" if (TP == 1,\n"+
" 0.46,\n"+
" if (TP == 2,\n"+
" (84/(L * PE(81/(L + 0.5)))) -1,\n"+
" if (TP == 3,\n"+
" (81/(L * PE(78/(L + 0.5)))) -1,\n"+
" if (CT == 3,\n"+
" if (TP == 1 || 2,\n"+
" 0.46,\n"+
" if (TP == 3,\n"+
" 1- L_c/ (PE(L_B/(L + 0,5)) * L ),\n"+
" 0))))))))";

jep.parse(eqn);

Which gives me
com.singularsys.jep.ParseException: Encountered "," at line 15, column 47.
Line 15 column 47 is easier to find than line 1, column 409.

Rich
--
Richard Morris
Web: www.singsurf.org www.pfaf.org
Email: ri...@singsurf.org
Tel: (+44) 01208 872963
Post: 1 Lerryn View, Lerryn, Lostwithiel, Cornwall, PL22 0QJ

guillau...@gmail.com

unread,
Aug 14, 2008, 8:07:35 AM8/14/08
to JEP Users
Ok, I use your formalism it is much better to find the bug,
but after i correct the "," by a "."
I got now a new error :
Function "if" illegal number of arguments 2
From where it is come from i use the if formalism that you told me ...
thank's in advance

Guilllaume

On 14 août, 13:30, Richard Morris <r...@singsurf.org> wrote:
> Email: r...@singsurf.org

guillau...@gmail.com

unread,
Aug 14, 2008, 8:39:19 AM8/14/08
to JEP Users
I think I don't have really understand the way to write multi
conditionnal expression,
i explain, for a simple if i do :
if(test, process_if_true, process_if_false).

If i got 2 inside themself if :
if(test_1, process_if_true, if(test_2, process_if_test_2_true,
process_if_test_2_false),process_if_test_1_false,

I am quitte sure that i got a syntax problem with imbricate if
expression, so how can i do ??
Guillaume

Richard Morris

unread,
Aug 14, 2008, 1:04:49 PM8/14/08
to jep-...@googlegroups.com
guillau...@gmail.com wrote:
> I think I don't have really understand the way to write multi
> conditionnal expression,
> i explain, for a simple if i do :
> if(test, process_if_true, process_if_false).
>
> If i got 2 inside themself if :
> if(test_1, process_if_true, if(test_2, process_if_test_2_true,
> process_if_test_2_false),process_if_test_1_false,
>
> I am quitte sure that i got a syntax problem with imbricate if
> expression, so how can i do ??

You do have the syntax right, I think its a problem of just counting the
number of brackets right.

>>>> A_N_E =
>>>> if (CT == 1,
>>>> (L_c / L_u) -1,
>>>> if (CT == 2,
>>>> if (TP == 1,
>>>> 0.46,
>>>> if (TP == 2,
>>>> (84/(L * PE(81/(L + 0.5)))) -1,
>>>> if (TP == 3,
>>>> (81/(L * PE(78/(L + 0.5)))) -1,
>>>> if (CT == 3,
>>>> if (TP == 1 || 2,
>>>> 0.46,
>>>> if (TP == 3,
>>>> 1- L_c/ (PE(L_B/(L + 0,5)) * L ),
>>>> 0))))))))

Looking that this a switch statement might make things simpler

public class Switch extends PostfixMathCommand {
private static final long serialVersionUID = 330L;

public Switch() {
this.numberOfParameters = -1;
}

public void run(Stack<Object> stack) throws EvaluationException {
Object vals[] = new Object[this.curNumberOfParameters];
for(int i=this.curNumberOfParameters-1;i>=0;++i)
vals[i] = stack.pop();
int index = (Integer) vals[0];
if(index>= this.curNumberOfParameters)
throw new EvaluationException("Switch: condition out of range
"+index+" max "+(this.curNumberOfParameters-1));
stack.push(vals[index]);
}
}

using the above finction which could be added with
jep.addFunction("switch",new Switch());

you could then transform your code to

>>>> A_N_E =
>>>> switch(CT,
>>>> (L_c / L_u) -1,
>>>> switch(TP,
>>>> 0.46,


>>>> (84/(L * PE(81/(L + 0.5)))) -1,

>>>> (81/(L * PE(78/(L + 0.5)))) -1),
>>>> switch(TP,
>>>> 0.46,
>>>> 0.46,
>>>> 1- L_c/ (PE(L_B/(L + 0.5)) * L )))

Rich
--
Richard Morris
Web: www.singsurf.org www.pfaf.org

Email: ri...@singsurf.org

guillau...@gmail.com

unread,
Aug 20, 2008, 7:20:16 AM8/20/08
to JEP Users
Thanks for your help, i found a sort a path to the solution :

String formule = "A_N_E =\n"+
" if (CT == 1, \n"+
" if (TP == 1, \n"+
" 0.46, \n"+
" if (TP == 2, \n"+
" 66 , \n"+
" 2),3), \n" +
" if (CT == 2,\n"+
" if (TP == 1, \n"+
" 0.56, \n"+
" if (TP == 2, \n"+
" 67, \n"+
" 4),5), \n"+
" if (CT == 3,\n"+
" if (TP == 1, \n"+
" 0.66, \n"+
" if (TP == 2, \n"+
" 68, \n"+
" 6),7), \n"+
" if (CT == 4,\n"+
" if (TP == 1, \n"+
" 0.76, \n"+
" if (TP == 2, \n"+
" 69, \n"+
" 8),9), \n"+
" 1))))\n";

Ok this formula is wel parsed by jep, but I found something
interresting :
-Always check the number of brackets.
-you have to get a else statement inside each sub conditions

Thank's to richard again you help me a lot :)
Guillaume

On 14 août, 19:04, Richard Morris <r...@singsurf.org> wrote:
> Email: r...@singsurf.org

guillau...@gmail.com

unread,
Aug 20, 2008, 7:20:30 AM8/20/08
to JEP Users
Thanks for your help, i found a sort a path to the solution :

String formule = "A_N_E =\n"+
" if (CT == 1, \n"+
" if (TP == 1, \n"+
" 0.46, \n"+
" if (TP == 2, \n"+
" 66 , \n"+
" 2),3), \n" +
" if (CT == 2,\n"+
" if (TP == 1, \n"+
" 0.56, \n"+
" if (TP == 2, \n"+
" 67, \n"+
" 4),5), \n"+
" if (CT == 3,\n"+
" if (TP == 1, \n"+
" 0.66, \n"+
" if (TP == 2, \n"+
" 68, \n"+
" 6),7), \n"+
" if (CT == 4,\n"+
" if (TP == 1, \n"+
" 0.76, \n"+
" if (TP == 2, \n"+
" 69, \n"+
" 8),9), \n"+
" 1))))\n";

Ok this formula is wel parsed by jep, but I found something
interresting :
-Always check the number of brackets.
-you have to get a else statement inside each sub conditions

Thank's to richard again you help me a lot :)
Guillaume

On 14 août, 19:04, Richard Morris <r...@singsurf.org> wrote:
> Email: r...@singsurf.org

Richard Morris

unread,
Feb 5, 2013, 8:12:30 AM2/5/13
to jep-...@googlegroups.com
On Monday, February 4, 2013 6:31:01 AM UTC, Tikeshwar Sahu wrote:
Cann't we have any solution to parse 3,5 as floating point number..without changing COMMA to DOT?


Surprisingly easy using the ConfigurableParser. Two steps are needed firstly we need a TokenMatcher to match the numbers in the input. It need a regular expression to match the syntax you want. Then you need to convert the string so that java will recognise it. All this is coded in the class CommaNumberTokenMatcher. 

There is a problem with using , and it is normally used elsewhere in the grammar. The rules for function arguments and arrays are changed to use ; as a separator.

If you interesting in localization we have also be working on a externalising the strings used in jep so these can be customised for other languages. These string generally occur in the error messages.
 
Hope that helps

Richard




static class CommaNumberTokenMatcher extends NumberTokenMatcher {

private static final long serialVersionUID = 1L;


public CommaNumberTokenMatcher() {

super("(\\d+\\,?\\d*)|(\\,\\d+)");

}


@Override

public Token buildToken(String s) {

String s2=s.replace(',','.'); // convert string changing , to .

return super.buildToken(s2); // create a Token using the string, calls Double.valueof(String);

}

}


@Test

public void testCommaNumber() throws JepException {

ConfigurableParser cp = new ConfigurableParser();

        cp.addHashComments();

        cp.addSlashComments();

        cp.addSingleQuoteStrings();

        cp.addDoubleQuoteStrings();

        cp.addWhiteSpace();

        cp.addTokenMatcher(new CommaNumberTokenMatcher()); 

        cp.addExponentNumbers();

        cp.addOperatorTokenMatcher();

        cp.addSymbols("(",")","[","]",";"); // changed

        cp.setImplicitMultiplicationSymbols("(","[");

        cp.addIdentifiers();

        cp.addSemiColonTerminator();

        cp.addWhiteSpaceCommentFilter();

        cp.addBracketMatcher("(",")");

        cp.addFunctionMatcher("(",")",";"); // changed

        cp.addListMatcher("[","]",";"); // changed

        cp.addArrayAccessMatcher("[","]");

Jep jep = new Jep(cp);

jep.parse("24,9");

Object result = jep.evaluate();

assertEquals(24.9,result);


jep.parse("if(2,1 > 3,4 ; 5,6 ; 7,8)");

result = jep.evaluate();

assertEquals(7.8,result);

jep.parse("[2,1;3,4]");

result = jep.evaluate();

assertArrayEquals(new Object[]{2.1,3.4}, ((List<?>) result).toArray());


}

Tikeshwar Sahu

unread,
Feb 6, 2013, 2:18:42 AM2/6/13
to jep-...@googlegroups.com
i have FLOATING_POINT_LITERAL like this

< FLOATING_POINT_LITERAL:

        (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)?

        | "." (["0"-"9"])+ (<EXPONENT>)?

               
        | (["0"-"9"])+ <EXPONENT>

    >



here in place of  "."(DOT) i need to use "jep.decimalSymabol()"

< FLOATING_POINT_LITERAL:

        (["0"-"9"])+ "jep.decimalSymabol()" (["0"-"9"])* (<EXPONENT>)?

        | "jep.decimalSymabol()" (["0"-"9"])+ (<EXPONENT>)?

               
        | (["0"-"9"])+ <EXPONENT>

    >

where decimalSymabol() will  return either ","
or "." , means based on Locale. But whet it return "," then i ll be getting exception like

Caused by: com.singularsys.jep.parser.ParseException: Encountered " "," ","" at line 1, column 5.
Was expecting one of:
    "," ...
    ">" ...
    "<" ...
    "=" ...
    "<=" ...
    ">=" ...
    "<>" ...
    "&&" ...
    "||" ...
    "+" ...
    "-" ...
    "*" ...
    "." ...
    "/" ...
 what i am doing is wrong or??


--
You received this message because you are subscribed to the Google Groups "Jep Java Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jep-users+...@googlegroups.com.
To post to this group, send email to jep-...@googlegroups.com.
Visit this group at http://groups.google.com/group/jep-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Tikeshwar Sahu
Zoho Corporation Pvt. Ltd
+91-7871565242

Richard Morris

unread,
Feb 6, 2013, 3:30:28 AM2/6/13
to jep-...@googlegroups.com
Ah I see you using the older style javacc based parser rather than the newer ConfigurableParser one. The latter has been designed to make it easy to customise the grammar and you may find it easier to switch.

I'm not quite sure how javacc translates the regular expressions for tokens into actual code and don't know if you can embed java code in their specifications. You may find the parser is expecting the input
3jep.decimalSymabol()1415927

What you can do is make the parser switchable by setting a Lexical State in the parser. We've done this for the identifiers which can either have a dot in them or not

<DEFAULT> TOKEN:

{

<INDENTIFIER1: <LETTER1>(<LETTER1>|<DIGIT1>|".")*>

|

< #LETTER1:

[

"\u0024",           // $

"\u0041"-"\u005a",  // A - Z

"\u005f",           // _

"\u0061"-"\u007a",  // a - z

...

]

>

|

< #DIGIT1: ["0"-"9"] >

}


<NO_DOT_IN_IDENTIFIERS> TOKEN:

{

<INDENTIFIER2: <LETTER2>(<LETTER2>|<DIGIT2>)*>

|

< #LETTER2:

[

"\u0024",           // $

"\u0041"-"\u005a",  // A - Z

"\u005f",           // _

"\u0061"-"\u007a",  // a - z

...

]

>

|

< #DIGIT2: ["0"-"9"] >

}


Latter in the BNF grammar you need to allow for both types of token

String Identifier() :

{

  Token t;

}

{

( t = <INDENTIFIER1> | t = <INDENTIFIER2> ) { return t.image; }

}


You can then call 

public void setInitialTokenManagerState(int state)

to set the state, using the constants defined in JccParserConstants.


Good luck, I've found working with the JavaCC grammar quite a tricky thing to get right and would not recommend it.

Richard

Reply all
Reply to author
Forward
0 new messages