왜 없는 실행 가능한 대안#include 에 ANTLR4 으로 C 문법?
문제
나는 그냥 시작하기 ANTLR v4 고 나는 가장 중요한 결정을 내리게 된다.
내가 사용하는 C 문법 파일에서 antlr 프로젝트 기 와 함께 작동하는 다음과 같은 비트의 C:
#include <stdio.h>
int main()
{
printf("Hello");
return 0;
}
(로 저장 C:\Users\Public .c).
내가 생성되 C 파서는 다음과 같이
java -cp lib/antlr-4.4-complete.jar org.antlr.v4.Tool -o src/cparser src/C.g4
고 내가 편집한 생성된 파일을 넣어 패키지 문 상단에 있습니다.
나는 그때 조금 Java 프로젝트를 포함하여 이러한 생성된 파일 참조 antlr-runtime-4.4.jar
주요 클래스는 그래서 다음과 같:
package antlrtest;
import java.io.IOException;
import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import cparser.CLexer;
import cparser.CParser;
import cparser.CParser.CompilationUnitContext;
public class AntlrTestMain {
public static void main(String[] arguments) {
try {
CParser parser = new CParser(
new CommonTokenStream(
new CLexer(
new ANTLRFileStream("C:\\Users\\Public\\t.c"))));
parser.setBuildParseTree(true);
// This line prints the error
CompilationUnitContext ctx = parser.compilationUnit();
MyListener listener = new MyListener();
ParseTreeWalker.DEFAULT.walk(listener, ctx);
} catch (IOException e) {
e.printStackTrace();
}
}
}
과 완전성을 위해,하지만 나는 생각하지 않는 것이 중요,수신기는 다음과 같습니다(다만,비어가려 무언가를 넣어서 여기에 물론):
package antlrtest;
import cparser.CBaseListener;
public class MyListener extends CBaseListener {
}
지금 할 때 어떻게 실행하는 경우에 전화 compilationUnit
방법은 다음과 같은 오류를 인쇄하는 콘솔:
line 1:0 token recognition error at: '#i'
line 1:9 no viable alternative at input 'nclude<'
나는 확 C 코드는 유효하지 않았습 편집 C.g4
파일에서 모든 그래서 나는 무엇을 잘못하고 여기에 표시되는 이유는 무엇입니까 이러한 오류?
전화 compilationUnit()
잘못된 것은 아마,그렇다면 어떻게 해야죠 전 나무로 워커?
해결책
문제입니다:
할 수 없습니다 분석에서 파일은 일반하지 않은 경우 전처리된 첫.는 이유는 아마도 전처리기는 물건은 포함하여 매우 제한적 확장할 수 있습니다.몇 가지 간단한 예제:
#define FOO if (a
void main ()
{
int a;
FOO );
}
그래서 당신을 만들어야 전처리기법 먼저.나는 비슷한았다 그것은 이 방법:
- 토큰의 전체 파일
- 자는 전처리기 파서 그것의 일을 하며 일부는 전처리기는 토큰으로"가"토큰하는 전처리기 매크로의 교체(여기:
if
,a
,(
). - 를 사용하여 정기적인 파서를 사용하여 수정된 토큰니다.
무엇을 할 수은 다음과 같다:
추가에 대한 규칙을 포함하여 문법 파일의 끝에서 파일(그래서 다른 전처리기는 물건이 일치할 가능한 경우):
SomePreprocessorStuff
: '#' ~[\r\n]*
-> skip
;
다른 팁
C 문법이 포함되어 있 ANTLR 프로젝트에 필요한 전처리된 소스 파일을 사용하여 입력할 수 있습니다.문법을 수행하지 않는 모든 파일을 포함한 매크로는 확장,또는 다른 모든 기능을 제공하는 전처리기.수행하지 않을 경우 전처리를 사용하기 전에 이 문법,구문 분석 트리를 생산하지 않을 것이 정확한 표현의 편집 단위입니다.
참고로 건너뛰는"전처리기는 물건"을 대신 사용하여 전처리기기 때문에,사전에 파일을 포함이 하나만분의 전처리기.
으로 업데이트 했보 JCPP 전처리기 고있어 그것은 작동하여 그것을 감싸기에 독 를 사용하는 CppReader 에 포함되어 있는 말하는 전처리기.
이것은 정말 최고의(효율성의 관점에서 이상)접근,당신은 아마 구축 TokenStream 에서 JCPP 의 토 스트림 때문에 여기서 우리는 lexing 에 두 번(일단 의 JCPP 하기 위해서 할 수 있 pre-프로세스에 의해 다시 ANTLR)지하는 방법으로 가야 하고 그것은 작동하고 적어도 나의 기본적인 테스트는 것처리습니다.
어쨌든,그래서,코드는 다음과 같습니다 질문에서 업데이트하는 전처리를 사용하여 JCPP:
public class AntlrTestMain {
public static void main(String[] args) {
String mainFileName = "C:\\Users\\Public\\t.c";
try {
// Construct the preprocessor with the main file to look at
Preprocessor pp = new Preprocessor(new File(mainFileName));
// Set up the preprocessor - you probably want to set more stuff
// here than just the include path - have a look in the javadoc
List<String> systemInclude = new ArrayList<String>();
systemInclude.add("C:\\MYCPPCOMPILER\\include");
pp.setSystemIncludePath(systemInclude);
// Get the parser by wrapping up the preprocessor in a reader
CParser parser = new CParser(
new CommonTokenStream(
new CLexer(
new ANTLRInputStream(new CppReader(pp)))));
// Use ANTLR to do whatever you want...
parser.setBuildParseTree(true);
MyListener listener = new MyListener();
ParseTreeWalker.DEFAULT.walk(listener, parser.compilationUnit());
} catch (IOException e) {
e.printStackTrace();
}
}
}
당신이 필요합니다 이러한 수입품에 대해 위의 코드:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.anarres.cpp.CppReader;
import org.anarres.cpp.Preprocessor;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import cparser.CLexer;
import cparser.CParser;
지가 있다고 생각하지 않는 것은 아무것도 잘못된 코드입니다.문법 파일이 없 규칙 정의 #include <foo.h>
.
그래서 당신이 할 수있는 확장 문법(수 있는 오히려 복잡할 때에 익숙하지 않은 antlr)또는 삭제를 포함-문을 얻으려면 지금 antlr 작업으로 귀하의 문법입니다.