문제

나는 그냥 시작하기 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 );
}

그래서 당신을 만들어야 전처리기법 먼저.나는 비슷한았다 그것은 이 방법:

  1. 토큰의 전체 파일
  2. 자는 전처리기 파서 그것의 일을 하며 일부는 전처리기는 토큰으로"가"토큰하는 전처리기 매크로의 교체(여기: if, a, ().
  3. 를 사용하여 정기적인 파서를 사용하여 수정된 토큰니다.

무엇을 할 수은 다음과 같다:

추가에 대한 규칙을 포함하여 문법 파일의 끝에서 파일(그래서 다른 전처리기는 물건이 일치할 가능한 경우):

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 작업으로 귀하의 문법입니다.

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