Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>What kgregory says is the right answer. You can see this if you build the grammar with the DEBUG_PARSER option and then run it:</p> <pre> $ javacc -debug_parser -output_directory=com/testing/ CodeParser.jj && javac com/testing/*.java && java -cp . com.testing.CodeParser Java Compiler Compiler Version 5.0 (Parser Generator) (type "javacc" with no arguments for help) Reading from file CodeParser.jj . . . File "TokenMgrError.java" is being rebuilt. File "ParseException.java" is being rebuilt. File "Token.java" is being rebuilt. File "SimpleCharStream.java" is being rebuilt. Parser generated successfully. Call: expression Call: operator_expression Consumed token: &lt;&lt;code&gt;: "A" at line 1 column 1&gt; Consumed token: &lt;&lt;op&gt;: "+" at line 1 column 2&gt; Call: expression Call: operator_expression Consumed token: &lt;&lt;code&gt;: "BC" at line 1 column 3&gt; Consumed token: &lt;&lt;op&gt;: "+" at line 1 column 5&gt; Call: expression Call: negated_expression Consumed token: &lt;"-" at line 1 column 6&gt; Call: parenthesis_expression Consumed token: &lt;"(" at line 1 column 7&gt; Call: expression Call: operator_expression Consumed token: &lt;&lt;code&gt;: "2XXL" at line 1 column 8&gt; Consumed token: &lt;&lt;op&gt;: "+" at line 1 column 12&gt; Call: expression Call: operator_expression Consumed token: &lt;&lt;code&gt;: "A" at line 1 column 13&gt; Consumed token: &lt;&lt;op&gt;: "/" at line 1 column 14&gt; Call: expression Consumed token: &lt;&lt;code&gt;: "-B" at line 1 column 15&gt; Return: expression Return: operator_expression Return: expression Return: operator_expression Return: expression Consumed token: &lt;")" at line 1 column 17&gt; Return: parenthesis_expression Return: negated_expression Return: expression Return: operator_expression Return: expression Return: operator_expression Return: expression </pre> <p>See that? The last token consumed is the second to last character - the second to last right parenthesis. </p> <p>If you want the exception, again, like kgregory said, you could add a new top-level production called "file" or "data" or something and end it with an token. That way any dangling parens like this would cause an error. Here's an grammar that does that:</p> <pre> options { STATIC=false; } PARSER_BEGIN(CodeParser) package com.testing; import java.io.StringReader; import java.io.Reader; public class CodeParser { public CodeParser(String s) { this((Reader)(new StringReader(s))); } public static void main(String args[]) { try { /** String has one open, but two closing parenthesis --&gt; should produce parse error */ String s = "A+BC+-(2XXL+A/-B))"; CodeParser parser = new CodeParser(s); parser.file(); } catch(Exception e) { e.printStackTrace(); } } } PARSER_END(CodeParser) TOKEN: { &lt;code : ("-")?(["A"-"Z", "0"-"9"])+ &gt; | &lt;op : ("+"|"/") &gt; | &lt;not : ("-") &gt; | &lt;lparenthesis : ("(") &gt; | &lt;rparenthesis : (")") &gt; } void file() : {} { expression() &lt;EOF&gt; } void expression() : { } { negated_expression() | parenthesis_expression() | LOOKAHEAD(2) operator_expression() | &lt;code&gt; } void negated_expression() : { } { &lt;not&gt;parenthesis_expression() } void parenthesis_expression() : { } { &lt;lparenthesis&gt;expression()&lt;rparenthesis&gt; } void operator_expression() : { } { &lt;code&gt;&lt;op&gt;expression() } </pre> <p>And a sample run:</p> <pre> $ javacc -debug_parser -output_directory=com/testing/ CodeParser.jj && javac com/testing/*.java && java -cp . com.testing.CodeParser Java Compiler Compiler Version 5.0 (Parser Generator) (type "javacc" with no arguments for help) Reading from file CodeParser.jj . . . File "TokenMgrError.java" is being rebuilt. File "ParseException.java" is being rebuilt. File "Token.java" is being rebuilt. File "SimpleCharStream.java" is being rebuilt. Parser generated successfully. Call: file Call: expression Call: operator_expression Consumed token: &lt;&lt;code&gt;: "A" at line 1 column 1&gt; Consumed token: &lt;&lt;op&gt;: "+" at line 1 column 2&gt; Call: expression Call: operator_expression Consumed token: &lt;&lt;code&gt;: "BC" at line 1 column 3&gt; Consumed token: &lt;&lt;op&gt;: "+" at line 1 column 5&gt; Call: expression Call: negated_expression Consumed token: &lt;"-" at line 1 column 6&gt; Call: parenthesis_expression Consumed token: &lt;"(" at line 1 column 7&gt; Call: expression Call: operator_expression Consumed token: &lt;&lt;code&gt;: "2XXL" at line 1 column 8&gt; Consumed token: &lt;&lt;op&gt;: "+" at line 1 column 12&gt; Call: expression Call: operator_expression Consumed token: &lt;&lt;code&gt;: "A" at line 1 column 13&gt; Consumed token: &lt;&lt;op&gt;: "/" at line 1 column 14&gt; Call: expression Consumed token: &lt;&lt;code&gt;: "-B" at line 1 column 15&gt; Return: expression Return: operator_expression Return: expression Return: operator_expression Return: expression Consumed token: &lt;")" at line 1 column 17&gt; Return: parenthesis_expression Return: negated_expression Return: expression Return: operator_expression Return: expression Return: operator_expression Return: expression Return: file com.testing.ParseException: Encountered " ")" ") "" at line 1, column 18. Was expecting: &lt;EOF&gt; at com.testing.CodeParser.generateParseException(CodeParser.java:354) at com.testing.CodeParser.jj_consume_token(CodeParser.java:238) at com.testing.CodeParser.file(CodeParser.java:34) at com.testing.CodeParser.main(CodeParser.java:22) </pre> <p>Voila! An exception.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload