I'm a newly to javacc. I tried to parse an existing javacc grammar (its the JSR341, EL 3.0 Grammar). It generates (almost) correct java. However, the generated code contains an illegal switch statement. I'm using the ph-javacc-maven-plugin.
private int jjMoveStringLiteralDfa0_0(){
switch(curChar)
{
case '#':
return jjMoveStringLiteralDfa1_0(0x8L);
case '$':
return jjMoveStringLiteralDfa1_0(0x4L);
case '\': // should be '\\'
return jjStartNfaWithStates_0(0, 4, 2);
default :
return jjMoveNfa_0(7, 0);
}
}
This is the offending grammar section from JS341 (although I'm not sure its the grammar itself) that's causing the problem:
<DEFAULT> TOKEN :
{
< LITERAL_EXPRESSION:
((~["\\", "$", "#"])
| ("\\" ("\\" | "$" | "#"))
| ("$" ~["{", "$"])
| ("#" ~["{", "#"])
)+
| "$"
| "#"
>
|
< START_DYNAMIC_EXPRESSION: "${" > {stack.push(DEFAULT);}:
IN_EXPRESSION
|
< START_DEFERRED_EXPRESSION: "#{" > {stack.push(DEFAULT);}:
IN_EXPRESSION
}
<DEFAULT> SKIP : { "\\" }
I played around with the options (JAVA_UNICODE_ESCAPE, UNICODE_INPUT) and grammar. But without result.
Question: how do I make javacc generate valid Java switch statement, i.e., with '\\' instead of '\'?
The observed behaviour is an issue and will be solved in parser-generator-cc 1.1.0.
I have this datatable in my cucumber scenario:
| name | value
| Description | one \n two \n three |
I want the values to appear in the textarea like this:
one
two
three
Because I need to make bullet points out of them.
So my actual question is, is it possible to use newline characters in one line or is there a better way to approach this?
EDIT: to clarify, it's not working with the code written above:
WebDriverException: unknown error: Runtime. evaluate threw exception: SyntaxError: Invalid or unexpected token
EDIT 2: I'm using a bit of unusual code to access the value, seeing as it is a p element and this is normally not possible:
js.executeScript("document.getElementsByTagName('p')[0].innerHTML = ' " + row.get("value") + " ' ");
This has been working for other rows tho, maybe because i'm using \n now?
You can try this way:
WebDriver driver = new ChromeDriver();
driver.get("https://stackoverflow.com/questions/51786797/newline-in-datatable-gherkin-cucumber/51787544#51787544");
Thread.sleep(3000); // pause to wait until page loads
String s = "SOME<br>WORDS";
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementsByTagName('div')[0].innerHTML = '" + s + "';");
Output:
SOME
WORDS
So, main idea is to use <br> tag as new line separator.
In your case it would be like this:
| name | value
| Description | one<br>two<br>three |
and code would be:
// make sure, that row.get("value") returns a string
js.executeScript("document.getElementsByTagName('p')[0].innerHTML = ' " + row.get("value") + " ' ");
I have records in database that contains \n.
NAME | ROW | COL
-------------------------------
name | 1 | 1
address | 1 | 2
tel\n no | 1 | 3
employeed\n id | 1 | 4
Then, I also save my delimiter , for text writing, in Database (\t)
DELIMITER | FILENAME_LOCATIO
----------------------
\t | SAMPLETEXT
Then, when I already want to write those values(first table) to a text file, it prints like this..it does not recognized the escape characters, instead it printed as ordinary text
name\taddress\ttelno\n no\temployeed\n id
Text file should look like this..
name address telno
no employeed
id
Here is the code im using..
FileWriter fw = new FileWriter(config.get("FILENAME_LOCATION").toString(), true);
BufferedWriter w = new BufferedWriter(fw);
List<Map<String, Object>> headers = sampleMapper.selectHeader();
for (Iterator<Map<String, Object>> iterator = headers.iterator(); iterator.hasNext();) {
Map<String, Object> map = (Map<String, Object>) iterator.next();
w.write(map.get("NAME").toString());
w.write(config.get("DELIMITER").toString()); // returns \t in String format
}
w.close();
It might depend on the OS you are running your application on, at least for the line delimiter.
try (BufferedWriter w = new BufferedWriter(new FileWriter("c:\\test.txt", false)))
{
w.write("hello");
w.write("\t");
w.write("hello");
w.write(System.getProperty("line.separator"));
w.write("world");
w.write("\t");
w.write("world");
}
catch (IOException e)
{
e.printStackTrace();
}
This code runs fine on my Windows, as the system property will provide you with the correct delimiter for the machine you're on (on Windows, it is \r\n).
According to this question, \t should work, and it does for me. It might be that your config does not give you a tab, but "\\t", which means a literal \ and a t. In that case, you could store the ascii char for tab in the database instead of \t.
I have a need to collect a subset of info from log files that reside on one-to-many log file servers. I have the following java code that does the initial data collection/filtering:
public String getLogServerInfo(String userName, String password, String hostNames, String id) throws Exception{
int timeout = 5;
String results = "";
String[] hostNameArray = hostNames.split("\\s*,\\s*");
for (String hostName : hostNameArray) {
SSHClient ssh = new SSHClient();
ssh.addHostKeyVerifier(new PromiscuousVerifier());
try {
Utils.writeStdOut("Parsing server: " + hostName);
ssh.connect(hostName);
ssh.authPassword(userName, password);
Session s = ssh.startSession();
try {
String sh1 = "cat /logs/en/event/event*.log | grep \"" + id + "\" | grep TYPE=ERROR";
Command cmd = s.exec(sh1);
results += IOUtils.readFully(cmd.getInputStream()).toString();
cmd.join(timeout, TimeUnit.SECONDS);
Utils.writeStdOut("\n** exit status: " + cmd.getExitStatus());
} finally {
s.close();
}
} finally {
ssh.disconnect();
ssh.close();
}
}
return results;
}
The results string variable looks something like this:
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:31 253 AM, HOST=server1, APPLICATION=app1, FUNCTION=function1, STATUS=null, GUID=null, etc. etc.
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:59 123 AM, HOST=server1, APPLICATION=app1, FUNCTION=function1, STATUS=null, GUID=null, etc. etc.
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:28 956 AM, HOST=server2, APPLICATION=app1, FUNCTION=function2, STATUS=null, GUID=null, etc. etc.
I need to accomplish the following:
What do I need to do to be able to sort results by TIMESTAMP? It is unsorted right now, because i am enumerating one to many files, and appending results to end of a string.
I only want a subset of "columns" returned, such as TYPE, TIMESTAMP, FUNCTION. I thought i could REGEX it in the grep, but maybe arrays would be better?
Results are simply being printed to console/report, as this is only printed for failed tests, and is there for troubleshooting purposes only.
I took the list of output that you provided and put it in a file, named test.txt, making sure that each "TYPE=ERROR etc. etc" was in a new line (I guess it's the same in your output, but it isn't clear).
Then I used cat test.txt | cut -d',' -f1,2,5 | sort -k2 to do what you want.
cut -d',' -f1,2,5 basically splits by comma and only reports tokens number 1,2,5 (TYPE,TIMESTAMP,FUNCTION). If you want more, you can add more numbers depending on what token you want
sort -k2 sorts according to the 2nd column (TIMESTAMP)
The output I get is:
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:28 956 AM, FUNCTION=function2
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:31 253 AM, FUNCTION=function1
TYPE=ERROR, TIMESTAMP=10/03/2015 07:14:59 123 AM, FUNCTION=function1
So what you should try and do, is to further pipe your command with |cut -d',' -f1,2,5 | sort -k2
I hope it helps.
After working on this some more, i come to find that one of the key/value pairs allows commas in the values, thus cut will not work. Here is the finished product:
My grep command stays the same, collecting data from all servers:
String sh1 = "cat /logs/en/event/event*.log | grep \"" + id + "\" | grep TYPE=ERROR";
Command cmd = s.exec(sh1);
results += IOUtils.readFully(cmd.getInputStream()).toString();
Put the string into an array, so i can process them line by line:
String lines[] = results.split("\r?\n");
I then used regex to get the data i needed, repeating the below for each line in the array, and for as many columns as needed. It's a bit of a hack, I probably could have done it better by simply replacing the comma in the offending key/value pair, then using SPLIT() and comma as delimeter, then looping for the fields i want.
lines2[i] = "";
Pattern p = Pattern.compile("TYPE=(.*?), APPLICATION=.*");
Matcher m = p.matcher(lines[i]);
if (m.find()) {
lines2[i] += ("TYPE=" + m.group(1));
}
Finally, this will sort by Timestamp, since it is 2nd column:
Arrays.sort(lines2);
I'm trying to create a parser for source code like this:
[code table 1.0]
code table code_table_name
id = 500
desc = "my code table one"
end code table
... and here below is the grammar I defined:
PARSER_BEGIN(CodeTableParser)
...
PARSER_END(CodeTableParser)
/* skip spaces */
SKIP: {
" "
| "\t"
| "\r"
| "\n"
}
/* reserved words */
TOKEN [IGNORE_CASE]: {
<CODE_TAB_HEADER: "[code table 1.0]">
| <CODE_TAB_END: "end" (" ")+ <CODE_TAB_BEGIN>>
| <CODE_TAB_BEGIN: <IDENT> | "code" (" ")+ "table">
| <ID: "id">
| <DESC: "desc">
}
/* token images */
TOKEN: {
<NUMBER: (<DIGIT>)+>
| <IDENT: (<ALPHA>)+>
| <VALUE: (<ALPHA> ["[", "]"])+>
| <STRING: <QUOTED>>
}
TOKEN: {
<#ALPHA: ["A"-"Z", "a"-"z", "0"-"9", "$", "_", "."]>
| <#DIGIT: ["0"-"9"]>
| <#QUOTED: "\"" (~["\""])* "\"">
}
void parse():
{
}
{
expression() <EOF>
}
void expression():
{
Token tCodeTab;
}
{
<CODE_TAB_HEADER>
<CODE_TAB_BEGIN>
tCodeTab = <IDENT>
(
<ID>
<DESC>
)*
<CODE_TAB_END>
}
The problem is that the parser correctly identifies token ("code table")... but it doesn't identifies token IDENT ("code_table_name") since it contains the words already contained in token CODE_TAB_BEGIN (i.e. "code"). The parser complains saying that "code is followed by invalid character _"...
Having said that, I'm wondering what I'm missing in order to let the parser work correctly. I'm a newbie and any help would be really appreciated ;-)
Thanks,
j3d
Your lexer will never produce an IDENT because the production
<CODE_TAB_BEGIN: <IDENT> | "code" (" ")+ "table">
says that every IDENT can be a CODE_TAB_BEGIN and, as this production comes first, it beats the production for IDENT by the first match rule. (RTFFAQ)
Replace that production by
<CODE_TAB_BEGIN: "code" (" ")+ "table">
You will run into trouble with ID and DESC, but this gets you past the second line of input.