why does 'a'..'z' in ANTLR match wildcards like $ or £ - lexer

When I run the following grammer:
test : WORD+;
WORD : ('a'..'z')+;
WS : ' '+ {$channel = HIDDEN;};
and I give the input "?test" why does antlr accept this as valid input? I thought the ('a'..'z') would only match characters within the lowercase alphabet?

ANTLR does produce an error when parsing the input string ?test with the grammar you posted. As is usually the case, the error lies with the tool being used around ANTLR (I see it happen a lot with ANTLRWorks as well, unfortunately!).
To test it yourself (properly), create a file Test.g:
grammar Test;
test : WORD+;
WORD : ('a'..'z')+;
WS : ' '+ {$channel = HIDDEN;};
and a file Main.java:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("?test");
TestLexer lexer = new TestLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
TestParser parser = new TestParser(tokens);
parser.test();
}
}
and download a copy of the ANTLR 3.2 JAR in the same directory.
Now generate a lexer & parser:
java -cp antlr-3.2.jar org.antlr.Tool Test.g
compile all Java source files:
javac -cp antlr-3.2.jar *.java
and run the Main class:
java -cp .:antlr-3.2.jar Main
(replace the : with ; if you're on Windows!)
which will produce the following error message:
line 1:0 no viable alternative at character '?'

Related

Copy Groovy Variable into File

In groovy log info I need to copy Groovy variable data into one file.
log.info('duplicates' + duplicates);
def a = vars.get ("duplicate");
new File('/Duplicate.txt').with {
delete()
withWriter { w ->
w.writeLine(a)
}
}
Facing with below issue:
javax.script.ScriptException: javax.script.ScriptException: java.lang.NullPointerException at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:158)
How can I debug this?
Most probably your duplicate JMeter Variable doesn't exist or hasn't been set.
If this question is a continuation of that one you can write duplicate values into a file like:
def myFile = new File('Duplicate.txt')
if (myFile.exists()) {
myFile.delete()
}
duplicates.unique().each { duplicate ->
myFile << duplicate.value << System.getProperty('line.separator')
}
Demo:
More information: Apache Groovy - Why and How You Should Use It

Error while doing Data-Driven Testing in JMeter using data in Excel

I am attempting to read xmls stored in one column of an Excel spreadsheet and fire them to a server using HTTP Sampler and then store the response xml in the same Excel.
This is the structure of my test plan in JMeter:
However I have encountered and error.
I am not able to pinpoint the exact place where the error is taking place but I have obtained the error message from the Results Tree are as follows:
for the JSR223 Sampler
Response message: javax.script.ScriptException: Sourced file: inline
evaluation of: import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.us . . . '' : Typed variable declaration :
Attempt to resolve method: parseInt() on undefined variable or class
name: INTEGER : at Line: 6 : in file: inline evaluation of:import
org.apache.poi.xssf.usermodel.XSSFWorkbook; import
org.apache.poi.xssf.us . . . '' : INTEGER .parseInt ( vars .get (
"counter" ) ) in inline evaluation of: ``import
org.apache.poi.xssf.usermodel.XSSFWorkbook; import
org.apache.poi.xssf.us . . . '' at line number 6
The error in the HTTP Request Sampler's Response Data tab reads as:
Exception occured: Parsing xml error, xml string is:${RQI}
BeanShell Assertion error is :
Assertion error: true Assertion failure: false Assertion failure
message: org.apache.jorphan.util.JMeterException: Error invoking bsh
method: eval In file: inline evaluation of: ``import
org.apache.poi.xssf.usermodel.XSSFWorkbook; import
org.apache.poi.xssf.us . . . '' Encountered ":" at line 6, column 65.
This is the code that I had used in the JSSR223 Sampler in the While Controller:
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import java.io.*;
int i = INTEGER.parseInt(vars.get("counter"));
XSSFRow row = vars.getObject("book").getSheetAt(0).getRow(i);
vars.putObject("row", row);
for (int j = 1; j <= vars.getObject("book").getSheetAt(0).getRow(0).getLastCellNum(); j++) {
if (row.getCell(j) == null) {
row.createCell(j).setCellValue("");
}
}
String payload = row.getCell(1).toString();
vars.put("RQI",payload);
//String password = row.getCell(2).toString();
// vars.put("password",password);
//String expectedResult = row.getCell(5).toString();
// vars.put("expectedResult",expectedResult);
Please assist. Also, feel free to ask for more information as I have left out the code for the other JSR223 Samplers in this post for brevity. Thank you in advance.
You must change this line:
INTEGER.parseInt(vars.get("counter"));
to this one
Integer.parseInt(vars.get("counter"));
check out Integer class JavaDoc - Integer.parseInt()
You should be using JSR223 Test Elements instead of Beanshell test elements and you should be using Groovy language in the JSR223 Test Elements
You might find How to Implement Data Driven Testing in your JMeter Test reference useful.

