I have written a very simple file with specification shown below to to tokenize words:
%%
%class Lexer
%unicode
WORD = [^\r\n\t ]
%%
{WORD} {System.out.println("Word is:"+yytext());}
. {System.out.println("Bad character: "+ yytext());}
The following are the commands I run:
jflex hindi.jlex
javac Lexer.java
I get the following error:
Lexer.java:442: cannot find symbol
symbol : class Yytoken
location: class Lexer
public Yytoken yylex() throws java.io.IOException {
^
1 error
Any help appreciated.
On a additional note I checked the Lexer.java file and there was no main function in it. Is that the reason for this error.
If you want to check the lexer standalone(without a parser) then add the following to the user code section:
%standalone
Those working with byaccj and getting this error should add a %byaccj line instead of %standalone below the %class Lexer line
Related
I am trying to build my own parser based on the existing Java grammar.
Even if I use the Java7 grammar from the source repo, generate the parser and use the TestRig from antlr-4.9.3-complete.jar given the code:
1 public class Test {
2 public static void main() {
3 test
4 int b = 1;
5 }
6 }
I get the following error:
line 4:8 no viable alternative at input 'test\n int'
So for some reason it concatenates the incorrect "test" line with correct "int" line.
Also it says "line 4:8" pointing at the "int" line when it should be pointing to "test" (line 3).
(In a regular Java editor I would see a correct error highlighting for the "test" word which would sound like):
"Syntax error, insert "VariableDeclarators" to complete LocalVariableDeclaration"
What do I do to arrive at a similar error with ANTLR so it only picks on the wrong "test" line?
Most likely it's just my misunderstanding how antlr interprets the errors, then how would I get the listener to at least report correctly the starting line?
You can't compare a sophisticated editor/IDE with a parser (generated by ANTLR). A text editor/IDE knows more about the input source and can look up if test is a valid type, and give a meaningful error message if the type cannot be found.
ANTLR's parser rule "sees" test int b as an Identifier, an INT and another Identifier token and cannot match any parser rule for these tokens, resulting in the error starting at the identifier test.
For example, if class test {} was in the classpath, then input without int would be valid:
public class Test {
public static void main() {
test
/*int*/ a = 1;
}
}
It wouldn't compile of course, but the syntax would be correct:
i compiled the :
grammar Hello; // Define a grammar called Hello
r : 'hello' ID ; // match keyword hello followed by an identifier
ID : [a-z]+ ; // match lower-case identifiers
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines, \r (Windows)r
the command to generate the class files (notice im creating it with -package hellogrammer ) :
java -jar antlr-4.9.2-complete.jar -package hellogrammer -o c:\Dev\my\java\ANTLR\test_project\core\src\main\java\hellogrammer c:\Dev\my\java\ANTLR\test_project\core\src\main\java\Hello.g4
and it creates the files just fine , then i compile the files and it looks like this :
c:\Dev\my\java\ANTLR\test_project\core\target\classes\hellogrammer>ls -1
HelloBaseListener.class
HelloLexer.class
HelloListener.class
'HelloParser$RContext.class'
HelloParser.class
now when I try to execute the TestRig command im getting no response from the command line :
c:\Dev\my\java\ANTLR\test_project\core\target\classes>java -cp ".;C:/Dev/my/java/ANTLR/antlr-4.9.2-complete.jar" org.antlr.v4.gui.TestRig hellogrammer.Hello -tree
it just stacks with no error or any response ...
The TestRig requires two separate parameters, first the grammar name and the the start rule name. This TestRig then begins parsing input from the input stream, so, you can either type input (with a Ctrl-D for signal EOF), or you can redirect your input to stdin with <
Try:
c:\Dev\my\java\ANTLR\test_project\core\target\classes>java -cp ".;C:/Dev/my/java/ANTLR/antlr-4.9.2-complete.jar" org.antlr.v4.gui.TestRig hellogrammar.Hello r -tree < “your input file”
I have a separated parser and lexer grammar and want to run org.antlr.v4.gui.TestRig to debug/test my grammar.
My lexer grammar start with:
lexer grammar TestLexer;
IDS: [a-zA-Z];
WS: [ \t];
NL: [\r?\n];
...
and my parser grammar start with:
parser grammar TestParser;
options { tokenVocab=TestLexer; }
testRule: WS* IDS+ NL;
...
My classpath env variable points to complete antlr.jar and current directory.
antlr is an alias to java org.antlr.v4.Tool
grun is an alias to java org.antlr.v4.gui.TestRig.
When I run antlr TestParser.g4 && javac *.java the parser code gets generated and compiled.
When I run grun TestParser testRule -gui I get the error:
Exception in thread "main" java.lang.ClassCastException: class TestParser
at java.lang.Class.asSubclass(Class.java:3404)
at org.antlr.v4.gui.TestRig.process(TestRig.java:135)
at org.antlr.v4.gui.TestRig.main(TestRig.java:119)
And when I run grun Test testRule -gui I get the error:
Can't load Test as lexer or parser
I don't have any problems when using a combined grammar.
What's missing in order to run TestRig?
When using separated lexer and parser you have to generate the code for the lexer and parser. This is not done automatically by generating the code for the parser alone.
Execute:
antlr TestLexer.g4
antlr TestParser.g4
javac *.java
After generating the code for both (lexer and parser) you have to run:
grun Test -gui testInput.txt
where testInput.txt contains some test input to parse.
Note: When using separated lexer and parser it's expected that the lexer ends on Lexer and the parser ends on Parser. The common part of the files is the name of grammar.
I.e TestLexer and TestParser -> Test is the name of the grammar.
I'm using the following code in post-build step of my Jenkins job:
evaluate(new File("Set-BuildBadge.groovy"));
So it runs a script successfully if it does not contain functions.
If inside the script I define a function for example:
def addSummaryWithText(Icon, Text) {
manager.createSummary(Icon).appendText(Text, false)
}
...
addSummaryWithText("installer.gif", "Project: " + ProjectName)
then I get the following error:
FATAL: Illegal class name "Set-BuildBadge$addSummaryWithText" in class
file Set-BuildBadge$addSummaryWithText java.lang.ClassFormatError:
Illegal class name "Set-BuildBadge$addSummaryWithText" in class file
Set-BuildBadge$addSummaryWithText at
java.lang.ClassLoader.defineClass1(Native Method) ...
I'm not getting how GroovyShell.evaluate works.
Can anyone help me?
Looks like the JVM doesn't like class names with a hyphen in them.
By calling your script Set-BuildBadge.groovy internally it is compiled into a class that isn't allowed when you add a function to the script.
Changing the name of the script to SetBuildBadge.groovy will fix it :-)
I ran the following command to compile a servlet called BeerSelect.java from HeadFirst Servlets and JSP book.
D:\Apache Tomcat\apache-tomcat-5.5.36\apache-tomcat-5.5.36\webapps\Coffee>javac
-classpath /common/lib servlet-api.jar:classes: -d classes src/com/example/web/B
eerSelect.java
My servlet-api.jar is located in D:\Apache Tomcat\apache-tomcat-5.5.36\apache-tomcat-5.5.36\common\lib
MESSAGE
javac: invalid flag: servlet-api.jar:classes:
Usage: javac <options> <source files> use -help for a list of possible options
Cannot understand how to fix this command and compile the servlet. Doing it for the first time new to servlets.
Then I changed the command to be
D:\Apache Tomcat\apache-tomcat-5.5.36\apache-tomcat-5.5.36\webapps\Coffee\WEB-IN
F\src\com\example\web>javac -classpath "D:\Apache Tomcat\apache-tomcat-5.5.36\ap
ache-tomcat-5.5.36\common\lib\servlet-api.jar";classes BeerSelect.java
MESSAGE
BeerSelect.java:3: package com.example.model does not exist
import com.example.model.*;
^
BeerSelect.java:15: cannot find symbol
symbol : class BeerExpert
location: class com.example.web.BeerSelect
BeerExpert be = new BeerExpert();
^
BeerSelect.java:15: cannot find symbol
symbol : class BeerExpert
location: class com.example.web.BeerSelect
BeerExpert be = new BeerExpert();
^
BeerSelect.java:32: cannot find symbol
symbol : variable out
location: class com.example.web.BeerSelect
out.println("<br>try: " + it.next());
^
4 errors
Why cannot it find the com.example.model package ?
IMAGE
It looks like you have three issues with your command: extra spaces, Unix-style pathnames, and missing additional Java source files. Try the following instead:
javac -classpath "D:\Apache Tomcat\apache-tomcat-5.5.36\apache-tomcat-5.5.36\common\lib\servlet-api.jar";classes -d classes src\com\example\web\*.java src\com\example\model\*.java
I've removed extra spaces, converted Unix paths to Windows paths, changed the classpath separator from the Unix-style ':' to Windows-style ';', and added your other Java sources - compiling them all together should resolve your first three compiler errors.
As for the last compiler error, that appears to be a genuine source code error - try prepending System. to the out.println("<br>try: " + it.next()); line. (It can also be resolved by a static import, but that would be unconventional.)
D:\Apache Tomcat\apache-tomcat-5.5.36\apache-tomcat-5.5.36\webapps\Coffee>javac -classpath "D:\Apache Tomcat\apache-tomcat-5.5.36\apache-tomcat-5.5.36\common\lib\servlet-api.jar";"D:\Apache Tomcat\apache-tomcat-5.5.36\apache-tomcat-5.5.36\webapps\Coffee\WEB-INF\src" WEB-INF\src\com\example\web\BeerSelect.java
This command works and compiles the class BeerSelect.java.