2013-02-26 7 views
1

저는 ParseKit을 사용하여 측정 단위를 구문 분석합니다. 이것을하기 위해서 저는 문법을 제공해야합니다. 나는 인터넷 검색을 시도했지만 저를 멀리하지 않았다. 그것이 내 자신에 대한 재미있는 운동이지만 나는 그것을 올바르게 얻고 싶습니다. ParseKit이 같은 BNF 문법을 기대하고있다 :BNF 측정 단위에 대한 문법

@start = number units; 
units = unit+ | unit+/unit+; 
unit = prefix baseUnit | baseUnit; 
prefix = '' | 'milli' | 'micro' | 'pico'; 
baseUnit = 'm' | 'meter' | 'g' | 'gram' 

내가 같은 입력을 지원하기 위해 찾고 있어요 : 나는 unidata.ucar.edu에서 발견

25 m² 
25 m^-3 
25 m**-5/kg**-2 
25 m/s squared 
25 mm² per second 
25 m/s 
5 kg meters per second squared 
3 m-kg/s^2 
3 m kilograms 
+0

게시 된 문법을 개선하여 원하는 입력을 완벽하게 지원할 수있는 도움을 찾고 있습니까? – rmaddy

+0

@rmaddy 공식/비공식 문법을 참조하는 것이 좋지만 개선을 환영합니다. –

+0

'나'란 무엇입니까? 'kge '란 무엇입니까? –

답변

1

개발자.

문법이 의미 상 올바르다는 것을 판별하기 위해 예제 입력을 자세히 보지 않았습니다.

그러나, do은 기존 문법에 두 가지 중요한 구문 문제를 참조하십시오.


먼저,이 라인은 왼쪽 재귀를 포함 (또한 인용되지 않은 /와 구문 오류) :

:

units = unit+ | unit+/unit+; // Incorrect. Will not work. 

당신은 이런 식으로 왼쪽 재귀를 제거하려면이 라인을 변경해야합니다

units = unit ('/' unit)*; 

my prior answer for more information on eliminating Left Recursion in your ParseKit grammars을 참조하십시오.


둘째,이 라인은 ''를 사용하여 "빈"경기를 할 수 있도록하려고 생각 : ParseKit 문법에 구문을 지원하지 않습니다

prefix = '' | 'milli' | 'micro' | 'pico'; // Incorrect. Will not work. 

. 이 기능은 완벽하게 지원되지만 구문처럼 Empty입니다 : 도움이

prefix = Empty | 'milli' | 'micro' | 'pico'; 

희망.

+0

우수. 그것은 몇 가지를 지워줍니다. 마침내 나는 '피코 그램'과 같은 것을 파싱 할 수 있지만 '피코 그램'은 파싱 할 수 없다. 하위 문자열을 구문 분석하는 방법에 대해서는 문서에서 아무것도 보지 못했습니다. –

+0

PKTokenizer를 사용자 지정해야하지만 어디서부터 시작해야할지 모르겠습니다. –

+0

당신은 내 대답을 여기에 정확하게 표시 (또는 적어도 상향 투표) 한 다음 토큰 화에 관한 새로운 질문을 할 수 있습니다 :). 필자는 'ParseKit'이라는 태그가 달린 모든 질문에 적시에 답변합니다. –

1

This grammar는 unwieldily 불구하고 꽤 공식을보고하지 않습니다 접두사 또는 단위를 포함합니다.

단위 - 사양 : 여기 ParseKit 중 하나 의 아무것도 Shift 키 사양

Shift-Spec: one of 
     Product-Spec 
     Product-Spec SHIFT REAL 
     Product-Spec SHIFT INT 
     Product-Spec SHIFT Timestamp 

Product-Spec: one of 
     Power-Spec 
     Product-Spec Power-Spec 
     Product-Spec MULTIPLY Power-Spec 
     Product-Spec DIVIDE Power-Spec 

Power-Spec: one of 
     Basic-Spec 
     Basic-Spec INT 
     Basic-Spec EXPONENT 
     Basic-Spec RAISE INT 

Basic-Spec: one of 
     ID 
     "(" Shift-Spec ")" 
     LOGREF Product_Spec ")" 
     Number 

Number: one of 
     INT 
     REAL 

Timestamp: one of 
     DATE 
     DATE CLOCK 
     DATE CLOCK CLOCK 
     DATE CLOCK INT 
     DATE CLOCK ID 
     TIMESTAMP 
     TIMESTAMP INT 
     TIMESTAMP ID 

SHIFT: 
     <space>* <shift_op> <space>* 

<shift_op>: one of 
     "@" 
     "after" 
     "from" 
     "since" 
     "ref" 

REAL: 
     the usual floating-point format 

INT: 
     the usual integer format 

MULTIPLY: one of 
     "-" 
     "." 
     "*" 
     <space>+ 
     <centered middot> 

DIVIDE: 
     <space>* <divide_op> <space>* 

<divide_op>: one of 
     per 
     PER 
     "/" 

EXPONENT: 
     ISO-8859-9 or UTF-8 encoded exponent characters 

RAISE: one of 
     "^" 
     "**" 

ID: one of 
     <id> 
     "%" 
     "'" 
     "\"" 
     degree sign 
     greek mu character 

<id>: 
     <alpha> <alphanum>* 

<alpha>: 
     [A-Za-z_] 
     ISO-8859-1 alphabetic characters 
     non-breaking space 

<alphanum>: one of 
     <alpha> 
     <digit> 

<digit>: 
     [0-9] 

LOGREF: 
     <log> <space>* <logref> 

<log>: one of 
     "log" 
     "lg" 
     "ln" 
     "lb" 

<logref>: 
     "(" <space>* <re> ":"? <space>* 

DATE: 
     <year> "-" <month> ("-" <day>)? 

<year>: 
     [+-]?[0-9]{1,4} 

<month>: 
     "0"?[1-9]|1[0-2] 

<day>: 
     "0"?[1-9]|[1-2][0-9]|"30"|"31" 

CLOCK: 
     <hour> ":" <minute> (":" <second>)? 

TIMSTAMP: 
     <year> (<month> <day>?)? "T" <hour> (<minute> <second>?)? 

<hour>: 
     [+-]?[0-1]?[0-9]|2[0-3] 

<minute>: 
     [0-5]?[0-9] 

<second>: 
     (<minute>|60) (\.[0-9]*)?