ANTLRWorks generates Parser declaring throws but nothing else in java file - java

I just started looking into ANTLR, and noticed ANTLRWorks 1.5 generates the Java parser file, but with incomplete throws declaration.
Grammar file:
grammar ASTDemo;
options {
output=AST;
}
parse
: orexpr+
| andexpr+
| TAG ' ' parens
| TAG (parens andexpr)+
| together+
;
parens
: '(' TAG ')';
andexpr
: TAG (AND^ TAG)+;
orexpr
: '[' TAG (OR^ TAG)+ ']';
together
: TAG (' '^ TAG)*
;
TAG : ('FOO' | 'BAR');
OR : '|';
AND : ': ';
WS : (' ')+;
Here is the sample line that has the incomplete throws statement
public final ASTDemoParser.parse_return parse() throws {
The current version of JDK being used to launch ANTLRWorks is 1.6x
Has anyone seen this before?
The unfortunate part, with this compile error ANTLRWorks is not allowing me to Debug my grammar within it. I'm forced to manually fix the file each time I want to test.

I have just compiled your grammar using ANTLRWorks 1.5 rc1 and JDK 1.7.0.11.
All compiled well, and mentioned code line looks like:
public final ASTDemoParser.parse_return parse() throws RecognitionException {
It could be arbitrary bug manifestation. Try to recompile it again, and may be you have try to use JDK 1.7.

Related

Spring Boot + Cucumber test: cucumber cannot detect my step definition method due to double quotation escaping in JSON

In a Spring Boot REST application, I want to check with Cucumber-jvm that the returned JSON is exactly what I expect. However, because I have to use double quotation around JSON key names, Cucumber cannot detect the correct step definition method and thus the test cannot pass.
Here is the expected JSON result:
{"fields":[],"errorMsg":"BIN not found"}
Cucumber step definition:
Given bin number is <bin>
When binlookup searches with this bin number
Then binlookup returns <result> and status code <code>
Examples:
| bin | result | code |
| "222222" | "{\"fields\":[\"bin\"]\,\"errorMsg\":\"Invalid Argument\"}" | 404 |
The corresponding method:
#Then("^binlookup returns \"([^\"]*)\" and status code \\d$")
public void binlookup_returns_and_status_code(String result, Integer code) throws Exception {
assertThat(this.results.getResponse().getContentType()).isEqualTo(MediaType.APPLICATION_JSON_UTF8_VALUE);
assertThat(this.results.getResponse().getStatus()).isEqualTo(code);
assertThat(this.results.getResponse().getContentAsString().length()).isNotEqualTo(0);
assertThat(this.results.getResponse().getContentAsString()).isEqualTo(result);
}
When running the test, I do have correct returned JSON:
{"fields":["bin"],"errorMsg":"Invalid Argument"}
But I see test errors and Cucumber cannot detect my method, and gives me tips like:
You can implement missing steps with the snippets below:
#Then("binlookup returns {string}\\:[],\\{string}\\:\\{string} and status code {int}")
public void binlookup_returns_and_status_code(String string, String string2, String string3, Integer int1) {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
Obviously, it pairs the first " with the first escaped " and sees {\"fields as the first parameter, but it is wrong.
But, I cannot quote the JSON string with ' ' because it will not be the case.
What can I do?
If it is impossible, how can I verify the JSON has the data I expect?
I read today somewhere that from now on, regex will be deprecated(reason unknown), and they are moving to Cucumber expression. I am with Cucumber 3.0.2, where Cucumber expression is available. So I tried that and suddenly, all is fine now.
I also noted that I have some error in the OP, and I corrected them too.
I also find that you can use single quotation mark around the whole string, so if you have many double quotations to escape, you should surround the whole string with single quotation and you can avoid escaping the double quotation then.
Now I have:
Examples:
| bin | result | code |
| "222222" | '{"fields":[],"errorMsg":"BIN not found"}' | 404 |
And method annotated like:
#Then("binlookup returns {string} and status code {int}")
public void binlookup_returns_and_status_code(String result, Integer code) throws Exception {
...
(Note that regex cannot coexist with cucumber expression; ^ and $ and other things will cause parsing error in cucumber expression)
And I can pass all the tests. At least in Eclipse. In IntelliJ I don't know.
...
Then binlookup returns '{"fields":[],"errorMsg":"BIN not found"}' and status code 404 # BinInfoControllerCucumberTests.binlookup_returns_and_status_code(String,Integer)
You can see that the method is found. Before was null(cannot be found).
Single quotation + regex expression does not work.
Remember: in the string, just escape the symbol which you use to surround the whole string, which can be single or double quotation.
The cucumber's stepdefs is all about regex. The arguments are captured using capture groups, you only need to use a regex that match the json.
I think it would work to you:
#Then("^binlookup returns \"(.*)\" and status code \\d$")
The \"(.*)\" regex will capture everything inside double quotes.
The entire regex is: "binlookup returns ", followed by everything inside double quotes (the \"(.*)\" regex), followed by " and status code ", followed by a number (the \d regex).
And in the stepDef file:
Examples:
| bin | result code |
| "222222" | "{"fields":["bin"],"errorMsg":"Invalid Argument"}" | 404 |
Note that you don't need to escape the double quotes inside json using this approach.
use the #DocStringType cucumber expression introduced in Cucumber-JVM 5 (https://github.com/cucumber/cucumber-jvm/blob/main/release-notes/v5.0.0.md) instead of using regular expressions
You can find an example here https://blog.executeautomation.com/all-new-cucumber-jvm-5-with-its-cucumber-expression
If a single quote (') is used at the step level and if the step is defined with {string} place holder this can be achieved. I was on cucumber version 6.10.3. Pretty sure this will work on some previous versions(maybe version 4.0.0+) too.
Create a stepdefintion like:
#Then("binlookup returns {string} and status code {int}")
public void binlookupReturnsAndStatusCode(String result, Integer code) throws Exception {
System.out.println(result);
System.out.println(code);
}
And scenario like below where the json string doesn't have to be escaped:
Given bin number is <bin>
When binlookup searches with this bin number
Then binlookup returns '<result>' and status code <code>
Examples:
| bin | result | code |
| "222222" | {"fields":["bin"],"errorMsg":"Invalid Argument"} | 404 |

antlr4 rule not ignoring standalone open bracket

The situation:
rule : block+ ;
block : '[' String ']' ;
String : ([a-z] | '[' | '\\]')+ ;
Trick is String can contain [ without backslash escape and ] with backslasash escape, so in this example:
[hello\]world][hello[[world]
First block can be parsed correctly, but the second one... parser is trying find ] for every [. Is there way to say antlr parser to ignore this standalone [? I can't change format, but i need to find some workaround with antlr.
PS: Without antlr there is algorythm to avoid this, something like: collect [ in queue before we will find first ] and use only head of queue. But I really need antlr =_=
You can use Lexer modes.
Lexical modes allow us to split a single lexer grammar into multiple
sublexers. The lexer can only return tokens matched by rules from the
current mode.
You can read more about lexer rules in antlr documentation here.
First you will need to divide you grammar into separate lexer and parser. Than just use another mode after you see open bracket.
Parser grammar:
parser grammar TestParser;
options { tokenVocab=TestLexer; }
rul : block+ ;
block : LBR STRING RBR ;
Lexer grammar:
lexer grammar TestLexer;
LBR: '[' -> pushMode(InString);
mode InString;
STRING : ([a-z] | '\\]' | '[')+ ;
RBR: ']' -> popMode;
Working example is here.
You can read the documentation on lexer modes

What is the simplest way to parse logical expressions from a string in java? [duplicate]

I'm looking for some advice on my school project. I am supposed to create a program that takes a logical expression and outputs a truth table for it. The actually creating of the truth table for me is not difficult at all and I've already wrote the methods in Java for it. I would like to know if there are any classes in java that I could use to parse the expression for me and put it into a stack. If not I'm looking for help on parsing the expression. It's the parentheses that get me whenever I try and think it through. Also if this would be easier in any other language I would be open to doing it in that. Perl is probably my next best language.
Some examples
(P && Q) -> R
(P || Q || R) && ((P -> R) -> Q)
If you're allowed to use a parser generator tool like ANTLR, here's how you could get started. The grammar for a simple logic-language could look like this:
grammar Logic;
parse
: expression EOF
;
expression
: implication
;
implication
: or ('->' or)*
;
or
: and ('||' and)*
;
and
: not ('&&' not)*
;
not
: '~' atom
| atom
;
atom
: ID
| '(' expression ')'
;
ID : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
However, if you'd parse input like (P || Q || R) && ((P -> R) -> Q) with a parser generated from the grammar above, the parse tree would contain the parenthesis (something you're not interested in after parsing the expression) and the operators would not be the root of each sub-trees, which doesn't make your life any easier if you're interested in evaluating the expression.
You'll need to tell ANTLR to omit certain tokens from the AST (this can be done by placing a ! after the token/rule) and make certain tokens/rules the root of their (sub) tree (this can be done by placing a ^ after it). Finally, you need to indicate in the options section of your grammar that you want a proper AST to be created instead of a simple parse tree.
So, the grammar above would look like this:
// save it in a file called Logic.g
grammar Logic;
options {
output=AST;
}
// parser/production rules start with a lower case letter
parse
: expression EOF! // omit the EOF token
;
expression
: implication
;
implication
: or ('->'^ or)* // make `->` the root
;
or
: and ('||'^ and)* // make `||` the root
;
and
: not ('&&'^ not)* // make `&&` the root
;
not
: '~'^ atom // make `~` the root
| atom
;
atom
: ID
| '('! expression ')'! // omit both `(` and `)`
;
// lexer/terminal rules start with an upper case letter
ID : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
You can test the parser with the following class:
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Main {
public static void main(String[] args) throws Exception {
// the expression
String src = "(P || Q || R) && ((P -> R) -> Q)";
// create a lexer & parser
LogicLexer lexer = new LogicLexer(new ANTLRStringStream(src));
LogicParser parser = new LogicParser(new CommonTokenStream(lexer));
// invoke the entry point of the parser (the parse() method) and get the AST
CommonTree tree = (CommonTree)parser.parse().getTree();
// print the DOT representation of the AST
DOTTreeGenerator gen = new DOTTreeGenerator();
StringTemplate st = gen.toDOT(tree);
System.out.println(st);
}
}
Now to run the Main class, do:
*nix/MacOS
java -cp antlr-3.3.jar org.antlr.Tool Logic.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main
Windows
java -cp antlr-3.3.jar org.antlr.Tool Logic.g
javac -cp antlr-3.3.jar *.java
java -cp .;antlr-3.3.jar Main
which will print a DOT source of the following AST:
(image produced with graphviz-dev.appspot.com)
Now all you need to do is evaluate this AST! :)
In Perl you can use Regexp::Grammars to do the parsing. It may be a little on the "grenade to kill an ant" side, but it should work.
Edit: Here is a (very quick) example which might get you going.
#!/usr/bin/env perl
use strict;
use warnings;
use Regexp::Grammars;
use Data::Dumper;
my $parser = qr/
<nocontext:>
<Logic>
<rule: Logic> <[Element]>*
<rule: Element> <Group> | <Operator> | <Item>
<rule: Group> \( <[Element]>* \)
<rule: Operator> (?:&&) | (?:\|\|) | (?:\-\>)
<rule: Item> \w+
/xms; #/ #Fix Syntax Highlight
my $text = '(P && Q) -> R';
print Dumper \%/ if $text =~ $parser; #/ #Fix Syntax Highlight
Look into JavaCC or ANTLR.
Regexps won't work.
You can probably also run your own parser using StreamTokenizer.
Building an expression parser is easy. Attaching actions to compute a value as you parse it is easy, too.
I assume you can write a BNF for your expression language.
This answer shows you how to build a parser easily, if you have a BNF.
Is there an alternative for flex/bison that is usable on 8-bit embedded systems?
If you want to write your own parser, use the Shunting-yard algorithm to get rid of parentheses by converting the expression from infix into postfix notation or directly into a tree.
Another parser generator for Java is CUP.

Need help compilig an ANTLR grammar file

im new with ANTLR and I don´t know how to compile my grammar.
I´m using the v4.4 of ANTLR with a .g4 file that contains:
grammar JayGrammar;
program: KEYWORD_VOI KEYWORD_MAI SEPARATOR_PAB SEPARATOR_PCD (declarations statements);
declarations: (declaration)*;
declaration: (type identifiers);
type: (KEYWORD_INT | KEYWORD_BOO);
identifiers: (IDENTIFIER)*;
statements: (statement)*;
statement: (block | assignment | ifstatement | whilestatementk);
block: SEPARATOR_LAB statements SEPARATOR_LCD;
assignment: (IDENTIFIER OPERATOR_IGU expression);
ifstatement: KEYWORD_IF SEPARATOR_PAB expression SEPARATOR_PCD statement (KEYWORD_ELS statement)?;
whilestatementk: KEYWORD_WHI SEPARATOR_PAB expression SEPARATOR_PCD statement;
expression: conjunction ((OPERATOR_O) conjunction)*;
conjunction: relation ((OPERATOR_Y) relation)*;
relation: addition ((OPERATOR_REL) addition)*;
addition: term ((OPERATOR_SUM|OPERATOR_RES) term)*;
term: negation ((OPERATOR_POR|OPERATOR_DIV) negation)*;
negation:(OPERATOR_NO) factor;
factor: IDENTIFIER|LITERAL|SEPARATOR_PAB expression SEPARATOR_PCD;
INPUTELEMENT: (WHITESPACE|TOKEN);
WHITESPACE: (' '|'\t'|'\r'|'\n'|'\f');
TOKEN: (IDENTIFIER|KEYWORD_BOO|KEYWORD_ELS|KEYWORD_IF|KEYWORD_MAI|KEYWORD_VOI|KEYWORD_WHI|LITERAL
|SEPARATOR_COM|SEPARATOR_LAB|SEPARATOR_LCD|SEPARATOR_PAB|SEPARATOR_PCD|SEPARATOR_PYC
|OPERATOR_REL|OPERATOR_DIV|OPERATOR_IGU|OPERATOR_NO|OPERATOR_O|OPERATOR_POR|OPERATOR_RES|OPERATOR_SUM|OPERATOR_Y);
LITERAL: (BOOLEAN INTEGER);
KEYWORD_BOO: BOOLEAN;
KEYWORD_ELS:'else';
KEYWORD_IF: 'if';
KEYWORD_INT: 'int';
KEYWORD_MAI: 'main';
KEYWORD_VOI: 'void';
KEYWORD_WHI: 'while';
BOOLEAN: ('true'|'false');
INTEGER: (DIGIT+);
IDENTIFIER: (LETTER (LETTER| DIGIT)*);
DIGIT: ('0'..'9')+;
LETTER: ('a'..'z'|'A'..'Z')+;
SEPARATOR_PAB: '(';
SEPARATOR_PCD: ')';
SEPARATOR_LAB: '{';
SEPARATOR_LCD: '}';
SEPARATOR_PYC: ';';
SEPARATOR_COM: ',';
OPERATOR_IGU: ('=');
OPERATOR_SUM: ('+');
OPERATOR_RES: ('-');
OPERATOR_POR: ('*');
OPERATOR_DIV: ('/');
OPERATOR_REL: ('<'|'<='|'>'|'>='|'=='|'!=');
OPERATOR_Y: ('&&');
OPERATOR_O: ('||');
OPERATOR_NO: ('!');
I'll be really glad if someone can tell me how to create the lexer and the parser with the extension ".java" and then compile them to create the classes.
I´ve been using NetBeans but i´m really confused, If there is another IDE I can use or anything else, please help me.
This is explained in the Antlr4 "Getting Started" page.
Doing it by hand is as simple as this:
$ antlr4 YourGrammar.g4
$ javac YourGrammar*.java
... assuming that you have installed and configured a Java JDK and Antlr.
There are a number of ways to use Antrlr with the Netbeans IDE:
Just write / generate an Ant build script, and then modify it to include rules for running antlr4 etcetera. With allows you to incorporate Antlr into your builds without any IDE-specific integration.
Follow the instructions here on integrating Antlr into Netbeans,
Install and use the Antlrworks 2 plugin.

Looking for advice on project. Parsing logical expression

I'm looking for some advice on my school project. I am supposed to create a program that takes a logical expression and outputs a truth table for it. The actually creating of the truth table for me is not difficult at all and I've already wrote the methods in Java for it. I would like to know if there are any classes in java that I could use to parse the expression for me and put it into a stack. If not I'm looking for help on parsing the expression. It's the parentheses that get me whenever I try and think it through. Also if this would be easier in any other language I would be open to doing it in that. Perl is probably my next best language.
Some examples
(P && Q) -> R
(P || Q || R) && ((P -> R) -> Q)
If you're allowed to use a parser generator tool like ANTLR, here's how you could get started. The grammar for a simple logic-language could look like this:
grammar Logic;
parse
: expression EOF
;
expression
: implication
;
implication
: or ('->' or)*
;
or
: and ('||' and)*
;
and
: not ('&&' not)*
;
not
: '~' atom
| atom
;
atom
: ID
| '(' expression ')'
;
ID : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
However, if you'd parse input like (P || Q || R) && ((P -> R) -> Q) with a parser generated from the grammar above, the parse tree would contain the parenthesis (something you're not interested in after parsing the expression) and the operators would not be the root of each sub-trees, which doesn't make your life any easier if you're interested in evaluating the expression.
You'll need to tell ANTLR to omit certain tokens from the AST (this can be done by placing a ! after the token/rule) and make certain tokens/rules the root of their (sub) tree (this can be done by placing a ^ after it). Finally, you need to indicate in the options section of your grammar that you want a proper AST to be created instead of a simple parse tree.
So, the grammar above would look like this:
// save it in a file called Logic.g
grammar Logic;
options {
output=AST;
}
// parser/production rules start with a lower case letter
parse
: expression EOF! // omit the EOF token
;
expression
: implication
;
implication
: or ('->'^ or)* // make `->` the root
;
or
: and ('||'^ and)* // make `||` the root
;
and
: not ('&&'^ not)* // make `&&` the root
;
not
: '~'^ atom // make `~` the root
| atom
;
atom
: ID
| '('! expression ')'! // omit both `(` and `)`
;
// lexer/terminal rules start with an upper case letter
ID : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
You can test the parser with the following class:
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Main {
public static void main(String[] args) throws Exception {
// the expression
String src = "(P || Q || R) && ((P -> R) -> Q)";
// create a lexer & parser
LogicLexer lexer = new LogicLexer(new ANTLRStringStream(src));
LogicParser parser = new LogicParser(new CommonTokenStream(lexer));
// invoke the entry point of the parser (the parse() method) and get the AST
CommonTree tree = (CommonTree)parser.parse().getTree();
// print the DOT representation of the AST
DOTTreeGenerator gen = new DOTTreeGenerator();
StringTemplate st = gen.toDOT(tree);
System.out.println(st);
}
}
Now to run the Main class, do:
*nix/MacOS
java -cp antlr-3.3.jar org.antlr.Tool Logic.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main
Windows
java -cp antlr-3.3.jar org.antlr.Tool Logic.g
javac -cp antlr-3.3.jar *.java
java -cp .;antlr-3.3.jar Main
which will print a DOT source of the following AST:
(image produced with graphviz-dev.appspot.com)
Now all you need to do is evaluate this AST! :)
In Perl you can use Regexp::Grammars to do the parsing. It may be a little on the "grenade to kill an ant" side, but it should work.
Edit: Here is a (very quick) example which might get you going.
#!/usr/bin/env perl
use strict;
use warnings;
use Regexp::Grammars;
use Data::Dumper;
my $parser = qr/
<nocontext:>
<Logic>
<rule: Logic> <[Element]>*
<rule: Element> <Group> | <Operator> | <Item>
<rule: Group> \( <[Element]>* \)
<rule: Operator> (?:&&) | (?:\|\|) | (?:\-\>)
<rule: Item> \w+
/xms; #/ #Fix Syntax Highlight
my $text = '(P && Q) -> R';
print Dumper \%/ if $text =~ $parser; #/ #Fix Syntax Highlight
Look into JavaCC or ANTLR.
Regexps won't work.
You can probably also run your own parser using StreamTokenizer.
Building an expression parser is easy. Attaching actions to compute a value as you parse it is easy, too.
I assume you can write a BNF for your expression language.
This answer shows you how to build a parser easily, if you have a BNF.
Is there an alternative for flex/bison that is usable on 8-bit embedded systems?
If you want to write your own parser, use the Shunting-yard algorithm to get rid of parentheses by converting the expression from infix into postfix notation or directly into a tree.
Another parser generator for Java is CUP.

Categories

Resources