2017-02-15 14 views
3

Perl 6 문법을 사용하여 .sql 파일을 작성하고 싶습니다. 구문 분석 할 때 관련없는 일부 줄을 건너 뛸 수 있을지 궁금합니다.Perl 6 문법을 사용하여 구조화 된 텍스트를 구문 분석 할 때 관련이없는 행을 건너 뛰는 방법은 무엇입니까?

예를 들면 : 나는 DROP 라인, /*!....!*/ 라인, -- 라인, 다음과 같은 텍스트 CREATE TABLE 블록 외부 공백을 건너 뛰려면.

입니다

, 나는 CREATE TABLE 블록에 집중 할 JUSE : 어떤 제안이

DROP TABLE IF EXISTS `abcd`; 
/*!40101 SET @saved_cs_client  = @@character_set_client */; 
/*!40101 SET character_set_client = utf8 */; 
CREATE TABLE `abcd` (
    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'app_id', 
    `username` varchar(255) DEFAULT NULL COMMENT 'username', 
    `url` varbinary(255) DEFAULT NULL COMMENT 'url', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `NewIndex1` (`username`) 
) ENGINE=InnoDB AUTO_INCREMENT=954 DEFAULT CHARSET=utf8; 
/*!40101 SET character_set_client = @saved_cs_client */; 

-- 
-- Table structure for table `temp` 
-- 

DROP TABLE IF EXISTS `temp`; 
/*!40101 SET @saved_cs_client  = @@character_set_client */; 
/*!40101 SET character_set_client = utf8 */; 
CREATE TABLE `temp` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `address` varchar(15) NOT NULL, 
    `name` varchar(50) DEFAULT NULL, 
    `phone_model` varchar(10) NOT NULL, 
    `expire_time` varchar(15) NOT NULL, 
    `created` varchar(15) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=1496 DEFAULT CHARSET=utf8; 
/*!40101 SET character_set_client = @saved_cs_client */; 

있습니까?

답변

4

그냥 액션 클래스의 값을 버리는 것은 어떨까요?

grammar SQL { 
    token TOP { <command>+ %% \n } 
    token command { <create-table> | <drop-table> | ... } 
    token drop-table { ... } 
    token create-table { ... } 
    ... 
} 

class Create-only { 
    method TOP ($/) { make @<command>».made } 
    method command ($/) { 
    make $/.values[0].made 
    } 
    method drop-table ($/) { make Empty } 
    method create-table ($/) { 
    make %($/.pairs.map: {.key => .value.made}) 
    # or whatever you need to to pass through the made values 
    } 
    ... 
} 

SQL.parse($text,:actions(Create-only)).made; 

간단한 예제가 작동 할 수 있음을 보여 :

grammar :: { 
    token TOP { <c>+ %% \n } 
    token c {<a>|<b>} 
    token a {a} 
    token b {b} 
}.parse(

    'abbbaab'.comb.join("\n"), 

    :actions(class :: { 
    method TOP ($/){make @<c>».made} 
    method a ($/){make ~$/} 
    method b ($/){make Empty} 
    method c($/){make $/.values[0].made } 
    }) 
).made.say 
[a a a] 
+0

멋진 '빈'! 하하 – ohmycloudy

4

대신 '토큰'의 '규칙'을 사용하는 경우, 브래드의 대답에서 SQL 문법 예를 들어, 원자 뒤에있는 공백이 <ws>으로 캡처되지 않는 호출로 바뀌므로 <ws> (공백)을 다시 정의하여 주석 등 다른 내용을 포함 할 수 있습니다 (예 :

).
token ws { \s* | <slash-star-comment>* | <dashes-comment>* } 
token slash-star-comment { \s* '/*!' .*? '!*/' \s* } 
token dashes-comment { \s* '--' \N* \s* } 

거기에 흩어져있는 \ s *가 있으므로 주석 앞이나 뒤에 공백이있을 수 있습니다.

+0

도 좋은 방법이라고 생각합니다. – ohmycloudy