2012-06-18 9 views
4

저는 현재 학사 프로젝트의 일환으로 포커 손 역사 파서를 연구 중입니다. 저는 지난 며칠 동안 약간의 연구를 해왔고 몇 가지 훌륭한 파서 생성기를 보았습니다 (프로젝트 자체는 Java로 코딩되기 때문에 JavaCC를 선택했습니다).문법 모호성 처리 (포커 파일 파싱)

핸드 히스토리 문법이 매우 기본적이고 간단하지만, 플레이어의 닉네임에 허용 된 문자 집합으로 인해 모호성 문제가 있습니다. 가정하자

우리는 다음과 같은 형식의 라인을 가지고 :

Seat 5: myNickname (1500 in chips) 

토큰 myNickname 모든 문자뿐 아니라 공백을 포함 할 수 있습니다. 즉, (1500 in chipSeat 5:이 유효한 별명이므로 궁극적으로 모호성 문제가 발생합니다. 길이 (4-12 자)를 제외하고는 플레이어의 닉네임에 대한 제한이 없습니다.

여러 데이터를 플레이어의 닉네임 (예 : 좌석 위치 및 칩 개수)과 함께 구문 분석하고 저장해야하므로 제 질문은 여기에 어떤 옵션이 있습니까?

나는 그것이 JavaCC에,이 따라 뭔가 사용 할 싶어요 :

SeatRecord seat() : 
{ Token seatPos, nickname, chipStack; } 
{ 
    "Seat" seatPos=<INTEGER> ":" nickname=<NICKNAME> "(" chipStack=<INTEGER> 
    "in chips)" 
    { 
     return new SeatRecord(seatPos.image, nickname.image, chipStack.image); 
    } 
} 

가 어느 지금

가 나는 또한 GLR 파서 주위를 검색 (때문에 언급 한 문제에) 작동하지 않습니다 (분명히 모호한 문법을 ​​다루고 있음) -하지만 그들은 주로 Bison을 제외하고는 버려지거나 문서화가 잘 안되는 것 같지만 Java 용 GLR 파서를 지원하지 않으며 너무 복잡하여 어리석은 문제를 제외하고는, 내가 말했듯이, 문법 자체는 꽤 기초적이다.)

또는 문자열을 직접 토큰 화해야하고, 필요한 데이터를 구문 분석하기 위해 indexOf(), lastIndexOf() 등을 사용해야합니까? 그것이 남아있는 유일한 선택이었다 경우에만 너무 추한 이럴 것 때문에 나는 그것을 위해 갈 것이라고 나는 (잘못된 해석으로 이어질 것입니다) 어떤 경우

+0

각 "기능"이 coloum이고 각 행이 seatRecord 인 2 차원 어레이에 저장하는 것은 어떻습니까? 각 부분을 문자열로 처리하고 사용자 정의 구분 기호 (어쩌면 일부 불분명 한 유니 코드 문자)를 추가하여 이름을 다듬지 않아도됩니다. – Azulflame

답변

7

, 당신은 아마 간단한 정규 표현식 멀리 얻을 수 있습니다 캡처 그룹을 사용하면 관심있는 정보를 추출 할 수 있습니다.

2

당신은이 개 솔루션을 놓칠 수 있습니다

  • 을 이름에 몇 가지 제한을 추가하십시오. 나는 그 별칭을 받아 들일 수있는 널리 사용되는 시스템을 거의 기억할 수 없다. 영숫자 문자와 "_"구분 기호를 사용하게하십시오. 또한 좌석에 대한 키워드를 추가 할 수 있습니다 (예 : 단어가 별명 일 수 없음).
  • 문법을 기반으로 구문 분석을위한 유한 자동화를 구축 할 수도 있습니다. 나는 FSM이 그러한 모호성 문법을 다룰 수 있다고 생각한다. 일단 가지고 있으면, 원하는 모든 것을 파싱 할 수 있습니다.

어쨌든 원래 디자인에 문제가 있다고 생각합니다. 닉네임은 이러한 이름 집합을 허용해서는 안됩니다. 또한 이름 대신 식별자를 사용할 수없는 이유는 이름을 데이터베이스에 저장할 수 있기 때문입니다.

^Seat ([0-9]+): (.*) \(([0-9]+) in chips\)$ 

이 경우 정규식 엔진의 NFA는 귀하의 모호성을 해결하고, 괄호는 다음과 같습니다 당신의 입력 형식은 사용자가 지정한만큼 간단한 경우

+0

감사합니다. 문제는 그것이 그러한 별명을 허용하는 외부 소프트웨어이며, 그것에 대해 할 수있는 일이 없다는 것입니다. 또한 파싱 할 파일을 생성하므로 내가 할 수있는 일은 없지만이를 처리해야합니다. :) –

+0

오, 알겠습니다. 이 경우 NFA를 정규식과 함께 사용하면 도움이됩니다. 그런 모호성을 다룰 수 있다고 생각합니다. –

2

시스템에 대한 문법 (문맥이없는 문법으로 작성)과 같을 수 :

S -> seating nickname chips 

seating -> "Seat " number ":" 
number -> "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 
number -> number number 

nickname -> "a" | "b" | "c" ...... | "z" | ...."+" | "?" | number 
nickname -> nickname nickname 

chips -> "(" number "in chips)" 

공지 형태의 규칙이 기본적으로 무한 수 있습니다

number -> number number 

문법. "무한 문법"은 모든 것을 캡슐화한다는 의미는 아닙니다. 위의 줄은 기본적으로 정규식 (\d*)과 동일합니다.

CFG에서 문법을 입력 한 다음 규칙적인 문법으로 변환하면 대부분 시간이 많이 걸립니다. 그것을하는 방법에 대한 자세한 내용 here. 행운을 빕니다!