ANTLR: 간단한 예가 있나요?
ANTLR을 시작하고 싶은데, antlr.org 사이트에서 몇 시간 동안 예제를 검토해도 Java 프로세스에 대한 문법을 명확하게 이해할 수 없습니다.
ANTLR을 사용하여 구현된 4연산 계산기가 파서 정의를 거쳐 Java 소스 코드까지 이어지는 간단한 예가 있습니까?
참고: 이 답변은 ANTLR3에 대한 것입니다!ANTLR4의 예를 찾는 경우 이 Q&A에서는 ANTLR4를 사용하여 간단한 식 파서와 평가자를 작성하는 방법을 보여 줍니다.
먼저 문법을 만듭니다.다음은 +, -, * 및 /의 4가지 기본 연산자를 사용하여 작성된 식을 평가하는 데 사용할 수 있는 작은 문법입니다.괄호를 사용하여 식을 그룹화할 수도 있습니다.
이 문법은 단수 연산자(-1+9)나 .99와 같은 소수점(선행 번호 없음)을 처리하지 않고, 2개의 단점을 제시합니다.이것은 여러분이 스스로 할 수 있는 하나의 예에 불과합니다.
다음은 문법 파일 Exp.g:
grammar Exp;
/* This will be the entry point of our parser. */
eval
: additionExp
;
/* Addition and subtraction have the lowest precedence. */
additionExp
: multiplyExp
( '+' multiplyExp
| '-' multiplyExp
)*
;
/* Multiplication and division have a higher precedence. */
multiplyExp
: atomExp
( '*' atomExp
| '/' atomExp
)*
;
/* An expression atom is the smallest part of an expression: a number. Or
when we encounter parenthesis, we're making a recursive call back to the
rule 'additionExp'. As you can see, an 'atomExp' has the highest precedence. */
atomExp
: Number
| '(' additionExp ')'
;
/* A number: can be an integer value, or a decimal value */
Number
: ('0'..'9')+ ('.' ('0'..'9')+)?
;
/* We're going to ignore all white space characters */
WS
: (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;}
;
(파서 규칙은 소문자로 시작하고 렉서 규칙은 대문자로 시작합니다.)
문법을 만든 후에는 구문 분석기와 어휘기를 생성해야 합니다.ANTLR jar를 다운로드하여 문법 파일과 동일한 디렉토리에 저장합니다.
셸/명령 프롬프트에서 다음 명령을 수행합니다.
java -cp antlr-3.2.jar org.antlr.Tool Exp.g
에러 메세지는 표시되지 않습니다.ExpLexer.java, ExpParser.java 및 Exp.tokens 파일이 생성됩니다.
모두 정상적으로 동작하는지 확인하려면 다음 테스트클래스를 만듭니다.
import org.antlr.runtime.*;
public class ANTLRDemo {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("12*(5-6)");
ExpLexer lexer = new ExpLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ExpParser parser = new ExpParser(tokens);
parser.eval();
}
}
컴파일:
// *nix/MacOS
javac -cp .:antlr-3.2.jar ANTLRDemo.java
// Windows
javac -cp .;antlr-3.2.jar ANTLRDemo.java
다음으로 실행합니다.
// *nix/MacOS
java -cp .:antlr-3.2.jar ANTLRDemo
// Windows
java -cp .;antlr-3.2.jar ANTLRDemo
정상적으로 처리되면 콘솔에 아무것도 인쇄되지 않습니다.즉, 파서가 에러를 검출하지 않았습니다.바꿀 때"12*(5-6)"
안으로"12*(5-6"
다시 컴파일하여 실행하면 다음과 같이 출력됩니다.
line 0:-1 mismatched input '<EOF>' expecting ')'
자, 이제 파서가 실제로 유용한 작업을 수행할 수 있도록 문법에 Java 코드를 조금 추가해 보겠습니다.코드를 추가하는 방법은{
그리고.}
당신의 문법 안에 평범한 자바 코드가 들어있습니다.
단, 먼저 문법 파일의 모든 파서 규칙은 기본 이중 값을 반환해야 합니다.이 작업을 수행하려면 다음 작업을 수행할 수 있습니다.returns [double value]
: "Discription"
grammar Exp;
eval returns [double value]
: additionExp
;
additionExp returns [double value]
: multiplyExp
( '+' multiplyExp
| '-' multiplyExp
)*
;
// ...
모든 규칙은 이중 값을 반환해야 합니다.과 '를 해보겠습니다.double value
(('Java')에 포함되지 않음{...}
에서는 달러 합니다value
:
grammar Exp;
/* This will be the entry point of our parser. */
eval returns [double value]
: additionExp { /* plain code block! */ System.out.println("value equals: "+$value); }
;
// ...
다음은 문법입니다만, Java 코드가 추가되어 있습니다.
grammar Exp;
eval returns [double value]
: exp=additionExp {$value = $exp.value;}
;
additionExp returns [double value]
: m1=multiplyExp {$value = $m1.value;}
( '+' m2=multiplyExp {$value += $m2.value;}
| '-' m2=multiplyExp {$value -= $m2.value;}
)*
;
multiplyExp returns [double value]
: a1=atomExp {$value = $a1.value;}
( '*' a2=atomExp {$value *= $a2.value;}
| '/' a2=atomExp {$value /= $a2.value;}
)*
;
atomExp returns [double value]
: n=Number {$value = Double.parseDouble($n.text);}
| '(' exp=additionExp ')' {$value = $exp.value;}
;
Number
: ('0'..'9')+ ('.' ('0'..'9')+)?
;
WS
: (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;}
;
그리고 저희가eval
이치노ANTLDemo.java 。
import org.antlr.runtime.*;
public class ANTLRDemo {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("12*(5-6)");
ExpLexer lexer = new ExpLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ExpParser parser = new ExpParser(tokens);
System.out.println(parser.eval()); // print the value
}
}
다시 (re) 문법 (1)에서 새로운 렉서 및 파서를 생성하고 모든 클래스 (2)를 컴파일하여 ANTLRDemo (3)를 실행합니다.
// *nix/MacOS
java -cp antlr-3.2.jar org.antlr.Tool Exp.g // 1
javac -cp .:antlr-3.2.jar ANTLRDemo.java // 2
java -cp .:antlr-3.2.jar ANTLRDemo // 3
// Windows
java -cp antlr-3.2.jar org.antlr.Tool Exp.g // 1
javac -cp .;antlr-3.2.jar ANTLRDemo.java // 2
java -cp .;antlr-3.2.jar ANTLRDemo // 3
해서 이제 여러분도 표현 수 거예요.12*(5-6)
솔에인!!!!!!!
다시 말씀드리지만, 이것은 매우 간단한 설명입니다.ANTLR Wiki에 접속하여 튜토리얼을 읽거나 제가 방금 올린 내용을 조금 재생해 보시기 바랍니다.
행운을 빕니다.
편집:
이 투고에서는 위의 예를 확장하여 다음과 같이 하는 방법을 보여 줍니다.Map<String, Double>
제공된 식에서 변수를 유지하는 값을 제공할 수 있습니다.
Antlr (2014년 6월)는 Antlr (2014년 6월)입니다.ANTLRStringStream
'''가 되기 위해'' ANTLRInputStream
, 에서하기 위해 parser.eval()
로로 합니다.parser.eval().value
그리고 나는 제거할 필요가 있었다.WS
절이 를 들어, 「」 때문입니다.$channel
【플렉서
가브리엘레 Tomassetti에 의해 ANTLR메가 튜토리얼은 도움이 된다.
문법을 예, 방문자 다른 언어의 예(자바, 자바 스크립트, C#, Python)과 많은 다른 것들을 가지고 있다.고도로 추천된다.
편집:가브리엘레 Tomassetti ANTLR에 의해서 다른 유용한 용품들이다.
Antlr 4을 위해java 코드 생성 과정 이하- 있다.
java -cp antlr-4.5.3-complete.jar org.antlr.v4.Tool Exp.g
classpath에 그에 따라 교반 이름을 업데이트합니다.
버전 4.7.1 약간:수입을 위해: 달랐다.
import org.antlr.v4.runtime.*;
주된 세대들에겐-CharStreams:.
CharStream in = CharStreams.fromString("12*(5-6)");
ExpLexer lexer = new ExpLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ExpParser parser = new ExpParser(tokens);
https://github.com/BITPlan/com.bitplan.antlr에서 유용한 도우미 클래스와 몇 가지 완전한 예가 포함된 ANTLR Java 라이브러리를 찾을 수 있습니다.메이븐과 함께 사용할 수 있고 일식이나 메이븐을 좋아하시면 됩니다.
https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/main/antlr4/com/bitplan/exp/Exp.g4
는 다중 및 추가 연산을 수행할 수 있는 단순한 표현 언어입니다.https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/test/java/com/bitplan/antlr/TestExpParser.java 에는 대응하는 유닛테스트가 준비되어 있습니다.
https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/main/antlr4/com/bitplan/iri/IRIParser.g4은 3개의 파트로 분할된 IRI 파서입니다.
- 파서 문법
- 렉서 문법
- Import된 LexBasic 문법
https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/test/java/com/bitplan/antlr/TestIRIParser.java에 유닛 테스트가 있습니다.
개인적으로 나는 이 부분이 바로잡기 가장 까다로운 부분이라고 생각했다.http://wiki.bitplan.com/index.php/ANTLR_maven_plugin 를 참조해 주세요.
https://github.com/BITPlan/com.bitplan.antlr/tree/master/src/main/antlr4/com/bitplan/expr
에는 이전 버전에서 ANTLR4의 성능 문제에 대해 작성된 세 가지 예가 있습니다.한편, 이 문제는 테스트 케이스 https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/test/java/com/bitplan/antlr/TestIssue994.java에 나타나 있듯이 수정되었습니다.
언급URL : https://stackoverflow.com/questions/1931307/antlr-is-there-a-simple-example
'source' 카테고리의 다른 글
Vue JS 체크박스를 바인드하는 방법? (0) | 2022.08.30 |
---|---|
배열을 비교할 때 항목 표시/숨김 (0) | 2022.08.30 |
vue js의 소품을 사용하여 하위 구성 요소의 속성을 업데이트하려면 어떻게 해야 합니까? (0) | 2022.08.30 |
범위 외의 vue.js 컴포넌트 데이터를 변경하는 방법 (0) | 2022.08.30 |
VueX 스토어가 작동하지 않음 (0) | 2022.08.30 |