2014-02-12 1 views
1

저는 ANTLR을 처음 사용하기 때문에 ANTLR4와 C#을 사용하여 계산기 응용 프로그램에 비교적 간단한 파서를 생성하려고합니다. 여기에 문법 파일이 있습니다. Antlr4 파서가 암시 적 승수 연산의 순서를 따르지 못합니다.

parser grammar CalculatorExpressionParser; 

options{ 
language = CSharp2; 
} 

expr: FUNC expr? (COMMA expr)* RIGHTPAREN    #CallFunction 
    | LEFTPAREN expr RIGHTPAREN       #Parens 
    | expr POW<assoc=right> expr      #Pow 
    | expr op=(MULTIPLY | DIVIDE)? expr     #MultDivide 
    | expr op=(ADD | SUBTRACT) expr      #AddSubtract 
    | SUBTRACT expr          #Negative 
    | NUMBER           #Number 
    ; 

나는 구문 분석하기 전에 수치 동등한 변수의 암시 적 곱셈과 변환을 지원하기 위해 토큰을 생성하는 사용자 정의 렉서를 썼다.

하지만 입력시 다음 결과가 표시됩니다. 내가 오류 복구 기능을 해제하고 모든 모호성 오류를보고 그것을 설정하고 내가 어떤을 받고있는 것으로 나타나지 않습니다 시도

2+6/3 => 4 (correct) 
6/3+2 => 1.2 (should be 4) 
6/(3+2) => 4 (also correct) 

1+2*3 => 7 (correct) 
2*3+1 => 8 (should be 7 too) 
(2*3)+1 => 7 (correct) 

참고.

어쨌든 내가 다음 문법을? 나누기/곱셈 연산자 다음에 암시 적 곱셈이 더 이상 지원되지 않는다는 점을 제외하고는 큰 효과가있는 것으로 보입니다.

parser grammar CalculatorExpressionParser; 

options{ 
language = CSharp2; 
} 

expr: FUNC expr? (COMMA expr)* RIGHTPAREN    #CallFunction 
    | LEFTPAREN expr RIGHTPAREN       #Parens 
    | expr POW<assoc=right> expr      #Pow 
    | expr op=(MULTIPLY | DIVIDE) expr     #MultDivide 
    | expr op=(ADD | SUBTRACT) expr      #AddSubtract 
    | SUBTRACT expr          #Negative 
    | NUMBER           #Number 
    ; 

궁금한 이유는 무엇입니까? 일치하는 순서를 어기 는가? 그리고 이것을 해결할 수있는 쉬운 방법이 있습니까?

+0

최신 릴리스에서 수정되었을 수 있습니다. 내가 테스트 할 수 있도록 문제를 설명하는 자급 한 예제가 있습니까? –

+0

dsffadfdasfadsfdf – hashtable

+0

다음은 간단한 렉서/구문 분석기 문법 파일, 방문자 구현 및 문제를 보여주는 테스트 프로그램입니다. https://dl.dropboxusercontent.com/u/22576981/ANTLR4Test/Combined1.zip – hashtable

답변

1

"expr expr"은 ANTLR 4.2가 처리 할 수 ​​있지만 연산자의 패턴에 맞지 않습니다. Sam은 C# 대상 업데이트 작업을 계속하고 있습니다.

+0

확인. 감사. :) Btw, 첫 번째 문법에서 암시 적 곱셈은 잘 작동했다, 그냥 내가 게시 한 것과 같은 무관 한 표현에 우선 순위를 망쳐 놨어. – hashtable

1

올바른 순서로 작업하기 위해 expr 문을 여러 문으로 분할하십시오.

일반적으로 다음과 같습니다. 각 expr은 한 세트의 수학 연산을 처리 한 다음 낮은 우선 순위 규칙을 호출하는 것에 유의하십시오. 일반적으로 가장 낮은 규칙은 INT 또는 FLOAT

과 같은 원자 연산자입니다.이 경우 논리적 AND 및 OR의 비교를 한 다음 지수를 곱한 다음 나누기/더하기/빼기를 ​​처리합니다.

참고 참고로 여기서 작업을 인라인하는 대신 AST 트리를 만들었습니다.

expr 
: subExpr -> ^(EXPR subExpr) 
; 

subExpr : logicalAndExp (addSubtractOp^ logicalAndExp)* 
; 

logicalAndExp 
: logicalOrExp (multiplyDivideOp^ logicalOrExp)*  
; 

logicalOrExp 
: comparatorExp (CARET^ comparatorExp)*  
; 

comparatorExp 
: powExp (comparatorOp^ powExp)* 
; 

powExp : multExp (BARBAR^ multExp)* 
; 

multExp 
: expressionAtom (AMPAMP^ expressionAtom)* 
;expression 
: subExpr -> ^(EXPR subExpr) 
; 

subExpr : logicalAndExp (addSubtractOp^ logicalAndExp)* 
; 

logicalAndExp 
: logicalOrExp (multiplyDivideOp^ logicalOrExp)*  
; 

logicalOrExp 
: comparatorExp (CARET^ comparatorExp)*  
; 

comparatorExp 
: powExp (comparatorOp^ powExp)* 
; 

powExp : multExp (BARBAR^ multExp)* 
; 

multExp 
: expressionAtom (AMPAMP^ expressionAtom)* 
; 
+0

유일한 방법입니까? Antlr4에서는 직접 왼쪽 재귀에 대한 지원을 추가하고 expr 규칙에 넣은 순서에 따라 연산자 우선 순위를 지정한다는 것을 이해합니다. 암시 적 곱셈을 지원합니다. 내가 왜 이걸 넣을 수 없는지 궁금 해서요? – hashtable

+0

표현 유형의 체인을 사용하여 그것을 지원하는 방법에 대한 설명 주셔서 감사합니다. :) 나는 지금 당장 그렇게해야 할 것 같습니다. – hashtable