

peg.jsにおいて  
以下のようなparserを書きました

**perser.pegjs**

[code]

    Start
    = c:(Content+) EOL {
      return c;
    }
    
    Content 
    = openId:OpenTag c:(Content)+ closeId:CloseTag {
        if (openId !== closeId) {
            throw new Error( "expect </ " + openId+ "> but </" + closeId + ">");
        }
        return { type:'element', id:openId, content:c};
    }
    /txt:ContentText {
      return {type:'txt', content:txt.trim()}
    }
    
    
    ContentText = [^<>\n]+ { return text();}
    
    OpenTag = "<" id:[0-9]+ ">" { return parseInt(id.join(''))}
    CloseTag = "</" id:[0-9]+ ">" { return parseInt(id.join(''))}
    
    
    EOL = [\n]*
    
[/code]

以下の入力を受け取りjsonを吐きます

[code]

    <1>abc</1><2>def<3>ghi</3></2>
    
[/code]

**出力**

[code]

    [
       {
          "type": "element",
          "id": 1,
          "content": [
             {
                "type": "txt",
                "content": "abc"
             }
          ]
       },
       {
          "type": "element",
          "id": 2,
          "content": [
             {
                "type": "txt",
                "content": "def"
             },
             {
                "type": "element",
                "id": 3,
                "content": [
                   {
                      "type": "txt",
                      "content": "ghi"
                   }
                ]
             }
          ]
       }
    ]
    
[/code]

このparserではContentText に **< ,>** を含めることが出来ませんが  
なんとか含ませたい場合どの様にparserをかけばよろしいでしょうか？


CC BY-SA 3.0
2016-10-31T05:32:55.243
30009
2017-12-03T14:06:30.663
2017-12-03T14:06:30.663
754
14874
question
javascript
peg.jsにて区切り文字とした'<' ,'>'をParserの状況によって意味を変えられるようにしたい


(質問者様による自己回答を Wiki として投稿しています)

一応自己解決しましたのでいかに修正内容を纏めます。  
もっとスマートな方法があればご教授下さい。

[code]

    Start = c:(Content+) EOL {
        return c;
    }
    
    Content = open:OpenTag c:Content+ close:CloseTag {
       return { type:'element', id:open, content:c};
    }
    /
    txt:Text {
      return {type:'txt', content:txt.trim()}
    }
    
    Text = txt:(NotOpenTag/NotCloseTag/NotTagNotEOL)+ { return txt.join('').trim(); }
    
    NotTagNotEOL = [^<>\n]   { return text();}
    
    NotOpenTag = "<" !Digit !"/" { return text();}
    /!Digit ">" { return text();}
    
    NotCloseTag = "</" !Digit { return text(); }
    
    OpenTag = "<" id:Digit ">" { return id;}
    CloseTag = "</" id:Digit ">" { return id; }
    
    Digit = [0-9]+  { return parseInt(text()); }
    
    EOL = [\n]*
    
[/code]


CC BY-SA 3.0
2017-12-03T14:05:49.783
40002
2017-12-03T14:05:49.783
754
30009
answer