Antlr4 파서 생성기 Java 팁

2059 단어 antlrantlr4java
나는 Antlr(및 기타 파서 생성기;_;)를 처음 사용하므로 파서, 렉서 및 방문자에 익숙해지는 데 시간이 걸렸습니다. 여기에 향후 도움이 될 수 있는 몇 가지 팁을 적어 둡니다.

  • 완전히 동일한 패턴과 일치하는 여러 어휘 분석기 규칙을 피하십시오. 그렇지 않으면 그 중 하나가 절대 일치하지 않습니다. 내 파서에는 두 개의 노드와 가중치가 있으며 모두 숫자이지만 서로 다른 요소이므로 다음과 같이 각각에 대해 서로 다른 렉서 규칙을 사용해야 한다고 생각했습니다.

  • tuple
        : nodefrom weight nodeto
        ;
    nodefrom: [0-9]+;
    weight: [0-9]+;
    nodeto: [0-9]+;
    


    그리고 이로 인해 불일치가 발생합니다. 이를 방지하려면 정수에 대해 하나의 Lexer 규칙만 사용하는 것이 좋습니다.

    tuple
        : nodefrom weight nodeto
        ;
    nodefrom: INT;
    weight: INT;
    nodeto: INT;
    INT: [0-9]+;
    


  • 문법에 관련된 여러 작업이 있을 수 있으므로 각 작업에 태그(#operator)를 추가해야 하므로 별도의 방문자 기능이 생성됩니다.
    예를 들어,

  • expr
        : expr '*'         #aster
        | expr '.' expr    #concate 
        | expr '+' expr    #plus
        | tuple            #tup
        | '(' expr ')'     #parens
        ;
    


    이것은 스타, 연결 및 플러스의 세 가지 작업을 사용하는 내 파서의 일부입니다. #aster, #concate 및 #or를 사용하면 visitAster(), visitConcate() 및 visitPlus() 인터페이스를 생성한 다음 이러한 작업을 별도로 구현할 수 있습니다. 이러한 태그를 생성하지 않으면 하나의 인터페이스인 visitExpr()만 생성됩니다.
  • 방문자 클래스에 대한 메서드를 구현할 때 구문 분석 트리를 순회할 때 계산하려는 값과 관련된 메서드에만 집중하면 됩니다. 예를 들어 내 구문 분석 트리에서 각 노드는 튜플입니다.
    (Node1, Weight_1, Weight_2, Node2)이며 각 값에 대한 방문 방법이 있습니다. 내가 생성한 방문자가 계산을 위해 Weight_1만 필요한 경우 특별히 visitWeight_1()을 구현해야 합니다.
  • 나는 이 방문자 클래스가 각 구문 분석 규칙에 대한 메서드를 자동으로 생성하고 ctx.ValueName()으로 간단히 한 노드의 값을 얻을 수 있는 정말 편리한 것을 발견했습니다. 그래서 방문자 메서드에 대한 코드를 작성할 때 항상 grun Calc prog -gui calc.txt를 실행하여 시각화된 구문 분석 트리를 열고 해당 노드 간의 관계를 확인합니다.

    이것은 내가 사용하고 있는 구문 분석 트리의 일부입니다. 튜플에는 (nodef, wc, wd, nodet)(괄호 포함) 6개의 요소가 있습니다. 따라서 바로 지금 visitTuple(Parser.TupleContext ctx) 함수에서 wc의 값을 얻으려면 ctx.wc()와 같은 것을 작성할 수 있습니다.

  • 아직 일하고 있어...

    좋은 웹페이지 즐겨찾기