NULL token in JavaCC - java

I have strange problem with token
< NULL: "null" >
in my JavaCC parser.
In expression like
String IsNullClause():
{
String res = "";
}
{
<IS> {res += " IS ";}
[<NOT> {res += " NOT ";} ]
<NULL> {res += " NULL ";}
{
return res;
}
}
parser doesn't see NULL token and throws exception that "null" expected. If I change token definition to < NULL: "null_val" > or something else it works fine.
Is this my mistake or JavaCC doesn't accept 'null' as a token value?

There are sample Java language grammars in JavaCC package, with the following token difinition:
< NULL: "null" >
so I'm pretty sure JavaCC can handle null token.
Are you sure no token declared before NULL matches "null"? Tokens are matched in the order of declaration. You may try to declare NULL at the very beginning.

Related

Allowing apostrophes in the HTML input field

I have a php code as shown below which validates the answer at Line A which user enters in a html form.
When user enters any answer with apostrophe in the html input field form, I am getting the error message Secret Answer is Invalid.
For example: On entering Hello World', I am getting the error message Secret Answer is Invalid from Line Z.
//response
$response_error = new error();
$response_error->field = SECRET_response;
if($response != "" && $service->validAnswer($answer) != 'true'){ // Line A
$response_error->inError = true;
$response_error->errorMessage = SECRET_response.ISINVALID; // Line Z
} else {
$response_error->inError = false;
}
The Java code/method belonging to the validAnswer method used at Line A above is:
public static boolean validAnswer(String answer) {
Pattern a = Pattern.compile("^(?=.*\\S)[a-zA-Z0-9éèàêâçîëïÇÉÔÂÊÎÔÛËÏÀùÙ!#%&$%*\\- ]+$"); // Line B
Matcher b = a.matcher(answer);
logger.info("validAnswer: mmatches(): " + (b.matches()) + " a: " + a);
return b.matches();
}
Problem Statement:
I am wondering what changes I need to make in the java code above so that it takes apostrophe in the html input form.
This is what I have tried in the Java code:
I have put ' in at the end of [ ] inside of it. On trying that, it doesn't seem to work.
public static boolean validAnswer(String answer) {
Pattern a = Pattern.compile("^(?=.*\\S)[a-zA-Z0-9éèàêâçîëïÇÉÔÂÊÎÔÛËÏÀùÙ!#%&$%*\\-' ]+$"); // Line A
Matcher b = a.matcher(answer);
logger.info("validAnswer: mmatches(): " + (b.matches()) + " a: " + a);
return b.matches();
}
Calling Java from PHP just to use a regex is very weird and inefficient. PHP has regex support of course, so you don't need Java for that.
Anyway, your latest code works perfectly:
import java.util.regex.*;
public class Test
{
public static boolean validAnswer(String answer)
{
Pattern a = Pattern.compile("^(?=.*\\S)[a-zA-Z0-9éèàêâçîëïÇÉÔÂÊÎÔÛËÏÀùÙ!#%&$%*\\-' ]+$");
Matcher b = a.matcher(answer);
return b.matches();
}
public static void main(String args[])
{
System.out.println(validAnswer("Hello World'"));
}
}
Output:
true
So I guess you didn't recompile your code after modifying it.

Using regex in a variable