Why EOF does not match with the grammar?

I have this simple grammar
grammar Monto;
import util;
documento: .*? monto .+;
monto: SYMBOL INT+;
SYMBOL: '$';
And when I run that I get this error:
line 1:0 mismatched input '<EOF>'
I added EOF to my main rule but it does not works, I tried with this
documento: .*? monto .+ EOF;
or this
documento: .*? monto .+? EOF;
The curious is when I run that from cmd(ANTLR4 tool) it works
EDITED
I'm using ANLTR 4.7.1 and this is how I create the lexers and parsers
public GrammarModule(String text) {
CharStream input = CharStreams.fromString(text);
demandantesLexer = new DemandantesLexer(input);
demandantesParser = new DemandantesParser(new CommonTokenStream(demandantesLexer));
demandadosLexer = new DemandadosLexer(input);
demandadosParser = new DemandadosParser(new CommonTokenStream(demandadosLexer));
direccionLexer = new DireccionLexer(input);
direccionParser = new DireccionParser(new CommonTokenStream(direccionLexer));
fechaLexer = new FechaLexer(input);
fechaParser = new FechaParser(new CommonTokenStream(fechaLexer));
montoLexer = new MontoLexer(input);
montoParser = new MontoParser(new CommonTokenStream(montoLexer));
numCuentaLexer = new NumCuentaLexer(input);
numCuentaParser = new NumCuentaParser(new CommonTokenStream(numCuentaLexer));
oficioLexer = new OficioLexer(input);
oficioParser = new OficioParser(new CommonTokenStream(oficioLexer));
referenciaLexer = new ReferenciaLexer(input);
referenciaParser = new ReferenciaParser(new CommonTokenStream(referenciaLexer));
}
Invoking the parsers
fechaParser.documento().fecha().getText();
montoParser.documento().monto().getText();
so on...
All of your lexers read from the same stream and presumably all of your grammars consume the entire input (at least Monto does and I expect Fecha does as well). You also don't appear to reset the input stream between the invocations of the different parsers. So after you invoke the Fecha parser, the input stream will be empty because the parser consumed all the input. So when you invoke the Monto parser, it reads from an empty stream and produces an error because the grammar does not match the empty input.
Instead you should just create a different CharStream instance for each lexer.

Creating if/else statements, and scanners based on the keyword in as string.

