2011-03-28 8 views
1
Productions 
    program = cls*; 
    cls = clsdef name openbrace clsdata closingbrace; 
    clsdata = (clsfield|clsmethod)*; 
    clsfield = [variabletype]:name [variablename]:name semi; 
    clsmethod = [returntype]:name [methodname]:name openmethodbrace closingmethodbrace openbrace closingbrace; 

문제는프로덕션 규칙 prod = (expr | expr ') * 형식의 sablecc에 대한 문제

clsdata = (clsfield|clsmethod)*; 

clsdata = clsfield*; 
clsdata = clsmethod*; 

로 설정하면 잘 작동하지만, 상상할 수 있듯이, 내가 의도 한 것과 같은 의미입니다. 클래스가 메소드와 필드를 모두 허용하도록하고 싶습니다 (특정 순서없이!).

그래서 내 질문에 오류가 발생하지 않도록 clsdata 정의해야합니다. 재귀적인 대안을 생각할 수도 있지만, 가능한 한 깨끗하게 유지하고 싶습니다!

감사

답변

1

clsdata = (clsfield | clsmethod) *;

는 SableCC는 구문 같은 EBNF 을 가지고 있지만 문법 규칙의 유형을 지원하지 않습니다. 이미했듯이, 비 종단 대체품 인 clsfieldclsmethod은 자체 생산으로 굴절시킬 필요가 있습니다.

아직 나는 이것이 당신이 SableeCC example grammars의를 보면 당신은 그 '클래스 멤버'을 정의하는 표준 방법입니다 볼이

을 할 수있는 가장 좋은 방법입니다 확실하지 않다. 다음과 같이 문법을 단순화 할 수도 있지만 clsmembers :

-1

이 작동 :

Productions 
    program = cls*; 
    cls = clsdef name openbrace clsmembers closingbrace; 
    clsmembers = clsmember*; 
    clsmember = {clsfield} clsfield | {clsmethod} clsmethod; 
    clsfield = [variabletype]:name [variablename]:name semi; 
    clsmethod = [returntype]:name [methodname]:name openmethodbrace closingmethodbrace openbrace closingbrace; 

아직 나는이이 작업을 수행하는 가장 좋은 방법입니다 확실하지 않다. 다른 접근법을 환영합니다!