문제

방금 Javacc로 시작했습니다. 그러나 나는 그것으로 이상한 행동을 가지고 있습니다. 나는 입력 int를 확인하고 싶습니다. 나는 그것이 이해할 수 있기를 바랍니다 :)

기본 방법에는 문자열이 있습니다. 오류는 하나의 오프닝이지만 두 개의 닫는 괄호가 있지만 구문 분석 예외는 없습니다 -> 왜?

왜 내가 예외를 얻지 못하는지 단서가 있습니까?

나는 왼쪽 재귀와 선택 충돌로 고군분투하고 있었지만 초기 시도와 함께 할 수있었습니다. 어쩌면 내가 문제를 소개했을까요?!

오 - 그리고 아마도 내 해결책은 그리 좋지 않을 것입니다 -이 사실을 무시하십시오 ... 또는 더 나은 조언을하십시오 ;-)

파일 : codeparser.jj

 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 --> should produce parse error */
               String s = "A+BC+-(2XXL+A/-B))";
               CodeParser parser = new CodeParser(s);
               parser.expression();
         }
         catch(Exception e)
         {
               e.printStackTrace();
         }
     }
 }
 PARSER_END(CodeParser)

 TOKEN:
 {
  <code : ("-")?(["A"-"Z", "0"-"9"])+ >
  | <op : ("+"|"/") >
  | <not : ("-") >
  | <lparenthesis : ("(") >
  | <rparenthesis : (")") >
 }

 void expression() :
 {
 }
 {
  negated_expression() | parenthesis_expression() | LOOKAHEAD(2) operator_expression() | <code>
 }

 void negated_expression() :
 {
 }
 {
       <not>parenthesis_expression()
 }

 void parenthesis_expression() :
 {
 }
 {
        <lparenthesis>expression()<rparenthesis>
 }

 void operator_expression() :
 {
 }
 {
       <code><op>expression()
 }

편집 -2009 년 11 월 16 일

이제 나는 antlr에게 시도했다.

문제 영역을 더 잘 일치시키기 위해 몇 가지 용어를 변경했습니다. 다음 코드 (이 사이트의 답변 사용)를 생각해 냈습니다.이 코드는 지금 작업을 수행하는 것으로 보입니다.

grammar Code;

CODE    :   ('A'..'Z'|'0'..'9')+;
OP  :   '+'|'/';

start   :   terms EOF;
terms   :   term (OP term)*;
term    :   '-'? CODE
    |   '-'? '(' terms ')';

그건 그렇고 ... Antlrworks는 디버깅/시각화를위한 훌륭한 도구입니다! 나에게 많은 도움이되었습니다.

추가 정보
위의 코드는 다음과 같은 것과 일치합니다.

(-Z19+-Z07+((FV+((M005+(M272/M276))/((M278/M273/M642)+-M005)))/(FW+(M005+(M273/M278/M642)))))+(-Z19+-Z07+((FV+((M005+(M272/M276))/((M278/M273/M642/M651)+-M005)))/(FW+(M0))))
도움이 되었습니까?

해결책

KGREGORY가 말하는 것은 정답입니다. Debug_Parser 옵션으로 문법을 구축 한 다음 실행하면 다음을 볼 수 있습니다.

$ 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: <<code>: "A" at line 1 column 1>
    Consumed token: <<op>: "+" at line 1 column 2>
    Call:   expression
      Call:   operator_expression
        Consumed token: <<code>: "BC" at line 1 column 3>
        Consumed token: <<op>: "+" at line 1 column 5>
        Call:   expression
          Call:   negated_expression
            Consumed token: <"-" at line 1 column 6>
            Call:   parenthesis_expression
              Consumed token: <"(" at line 1 column 7>
              Call:   expression
                Call:   operator_expression
                  Consumed token: <<code>: "2XXL" at line 1 column 8>
                  Consumed token: <<op>: "+" at line 1 column 12>
                  Call:   expression
                    Call:   operator_expression
                      Consumed token: <<code>: "A" at line 1 column 13>
                      Consumed token: <<op>: "/" at line 1 column 14>
                      Call:   expression
                        Consumed token: <<code>: "-B" at line 1 column 15>
                      Return: expression
                    Return: operator_expression
                  Return: expression
                Return: operator_expression
              Return: expression
              Consumed token: <")" at line 1 column 17>
            Return: parenthesis_expression
          Return: negated_expression
        Return: expression
      Return: operator_expression
    Return: expression
  Return: operator_expression