I'm trying to have my code search for specific keywords, and based on those specific keywords create a scanner user-input prompt to replace such keywords.
For example, in the txt file:
Hi my name is < name>, What is your name? is your name < name>?
I like to eat < food>. Do you?
The program should detect the "< name>" and prompt the user to enter in a name twice for different keywords.
So far I have this:
// Java program to illustrate reading from Text File
// Using scanner class
import java.io.File;
import java.util.Scanner;
public class TxtOutput{
public static void main(String[] args) throws Exception
{
// pass the path to the file as a parameter
File file = new File("C:\\Users\\aaron\\Documents\\TestTXT\\test.txt");
Scanner sc = new Scanner(file);
//Types of keywords
//<adjective>, <plural-noun>, <place>, <noun>, <funny-noise>, <person's-name>, <job>, <CITY>, , <Color!>
//, <Exciting-adjective>, <Interersting-Adjective>, <aDvErB>, <NUMBER>, <Plural-noun>, <body-part>, <verb>,
//<Number>, <verB>, <job-title>,
String data1 = sc.nextLine();
if (data1.contains("<job>"));
Scanner user_input = new Scanner (System.in);
String job1;
System.out.println("Enter a profession");
job1 = user_input.next();
String replacedData1 = data1.replace("<job>", job1 );
System.out.println(replacedData1);
}
}
The program can only detect one keyword and it has a pre-made if and else statement. Is there a way to make an if and else statement with a scanner based on the keywords such as "< name>" or "< food>" in a line?
I don't want to bombard this program with an unnecessary amount of pre-made if and else statements. I was wondering if there's a more efficient way to do this.
You could search the whole data file for <..> keyword templates using regex, add the keywords found to a unique Set, and then loop over the keywords to ask for replacements. I think you like this:
I suggest specifying the keyword templates explicitly using alternations | in the regex like that:
<adjective>|<plural-noun>|<place>|<noun>|<funny-noise>|<person's-name>|<job>|<CITY>|<Color!>|<Exciting-adjective>|<Interersting-Adjective>|<aDvErB>|<NUMBER>|<Plural-noun>|<body-part>|<verb>|<Number>|<verB>|<job-title>
Demo
We could use a generic regex like <[^<>]+> but I don't know what else is in your file. Give it a try.
Putting everything together, complete sample:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Ideone {
public static void main(String[] args) throws java.lang.Exception {
Set < String > uniqueKeywords = new HashSet < String > ();
final String regex = "<adjective>|<plural-noun>|<place>|<noun>|<funny-noise>|<person's-name>|<job>|<CITY>|<Color!>|<Exciting-adjective>|<Interersting-Adjective>|<aDvErB>|<NUMBER>|<Plural-noun>|<body-part>|<verb>|<Number>|<verB>|<job-title>";
final String filecontent = "Text template containing all sorts of .. <adjective>, <plural-noun>, <place>, <noun>, <funny-noise>, <person's-name>, <job>, <CITY>, , <Color!> <Exciting-adjective>, <Interersting-Adjective>, <aDvErB>, <NUMBER>, <Plural-noun>, <body-part>, <verb>, <Number>, <verB>, <job-title>, String data1 = sc.nextLine(); blah blah";
final Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
final Matcher matcher = pattern.matcher(filecontent);
while (matcher.find()) {
uniqueKeywords.add(matcher.group(0));
}
Scanner user_input = new Scanner(System.in);
for (String keyword: uniqueKeywords) {
System.out.println("Enter a " + keyword);
String replacement = user_input.next();
String replacedData1 = filecontent.replace(keyword, replacement);
System.out.println(replacedData1);
}
}
}

Groovy split using file.seperator

I'm getting an error as follows
Groovy script throws an exception of type class
java.util.regex.PatternSyntaxException with message =
Unexpected internal error near index 1
\
^
from the Split statement as follows:
String strClassPath = System.getProperty("java.class.path");
String[] path = strClassPath.split(System.getProperty("file.separator"));
How should I make this work correctly for both UNIX and Windows systems (that's why I'm using "file.separator")
Many thanks in advance
This calls java's split(String regexp). So your input must be a regexp (or must be quoted):
import java.util.regex.Pattern
def cp = {path, sep ->
path.split(Pattern.quote(sep))
}
assert cp('C:\\window\\something\\groovy.jar', '\\') == ['C:', 'window', 'something', 'groovy.jar']
assert cp('/usr/local/share/groovy.jar', '/') == ['', 'usr', 'local', 'share', 'groovy.jar']
So much for the regexp/split. If you are after the path, you might be better off using Path. e.g.
assert new File('/usr/local/share/groovy.jar').toPath().collect()*.toString() == ['usr', 'local', 'share', 'groovy.jar']

Resources