I'm trying to parse a file listed with applicable regex, accepting the regex string to a variable and then use it in a expression. But while in doing so I'm facing troubles with \ and could not use them. Below is the block which is using the code. Can you tell me why it is working for ""©?.*"" and not for ""©?\\s*\\w+.*"". The expression is valid otherwise.
String valuePattern = attrs.getNamedItem("valuePattern").getTextContent();
if (newNodeName == "") {
System.out.println(valuePattern);
// System.out.println("Inside Delete node...");
if (valuePattern == ""
|| (valuePattern != "" && node.getTextContent().matches(valuePattern))) {
System.out.println("in match");
System.out.println("Deleting: " + node.getTextContent());
node = null;
}
As Jon Skeet pointed out, first of all, you should repair your String comparison.
String valuePattern = attrs.getNamedItem("valuePattern").getTextContent();
if (("").equals(newNodeName) {
System.out.println(valuePattern);
if (("").equals(valuePattern)
|| (!("").equals(valuePattern) && node.getTextContent().matches(valuePattern))) {
System.out.println("in match");
System.out.println("Deleting: " + node.getTextContent());
node = null;
}
}

Why is my string doesn't accept null?

I need the String receive the null value if it is not found in mapper.getChave is what is returned. What I do? If I only get nullPointerException
for(String chave : linha.keySet()) {
//Processa chave
String novaChave = mapper.getChave(chave.trim());
if (!(novaChave == null || novaChave.isEmpty())) {
//Processa valor
String novoValor = linha.getString(chave);
temp.append(novaChave, novoValor);
}
else {
extras.append(chave, linha.getString(chave));
}
}
Log
java.lang.NullPointerException
at oknok.validacao.readers.PlanilhaReader.processaAtributosPlanilha(PlanilhaReader.java:237)
Line 237 is
String novaChave = mapper.getChave(chave.trim());
**UPDATE: The first time the loop runs, i have a Nullpointer and chave contains a value
System.out.println(chave.isEmpty() + "\t" + chave + "\t" + chave.trim());
Output
false Veículo Veículo
You need to add null check for mapper as well as chave.
if (mapper!= null && chave != null && !"".equals(chave) {
// do something
}
mapper.getChave(chave.trim())
^ ^ possible places for NPE.
Most probably value of chave or mapper would be null and you are calling trim() and .getChave() on them respectively causing nullpointer
You need to check whether chave is null before trimming it or doing anything else (I'm assuming that mapper is pre-initialised and not null, but you should check that too)
e.g.
if (chave != null && !"".equals(chave.trim()) {
// now do something
}
You may find it easier (more intuitive) to use something like Apache Commons StringUtils.isNotBlank(String). See here for the doc.
There is a null string reference in linha.keySet().
Follow code change null string to "" : you can change "" to anything you like
String novaChave = mapper.getChave((chave == null ? "" : chave).trim());

Getting the next token and remaining String with StreamTokenizer

I have a StreamTokenizer that will tokenize a String. I am interested in a way to get the next token from a String, as well as the remaining String (without the token we just took).
public static void parseString(String s){
StreamTokenizer st = new StreamTokenizer(new StringReader(s));
try {
while (st.nextToken() != st.TT_EOF){
if (st.ttype == st.TT_WORD){
System.out.println("Word: " + st.sval);
if (st.sval.equals("start")){
start(st.sval, ???)
}
}
else if (st.ttype == st.TT_NUMBER){
System.out.println("Number: " + st.nval);
}
else if (st.ttype == '\''){
System.out.println(st.sval);
}
else{
System.out.println((char)st.ttype);
}
}
} catch (IOException e){}
}
public String start(String text, String theRest){
return "<start>" + text + "" + parseString(theRest) + "</start>";
}
Some things I've tried:
I've tried just using the original String s but StreamTokenizer doesn't alter a String after it tokenizes it (I forget the word to describe this).
I could find the index of the current token, and slice that token out of the original string.
I was wondering if there was a more elegant way to go about this?
In regards to the first bullet point, I believe the word you're thinking of is probably "immutable". You're correct, anything that seems to be manipulating a String is in fact creating a new string; the original is left intact.
For the second bullet point, frankly I would have suggested the same as well. At the moment I cannot think of a better way.
Here's a general example:
int startIndex = s.indexOf(currentToken) + currentToken.length;
String remainingString = s.subString(startIndex, s.length-1);
If my string is "Hi my name is Paul", and the current token is "name", the result of remainingString should be " is Paul".
You could easily encapsulate that in a helper method somewhere to help keep things clean and separated.
Probably not the answer you're looking for, but hopefully that somewhat helps.

How do I use Java ScriptEngine to create a Javascript function

In this question I asked about supporting an expression language and used the Javascript idea sucessfully Putting a simple expression language into java
But the Javascript expressions required have become quite verbose and Im trying to work out how I can use ScriptEngine to create javascript functions that I can refer to in my expressions so that the expressions can be shorter.
So far I've hacked a solution by using reexp on the user entered string which can include a pseudo function called ifempty which I then convert to the javascript before passing to script engine
public final String formatFromMask(String mask,Song exampleSong)
{
mask = convertPsuedoFunctions(mask);
try
{
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
for(SongFieldName next:SongFieldName.values())
{
engine.put(next.getScriptVar(),exampleSong.getFieldValueOrEmptyString(next.getSongFieldKey()));
}
Object result = engine.eval(mask);
return (String)result;
}
catch(ScriptException se)
{
se.printStackTrace();
}
return "";
}
private String convertPsuedoFunctions(String mask)
{
//i.e ifnotempty(artist,' - ') -> (artist.length>0 ? artist + ' - ' : '')
mask=mask.replaceAll("ifnotempty\\(([a-z]*)\\,('.*')\\)",
"($1.length>0 ? $1 + $2 : '')");
return mask;
}
which could parse an expression such as
ifnotempty(album,'/')
+ ifnotempty(artist,' - ')
+ ifnotempty(album,' - ')
+ ifnotempty(track,' - ')
+ ifnotempty(title,'')
but I was wondering about a proper solution, whereby I actually create a real javascript function.
Why not creating a real Javascript function that you add to the script?
function ifnotempty(value,sep){
return value != undefined && value.length > 0 ? value + sep : '';
}
So your function becomes:
private String convertPsuedoFunctions(String mask)
{
return
"function ifnotempty(value,sep){return value!=undefined&&value.length>0?value+sep:'';}"
+ mask;
}
Additionally you can create a file with some default functions you support and prepend that to the users script. Just like above. But instead of one hardcoded function, you read the file into a String.
private static final String defaultFunctions =
com.google.common.io.Files.toString(new File("functions.js"),Charsets.US_ASCII);
private String convertPsuedoFunctions(String mask)
{
return defaultFunctions + mask;
}

Categories