Return: expression

저거 봐? 소비 된 마지막 토큰은 두 번째로 마지막 캐릭터입니다. 두 번째는 오른쪽 괄호입니다.

KGREGRY가 말했듯이 예외를 원한다면 "파일"또는 "데이터"라는 새로운 최상위 프로덕션을 추가하여 토큰으로 끝낼 수 있습니다. 그렇게하면 이와 같은 매달려있는 파렌은 오류가 발생합니다. 다음은 다음과 같은 문법입니다.

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 --> 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:
{
        <code : ("-")?(["A"-"Z", "0"-"9"])+ >
        | <op : ("+"|"/") >
        | <not : ("-") >
        | <lparenthesis : ("(") >
        | <rparenthesis : (")") >
}

void file() : {} {
  expression() <EOF>
}
void expression() :
{
}
{
        negated_expression() | parenthesis_expression() | LOOKAHEAD(2) operator_expression() | <code>
}

void negated_expression() :
{
}
{
      <not>parenthesis_expression()
}

void parenthesis_expression() :
{
}
{
       <lparenthesis>expression()<rparenthesis>
}

void operator_expression() :
{
}
{
      <code><op>expression()
}

및 샘플 실행 :

$ 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: <<code>: "A" at line 1 column 1>
      Consumed token: <<op>: "+" at line 1 column 2>
      Call:   expression
        Call:   operator_expression
          Consumed token: <<code>: "BC" at line 1 column 3>
          Consumed token: <<op>: "+" at line 1 column 5>
          Call:   expression
            Call:   negated_expression
              Consumed token: <"-" at line 1 column 6>
              Call:   parenthesis_expression
                Consumed token: <"(" at line 1 column 7>
                Call:   expression
                  Call:   operator_expression
                    Consumed token: <<code>: "2XXL" at line 1 column 8>
                    Consumed token: <<op>: "+" at line 1 column 12>
                    Call:   expression
                      Call:   operator_expression
                        Consumed token: <<code>: "A" at line 1 column 13>
                        Consumed token: <<op>: "/" at line 1 column 14>
                        Call:   expression
                          Consumed token: <<code>: "-B" at line 1 column 15>
                        Return: expression
                      Return: operator_expression
                    Return: expression
                  Return: operator_expression
                Return: expression
                Consumed token: <")" at line 1 column 17>
              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:
    <EOF> 

  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)

짜잔! 예외.

다른 팁

로부터 Java CC FAQ:

4.7 룩 하이드 사양을 추가하고 경고가 사라졌습니다. 그것이 내가 문제를 해결했다는 것을 의미합니까?

아니요. Javacc는 Lookahead 사양을 사용하는 경우 선택 충돌 경고를보고하지 않습니다. 그만큼 경고의 부재 문제를 올바르게 해결했다는 의미는 아닙니다. 단지 Lookahead Specification을 추가했음을 의미합니다.

먼저 룩보드를 사용하지 않고 갈등을 없애려고 시작합니다.

문제는 파서를 사용할 때 오류가 발생하지 않는다는 것입니다. 맞습니까? 파서 생성기가 문법이 잘못되었다고 주장하는 것은 아닙니다 (다른 답변에서 논의 인 것 같습니다).

이 경우, 구문자가 올바르게 일치하기 때문에 문제를보고 있다고 생각합니다. 표현 생산은 후속 입력을 무시합니다. 나는 오랫동안 Javacc를 사용하지 않았지만 IIRC는 스트림 끝에 도달하지 못한 오류를 던지지 않았습니다.

대부분의 문법은 전체 파일과 일치하는 명시적인 최상위 프로덕션을 가지고 있습니다. 이와 같은 것을 보게됩니다 (내가 말했듯이 구문이 잘못되었다고 확신합니다. 오랜 시간이 지났습니다).

input : ( expression ) *

또는 단일 표현식 만 처리하려면 사용할 수있는 EOF 토큰이있을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top