Browse Source

New: PCRE version

Leonardo Di Donato 8 years ago
parent
commit
c93dbdde39
13 changed files with 60 additions and 1142 deletions
  1. 0 2
      grammar/.gitignore
  2. 0 122
      grammar/Urn.g4
  3. 0 8
      grammar/Urn.tokens
  4. 0 8
      grammar/UrnLexer.tokens
  5. 0 39
      grammar/urn_base_listener.go
  6. 0 124
      grammar/urn_lexer.go
  7. 0 27
      grammar/urn_listener.go
  8. 0 634
      grammar/urn_parser.go
  9. 0 33
      listener.go
  10. 0 41
      listener_test.go
  11. 0 34
      makefile
  12. 58 64
      urn.go
  13. 2 6
      urn_test.go

+ 0 - 2
grammar/.gitignore

@@ -1,2 +0,0 @@
-.antlr
-antlr

+ 0 - 122
grammar/Urn.g4

@@ -1,122 +0,0 @@
-/*
- * This grammar encodes the URN syntax.
- *
- * RFC 2141.
- * https.//tools.ietf.org/html/rfc2141
- */
-grammar Urn;
-
-@parser::members {
-func isIdentifier(s string) bool {
-    for i, r := range s {
-        // !unicode.IsLetter(r) etc. when (if) we'll need unicode
-        if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') && (r < '0' || r > '9') && (r != '-' || (i == 0 && r == '-')) {
-            return false
-        }
-    }
-    return true
-}
-}
-
-urn
-    : Urn Colon iD Colon sS EOF
-    ;
-
-iD  
-    : Part
-    {len($ctx.GetText()) <= 32}?<fail={"exceed max (32) number of characters"}>
-    {isIdentifier($ctx.GetText())}?<fail={"is not a valid identifier"}>
-    ;
-
-sS
-    : Part (Colon|Hyphen)* sS?
-    | (Colon|Hyphen)+ sS?
-    | Part sS?
-    | Urn
-    ;
-
-Urn
-    : URN
-    ;
-
-Part
-    : IDENTIFIER
-    | CHARS
-    ;
-
-Colon
-    : ':'
-    ;
-
-Hyphen
-    : '-'
-    ;
-
-Whitespace
-    : ' '
-    ;
-
-fragment URN
-    : [uU][rR][nN]
-    ;
-
-fragment IDENTIFIER   
-    : ALPHA_NUMERIC (ALPHA_NUMERIC|Hyphen)+
-    ;
-
-fragment CHARS
-    : (TRANSLATION|HEX)+
-    ;
-
-fragment HEX
-    : '%' HEX_DIGIT HEX_DIGIT
-    ;
-
-fragment NUMBER
-    : [0-9]
-    ;
-
-fragment LETTER
-    : [A-Z]
-    | [a-z]
-    ;
-
-fragment ALPHA_NUMERIC
-    : NUMBER
-    | LETTER 
-    ;
-
-fragment OTHER
-    : '('
-    | ')'
-    | '+'
-    | ','
-    | '.'
-    | '='
-    | '@'
-    | ';'
-    | '$'
-    | '_'
-    | '!'
-    | '*'
-    | '\''
-    ;
-
-fragment HEX_DIGIT
-    : NUMBER
-    | [A-F]
-    | [a-f]
-    ;
-
-fragment RESERVED
-    : '%'
-    | '/'
-    | '?'
-    | '#'
-    ;
-
-fragment TRANSLATION
-    : OTHER
-    | RESERVED
-    | ALPHA_NUMERIC
-    ;

+ 0 - 8
grammar/Urn.tokens

@@ -1,8 +0,0 @@
-Urn=1
-Part=2
-Colon=3
-Hyphen=4
-Whitespace=5
-':'=3
-'-'=4
-' '=5

+ 0 - 8
grammar/UrnLexer.tokens

@@ -1,8 +0,0 @@
-Urn=1
-Part=2
-Colon=3
-Hyphen=4
-Whitespace=5
-':'=3
-'-'=4
-' '=5

+ 0 - 39
grammar/urn_base_listener.go

@@ -1,39 +0,0 @@
-// Generated from /home/leodido/workspaces/go/src/github.com/leodido/go-urn/grammar/Urn.g4 by ANTLR 4.7.
-
-package grammar // Urn
-import "github.com/antlr/antlr4/runtime/Go/antlr"
-
-// BaseUrnListener is a complete listener for a parse tree produced by UrnParser.
-type BaseUrnListener struct{}
-
-var _ UrnListener = &BaseUrnListener{}
-
-// VisitTerminal is called when a terminal node is visited.
-func (s *BaseUrnListener) VisitTerminal(node antlr.TerminalNode) {}
-
-// VisitErrorNode is called when an error node is visited.
-func (s *BaseUrnListener) VisitErrorNode(node antlr.ErrorNode) {}
-
-// EnterEveryRule is called when any rule is entered.
-func (s *BaseUrnListener) EnterEveryRule(ctx antlr.ParserRuleContext) {}
-
-// ExitEveryRule is called when any rule is exited.
-func (s *BaseUrnListener) ExitEveryRule(ctx antlr.ParserRuleContext) {}
-
-// EnterUrn is called when production urn is entered.
-func (s *BaseUrnListener) EnterUrn(ctx *UrnContext) {}
-
-// ExitUrn is called when production urn is exited.
-func (s *BaseUrnListener) ExitUrn(ctx *UrnContext) {}
-
-// EnterID is called when production iD is entered.
-func (s *BaseUrnListener) EnterID(ctx *IDContext) {}
-
-// ExitID is called when production iD is exited.
-func (s *BaseUrnListener) ExitID(ctx *IDContext) {}
-
-// EnterSS is called when production sS is entered.
-func (s *BaseUrnListener) EnterSS(ctx *SSContext) {}
-
-// ExitSS is called when production sS is exited.
-func (s *BaseUrnListener) ExitSS(ctx *SSContext) {}

+ 0 - 124
grammar/urn_lexer.go

@@ -1,124 +0,0 @@
-// Generated from /home/leodido/workspaces/go/src/github.com/leodido/go-urn/grammar/Urn.g4 by ANTLR 4.7.
-
-package grammar
-import (
-	"fmt"
-	"unicode"
-
-	"github.com/antlr/antlr4/runtime/Go/antlr"
-)
-// Suppress unused import error
-var _ = fmt.Printf
-var _ = unicode.IsLetter
-
-
-var serializedLexerAtn = []uint16{
-	3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 7, 90, 8, 
-	1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 
-	7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 
-	13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 3, 2, 
-	3, 2, 3, 3, 3, 3, 5, 3, 40, 10, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 
-	3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 6, 8, 55, 10, 8, 13, 8, 14, 8, 
-	56, 3, 9, 3, 9, 6, 9, 61, 10, 9, 13, 9, 14, 9, 62, 3, 10, 3, 10, 3, 10, 
-	3, 10, 3, 11, 3, 11, 3, 12, 5, 12, 72, 10, 12, 3, 13, 3, 13, 5, 13, 76, 
-	10, 13, 3, 14, 3, 14, 3, 15, 3, 15, 5, 15, 82, 10, 15, 3, 16, 3, 16, 3, 
-	17, 3, 17, 3, 17, 5, 17, 89, 10, 17, 2, 2, 18, 3, 3, 5, 4, 7, 5, 9, 6, 
-	11, 7, 13, 2, 15, 2, 17, 2, 19, 2, 21, 2, 23, 2, 25, 2, 27, 2, 29, 2, 31, 
-	2, 33, 2, 3, 2, 10, 4, 2, 87, 87, 119, 119, 4, 2, 84, 84, 116, 116, 4, 
-	2, 80, 80, 112, 112, 3, 2, 50, 59, 4, 2, 67, 92, 99, 124, 10, 2, 35, 35, 
-	38, 38, 41, 46, 48, 48, 61, 61, 63, 63, 66, 66, 97, 97, 4, 2, 67, 72, 99, 
-	104, 6, 2, 37, 37, 39, 39, 49, 49, 65, 65, 2, 87, 2, 3, 3, 2, 2, 2, 2, 
-	5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 3, 
-	35, 3, 2, 2, 2, 5, 39, 3, 2, 2, 2, 7, 41, 3, 2, 2, 2, 9, 43, 3, 2, 2, 2, 
-	11, 45, 3, 2, 2, 2, 13, 47, 3, 2, 2, 2, 15, 51, 3, 2, 2, 2, 17, 60, 3, 
-	2, 2, 2, 19, 64, 3, 2, 2, 2, 21, 68, 3, 2, 2, 2, 23, 71, 3, 2, 2, 2, 25, 
-	75, 3, 2, 2, 2, 27, 77, 3, 2, 2, 2, 29, 81, 3, 2, 2, 2, 31, 83, 3, 2, 2, 
-	2, 33, 88, 3, 2, 2, 2, 35, 36, 5, 13, 7, 2, 36, 4, 3, 2, 2, 2, 37, 40, 
-	5, 15, 8, 2, 38, 40, 5, 17, 9, 2, 39, 37, 3, 2, 2, 2, 39, 38, 3, 2, 2, 
-	2, 40, 6, 3, 2, 2, 2, 41, 42, 7, 60, 2, 2, 42, 8, 3, 2, 2, 2, 43, 44, 7, 
-	47, 2, 2, 44, 10, 3, 2, 2, 2, 45, 46, 7, 34, 2, 2, 46, 12, 3, 2, 2, 2, 
-	47, 48, 9, 2, 2, 2, 48, 49, 9, 3, 2, 2, 49, 50, 9, 4, 2, 2, 50, 14, 3, 
-	2, 2, 2, 51, 54, 5, 25, 13, 2, 52, 55, 5, 25, 13, 2, 53, 55, 5, 9, 5, 2, 
-	54, 52, 3, 2, 2, 2, 54, 53, 3, 2, 2, 2, 55, 56, 3, 2, 2, 2, 56, 54, 3, 
-	2, 2, 2, 56, 57, 3, 2, 2, 2, 57, 16, 3, 2, 2, 2, 58, 61, 5, 33, 17, 2, 
-	59, 61, 5, 19, 10, 2, 60, 58, 3, 2, 2, 2, 60, 59, 3, 2, 2, 2, 61, 62, 3, 
-	2, 2, 2, 62, 60, 3, 2, 2, 2, 62, 63, 3, 2, 2, 2, 63, 18, 3, 2, 2, 2, 64, 
-	65, 7, 39, 2, 2, 65, 66, 5, 29, 15, 2, 66, 67, 5, 29, 15, 2, 67, 20, 3, 
-	2, 2, 2, 68, 69, 9, 5, 2, 2, 69, 22, 3, 2, 2, 2, 70, 72, 9, 6, 2, 2, 71, 
-	70, 3, 2, 2, 2, 72, 24, 3, 2, 2, 2, 73, 76, 5, 21, 11, 2, 74, 76, 5, 23, 
-	12, 2, 75, 73, 3, 2, 2, 2, 75, 74, 3, 2, 2, 2, 76, 26, 3, 2, 2, 2, 77, 
-	78, 9, 7, 2, 2, 78, 28, 3, 2, 2, 2, 79, 82, 5, 21, 11, 2, 80, 82, 9, 8, 
-	2, 2, 81, 79, 3, 2, 2, 2, 81, 80, 3, 2, 2, 2, 82, 30, 3, 2, 2, 2, 83, 84, 
-	9, 9, 2, 2, 84, 32, 3, 2, 2, 2, 85, 89, 5, 27, 14, 2, 86, 89, 5, 31, 16, 
-	2, 87, 89, 5, 25, 13, 2, 88, 85, 3, 2, 2, 2, 88, 86, 3, 2, 2, 2, 88, 87, 
-	3, 2, 2, 2, 89, 34, 3, 2, 2, 2, 12, 2, 39, 54, 56, 60, 62, 71, 75, 81, 
-	88, 2,
-}
-
-var lexerDeserializer = antlr.NewATNDeserializer(nil)
-var lexerAtn = lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn)
-
-var lexerChannelNames = []string{
-	"DEFAULT_TOKEN_CHANNEL", "HIDDEN",
-}
-
-var lexerModeNames = []string{
-	"DEFAULT_MODE",
-}
-
-var lexerLiteralNames = []string{
-	"", "", "", "':'", "'-'", "' '",
-}
-
-var lexerSymbolicNames = []string{
-	"", "Urn", "Part", "Colon", "Hyphen", "Whitespace",
-}
-
-var lexerRuleNames = []string{
-	"Urn", "Part", "Colon", "Hyphen", "Whitespace", "URN", "IDENTIFIER", "CHARS", 
-	"HEX", "NUMBER", "LETTER", "ALPHA_NUMERIC", "OTHER", "HEX_DIGIT", "RESERVED", 
-	"TRANSLATION",
-}
-
-type UrnLexer struct {
-	*antlr.BaseLexer
-	channelNames []string
-	modeNames []string
-	// TODO: EOF string
-}
-
-var lexerDecisionToDFA = make([]*antlr.DFA, len(lexerAtn.DecisionToState))
-
-func init() {
-	for index, ds := range lexerAtn.DecisionToState {
-		lexerDecisionToDFA[index] = antlr.NewDFA(ds, index)
-	}
-}
-
-func NewUrnLexer(input antlr.CharStream) *UrnLexer {
-
-	l := new(UrnLexer)
-
-	l.BaseLexer = antlr.NewBaseLexer(input)
-	l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache())
-
-	l.channelNames = lexerChannelNames
-	l.modeNames = lexerModeNames
-	l.RuleNames = lexerRuleNames
-	l.LiteralNames = lexerLiteralNames
-	l.SymbolicNames = lexerSymbolicNames
-	l.GrammarFileName = "Urn.g4"
-	// TODO: l.EOF = antlr.TokenEOF
-
-	return l
-}
-
-// UrnLexer tokens.
-const (
-	UrnLexerUrn = 1
-	UrnLexerPart = 2
-	UrnLexerColon = 3
-	UrnLexerHyphen = 4
-	UrnLexerWhitespace = 5
-)
-

+ 0 - 27
grammar/urn_listener.go

@@ -1,27 +0,0 @@
-// Generated from /home/leodido/workspaces/go/src/github.com/leodido/go-urn/grammar/Urn.g4 by ANTLR 4.7.
-
-package grammar // Urn
-import "github.com/antlr/antlr4/runtime/Go/antlr"
-
-// UrnListener is a complete listener for a parse tree produced by UrnParser.
-type UrnListener interface {
-	antlr.ParseTreeListener
-
-	// EnterUrn is called when entering the urn production.
-	EnterUrn(c *UrnContext)
-
-	// EnterID is called when entering the iD production.
-	EnterID(c *IDContext)
-
-	// EnterSS is called when entering the sS production.
-	EnterSS(c *SSContext)
-
-	// ExitUrn is called when exiting the urn production.
-	ExitUrn(c *UrnContext)
-
-	// ExitID is called when exiting the iD production.
-	ExitID(c *IDContext)
-
-	// ExitSS is called when exiting the sS production.
-	ExitSS(c *SSContext)
-}

+ 0 - 634
grammar/urn_parser.go

@@ -1,634 +0,0 @@
-// Generated from /home/leodido/workspaces/go/src/github.com/leodido/go-urn/grammar/Urn.g4 by ANTLR 4.7.
-
-package grammar // Urn
-import (
-	"fmt"
-	"reflect"
-	"strconv"
-
-	"github.com/antlr/antlr4/runtime/Go/antlr"
-)
-
-// Suppress unused import errors
-var _ = fmt.Printf
-var _ = reflect.Copy
-var _ = strconv.Itoa
-
-
-var parserATN = []uint16{
-	3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 7, 45, 4, 
-	2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 
-	2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 7, 4, 22, 10, 4, 12, 4, 14, 4, 25, 
-	11, 4, 3, 4, 5, 4, 28, 10, 4, 3, 4, 6, 4, 31, 10, 4, 13, 4, 14, 4, 32, 
-	3, 4, 5, 4, 36, 10, 4, 3, 4, 3, 4, 5, 4, 40, 10, 4, 3, 4, 5, 4, 43, 10, 
-	4, 3, 4, 2, 2, 5, 2, 4, 6, 2, 3, 3, 2, 5, 6, 2, 49, 2, 8, 3, 2, 2, 2, 4, 
-	15, 3, 2, 2, 2, 6, 42, 3, 2, 2, 2, 8, 9, 7, 3, 2, 2, 9, 10, 7, 5, 2, 2, 
-	10, 11, 5, 4, 3, 2, 11, 12, 7, 5, 2, 2, 12, 13, 5, 6, 4, 2, 13, 14, 7, 
-	2, 2, 3, 14, 3, 3, 2, 2, 2, 15, 16, 7, 4, 2, 2, 16, 17, 6, 3, 2, 3, 17, 
-	18, 6, 3, 3, 3, 18, 5, 3, 2, 2, 2, 19, 23, 7, 4, 2, 2, 20, 22, 9, 2, 2, 
-	2, 21, 20, 3, 2, 2, 2, 22, 25, 3, 2, 2, 2, 23, 21, 3, 2, 2, 2, 23, 24, 
-	3, 2, 2, 2, 24, 27, 3, 2, 2, 2, 25, 23, 3, 2, 2, 2, 26, 28, 5, 6, 4, 2, 
-	27, 26, 3, 2, 2, 2, 27, 28, 3, 2, 2, 2, 28, 43, 3, 2, 2, 2, 29, 31, 9, 
-	2, 2, 2, 30, 29, 3, 2, 2, 2, 31, 32, 3, 2, 2, 2, 32, 30, 3, 2, 2, 2, 32, 
-	33, 3, 2, 2, 2, 33, 35, 3, 2, 2, 2, 34, 36, 5, 6, 4, 2, 35, 34, 3, 2, 2, 
-	2, 35, 36, 3, 2, 2, 2, 36, 43, 3, 2, 2, 2, 37, 39, 7, 4, 2, 2, 38, 40, 
-	5, 6, 4, 2, 39, 38, 3, 2, 2, 2, 39, 40, 3, 2, 2, 2, 40, 43, 3, 2, 2, 2, 
-	41, 43, 7, 3, 2, 2, 42, 19, 3, 2, 2, 2, 42, 30, 3, 2, 2, 2, 42, 37, 3, 
-	2, 2, 2, 42, 41, 3, 2, 2, 2, 43, 7, 3, 2, 2, 2, 8, 23, 27, 32, 35, 39, 
-	42,
-}
-var deserializer = antlr.NewATNDeserializer(nil)
-var deserializedATN = deserializer.DeserializeFromUInt16(parserATN)
-
-var literalNames = []string{
-	"", "", "", "':'", "'-'", "' '",
-}
-var symbolicNames = []string{
-	"", "Urn", "Part", "Colon", "Hyphen", "Whitespace",
-}
-
-var ruleNames = []string{
-	"urn", "iD", "sS",
-}
-var decisionToDFA = make([]*antlr.DFA, len(deserializedATN.DecisionToState))
-
-func init() {
-	for index, ds := range deserializedATN.DecisionToState {
-		decisionToDFA[index] = antlr.NewDFA(ds, index)
-	}
-}
-
-type UrnParser struct {
-	*antlr.BaseParser
-}
-
-func NewUrnParser(input antlr.TokenStream) *UrnParser {
-	this := new(UrnParser)
-
-	this.BaseParser = antlr.NewBaseParser(input)
-
-	this.Interpreter = antlr.NewParserATNSimulator(this, deserializedATN, decisionToDFA, antlr.NewPredictionContextCache())
-	this.RuleNames = ruleNames
-	this.LiteralNames = literalNames
-	this.SymbolicNames = symbolicNames
-	this.GrammarFileName = "Urn.g4"
-
-	return this
-}
-
-
-func isIdentifier(s string) bool {
-    for i, r := range s {
-        // !unicode.IsLetter(r) etc. when (if) we'll need unicode
-        if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') && (r < '0' || r > '9') && (r != '-' || (i == 0 && r == '-')) {
-            return false
-        }
-    }
-    return true
-}
-
-
-
-// UrnParser tokens.
-const (
-	UrnParserEOF = antlr.TokenEOF
-	UrnParserUrn = 1
-	UrnParserPart = 2
-	UrnParserColon = 3
-	UrnParserHyphen = 4
-	UrnParserWhitespace = 5
-)
-
-// UrnParser rules.
-const (
-	UrnParserRULE_urn = 0
-	UrnParserRULE_iD = 1
-	UrnParserRULE_sS = 2
-)
-
-// IUrnContext is an interface to support dynamic dispatch.
-type IUrnContext interface {
-	antlr.ParserRuleContext
-
-	// GetParser returns the parser.
-	GetParser() antlr.Parser
-
-	// IsUrnContext differentiates from other interfaces.
-	IsUrnContext()
-}
-
-type UrnContext struct {
-	*antlr.BaseParserRuleContext
-	parser antlr.Parser
-}
-
-func NewEmptyUrnContext() *UrnContext {
-	var p = new(UrnContext)
-	p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
-	p.RuleIndex = UrnParserRULE_urn
-	return p
-}
-
-func (*UrnContext) IsUrnContext() {}
-
-func NewUrnContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *UrnContext {
-	var p = new(UrnContext)
-
-	p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
-
-	p.parser = parser
-	p.RuleIndex = UrnParserRULE_urn
-
-	return p
-}
-
-func (s *UrnContext) GetParser() antlr.Parser { return s.parser }
-
-func (s *UrnContext) Urn() antlr.TerminalNode {
-	return s.GetToken(UrnParserUrn, 0)
-}
-
-func (s *UrnContext) AllColon() []antlr.TerminalNode {
-	return s.GetTokens(UrnParserColon)
-}
-
-func (s *UrnContext) Colon(i int) antlr.TerminalNode {
-	return s.GetToken(UrnParserColon, i)
-}
-
-func (s *UrnContext) ID() IIDContext {
-	var t = s.GetTypedRuleContext(reflect.TypeOf((*IIDContext)(nil)).Elem(), 0)
-
-	if t == nil {
-		return nil
-	}
-
-	return t.(IIDContext)
-}
-
-func (s *UrnContext) SS() ISSContext {
-	var t = s.GetTypedRuleContext(reflect.TypeOf((*ISSContext)(nil)).Elem(), 0)
-
-	if t == nil {
-		return nil
-	}
-
-	return t.(ISSContext)
-}
-
-func (s *UrnContext) EOF() antlr.TerminalNode {
-	return s.GetToken(UrnParserEOF, 0)
-}
-
-func (s *UrnContext) GetRuleContext() antlr.RuleContext {
-	return s
-}
-
-func (s *UrnContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
-	return antlr.TreesStringTree(s, ruleNames, recog)
-}
-
-
-func (s *UrnContext) EnterRule(listener antlr.ParseTreeListener) {
-	if listenerT, ok := listener.(UrnListener); ok {
-		listenerT.EnterUrn(s)
-	}
-}
-
-func (s *UrnContext) ExitRule(listener antlr.ParseTreeListener) {
-	if listenerT, ok := listener.(UrnListener); ok {
-		listenerT.ExitUrn(s)
-	}
-}
-
-
-
-
-func (p *UrnParser) Urn() (localctx IUrnContext) {
-	localctx = NewUrnContext(p, p.GetParserRuleContext(), p.GetState())
-	p.EnterRule(localctx, 0, UrnParserRULE_urn)
-
-	defer func() {
-		p.ExitRule()
-	}()
-
-	defer func() {
-		if err := recover(); err != nil {
-			if v, ok := err.(antlr.RecognitionException); ok {
-				localctx.SetException(v)
-				p.GetErrorHandler().ReportError(p, v)
-				p.GetErrorHandler().Recover(p, v)
-			} else {
-				panic(err)
-			}
-		}
-	}()
-
-	p.EnterOuterAlt(localctx, 1)
-	{
-		p.SetState(6)
-		p.Match(UrnParserUrn)
-	}
-	{
-		p.SetState(7)
-		p.Match(UrnParserColon)
-	}
-	{
-		p.SetState(8)
-		p.ID()
-	}
-	{
-		p.SetState(9)
-		p.Match(UrnParserColon)
-	}
-	{
-		p.SetState(10)
-		p.SS()
-	}
-	{
-		p.SetState(11)
-		p.Match(UrnParserEOF)
-	}
-
-
-
-	return localctx
-}
-
-
-// IIDContext is an interface to support dynamic dispatch.
-type IIDContext interface {
-	antlr.ParserRuleContext
-
-	// GetParser returns the parser.
-	GetParser() antlr.Parser
-
-	// IsIDContext differentiates from other interfaces.
-	IsIDContext()
-}
-
-type IDContext struct {
-	*antlr.BaseParserRuleContext
-	parser antlr.Parser
-}
-
-func NewEmptyIDContext() *IDContext {
-	var p = new(IDContext)
-	p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
-	p.RuleIndex = UrnParserRULE_iD
-	return p
-}
-
-func (*IDContext) IsIDContext() {}
-
-func NewIDContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *IDContext {
-	var p = new(IDContext)
-
-	p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
-
-	p.parser = parser
-	p.RuleIndex = UrnParserRULE_iD
-
-	return p
-}
-
-func (s *IDContext) GetParser() antlr.Parser { return s.parser }
-
-func (s *IDContext) Part() antlr.TerminalNode {
-	return s.GetToken(UrnParserPart, 0)
-}
-
-func (s *IDContext) GetRuleContext() antlr.RuleContext {
-	return s
-}
-
-func (s *IDContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
-	return antlr.TreesStringTree(s, ruleNames, recog)
-}
-
-
-func (s *IDContext) EnterRule(listener antlr.ParseTreeListener) {
-	if listenerT, ok := listener.(UrnListener); ok {
-		listenerT.EnterID(s)
-	}
-}
-
-func (s *IDContext) ExitRule(listener antlr.ParseTreeListener) {
-	if listenerT, ok := listener.(UrnListener); ok {
-		listenerT.ExitID(s)
-	}
-}
-
-
-
-
-func (p *UrnParser) ID() (localctx IIDContext) {
-	localctx = NewIDContext(p, p.GetParserRuleContext(), p.GetState())
-	p.EnterRule(localctx, 2, UrnParserRULE_iD)
-
-	defer func() {
-		p.ExitRule()
-	}()
-
-	defer func() {
-		if err := recover(); err != nil {
-			if v, ok := err.(antlr.RecognitionException); ok {
-				localctx.SetException(v)
-				p.GetErrorHandler().ReportError(p, v)
-				p.GetErrorHandler().Recover(p, v)
-			} else {
-				panic(err)
-			}
-		}
-	}()
-
-	p.EnterOuterAlt(localctx, 1)
-	{
-		p.SetState(13)
-		p.Match(UrnParserPart)
-	}
-	p.SetState(14)
-
-	if !(len(localctx.(*IDContext).GetText()) <= 32) {
-		panic(antlr.NewFailedPredicateException(p, "len($ctx.GetText()) <= 32", "exceed max (32) number of characters"))
-	}
-	p.SetState(15)
-
-	if !(isIdentifier(localctx.(*IDContext).GetText())) {
-		panic(antlr.NewFailedPredicateException(p, "isIdentifier($ctx.GetText())", "is not a valid identifier"))
-	}
-
-
-
-	return localctx
-}
-
-
-// ISSContext is an interface to support dynamic dispatch.
-type ISSContext interface {
-	antlr.ParserRuleContext
-
-	// GetParser returns the parser.
-	GetParser() antlr.Parser
-
-	// IsSSContext differentiates from other interfaces.
-	IsSSContext()
-}
-
-type SSContext struct {
-	*antlr.BaseParserRuleContext
-	parser antlr.Parser
-}
-
-func NewEmptySSContext() *SSContext {
-	var p = new(SSContext)
-	p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1)
-	p.RuleIndex = UrnParserRULE_sS
-	return p
-}
-
-func (*SSContext) IsSSContext() {}
-
-func NewSSContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SSContext {
-	var p = new(SSContext)
-
-	p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState)
-
-	p.parser = parser
-	p.RuleIndex = UrnParserRULE_sS
-
-	return p
-}
-
-func (s *SSContext) GetParser() antlr.Parser { return s.parser }
-
-func (s *SSContext) Part() antlr.TerminalNode {
-	return s.GetToken(UrnParserPart, 0)
-}
-
-func (s *SSContext) SS() ISSContext {
-	var t = s.GetTypedRuleContext(reflect.TypeOf((*ISSContext)(nil)).Elem(), 0)
-
-	if t == nil {
-		return nil
-	}
-
-	return t.(ISSContext)
-}
-
-func (s *SSContext) AllColon() []antlr.TerminalNode {
-	return s.GetTokens(UrnParserColon)
-}
-
-func (s *SSContext) Colon(i int) antlr.TerminalNode {
-	return s.GetToken(UrnParserColon, i)
-}
-
-func (s *SSContext) AllHyphen() []antlr.TerminalNode {
-	return s.GetTokens(UrnParserHyphen)
-}
-
-func (s *SSContext) Hyphen(i int) antlr.TerminalNode {
-	return s.GetToken(UrnParserHyphen, i)
-}
-
-func (s *SSContext) Urn() antlr.TerminalNode {
-	return s.GetToken(UrnParserUrn, 0)
-}
-
-func (s *SSContext) GetRuleContext() antlr.RuleContext {
-	return s
-}
-
-func (s *SSContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
-	return antlr.TreesStringTree(s, ruleNames, recog)
-}
-
-
-func (s *SSContext) EnterRule(listener antlr.ParseTreeListener) {
-	if listenerT, ok := listener.(UrnListener); ok {
-		listenerT.EnterSS(s)
-	}
-}
-
-func (s *SSContext) ExitRule(listener antlr.ParseTreeListener) {
-	if listenerT, ok := listener.(UrnListener); ok {
-		listenerT.ExitSS(s)
-	}
-}
-
-
-
-
-func (p *UrnParser) SS() (localctx ISSContext) {
-	localctx = NewSSContext(p, p.GetParserRuleContext(), p.GetState())
-	p.EnterRule(localctx, 4, UrnParserRULE_sS)
-	var _la int
-
-
-	defer func() {
-		p.ExitRule()
-	}()
-
-	defer func() {
-		if err := recover(); err != nil {
-			if v, ok := err.(antlr.RecognitionException); ok {
-				localctx.SetException(v)
-				p.GetErrorHandler().ReportError(p, v)
-				p.GetErrorHandler().Recover(p, v)
-			} else {
-				panic(err)
-			}
-		}
-	}()
-
-	var _alt int
-
-	p.SetState(40)
-	p.GetErrorHandler().Sync(p)
-	switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 5, p.GetParserRuleContext()) {
-	case 1:
-		p.EnterOuterAlt(localctx, 1)
-		{
-			p.SetState(17)
-			p.Match(UrnParserPart)
-		}
-		p.SetState(21)
-		p.GetErrorHandler().Sync(p)
-		_alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext())
-
-		for _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
-			if _alt == 1 {
-				p.SetState(18)
-				_la = p.GetTokenStream().LA(1)
-
-				if !(_la == UrnParserColon || _la == UrnParserHyphen) {
-					p.GetErrorHandler().RecoverInline(p)
-				} else {
-				    p.GetErrorHandler().ReportMatch(p)
-					p.Consume()
-				}
-
-
-			}
-			p.SetState(23)
-			p.GetErrorHandler().Sync(p)
-			_alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext())
-		}
-		p.SetState(25)
-		p.GetErrorHandler().Sync(p)
-		_la = p.GetTokenStream().LA(1)
-
-
-		if (((_la) & -(0x1f+1)) == 0 && ((1 << uint(_la)) & ((1 << UrnParserUrn) | (1 << UrnParserPart) | (1 << UrnParserColon) | (1 << UrnParserHyphen))) != 0) {
-			{
-				p.SetState(24)
-				p.SS()
-			}
-
-		}
-
-
-	case 2:
-		p.EnterOuterAlt(localctx, 2)
-		p.SetState(28)
-		p.GetErrorHandler().Sync(p)
-		_alt = 1
-		for ok := true; ok; ok = _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
-			switch _alt {
-			case 1:
-					p.SetState(27)
-					_la = p.GetTokenStream().LA(1)
-
-					if !(_la == UrnParserColon || _la == UrnParserHyphen) {
-						p.GetErrorHandler().RecoverInline(p)
-					} else {
-					    p.GetErrorHandler().ReportMatch(p)
-						p.Consume()
-					}
-
-
-
-
-			default:
-				panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
-			}
-
-			p.SetState(30)
-			p.GetErrorHandler().Sync(p)
-			_alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 2, p.GetParserRuleContext())
-		}
-		p.SetState(33)
-		p.GetErrorHandler().Sync(p)
-		_la = p.GetTokenStream().LA(1)
-
-
-		if (((_la) & -(0x1f+1)) == 0 && ((1 << uint(_la)) & ((1 << UrnParserUrn) | (1 << UrnParserPart) | (1 << UrnParserColon) | (1 << UrnParserHyphen))) != 0) {
-			{
-				p.SetState(32)
-				p.SS()
-			}
-
-		}
-
-
-	case 3:
-		p.EnterOuterAlt(localctx, 3)
-		{
-			p.SetState(35)
-			p.Match(UrnParserPart)
-		}
-		p.SetState(37)
-		p.GetErrorHandler().Sync(p)
-		_la = p.GetTokenStream().LA(1)
-
-
-		if (((_la) & -(0x1f+1)) == 0 && ((1 << uint(_la)) & ((1 << UrnParserUrn) | (1 << UrnParserPart) | (1 << UrnParserColon) | (1 << UrnParserHyphen))) != 0) {
-			{
-				p.SetState(36)
-				p.SS()
-			}
-
-		}
-
-
-	case 4:
-		p.EnterOuterAlt(localctx, 4)
-		{
-			p.SetState(39)
-			p.Match(UrnParserUrn)
-		}
-
-	}
-
-
-	return localctx
-}
-
-
-func (p *UrnParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool {
-	switch ruleIndex {
-	case 1:
-			var t *IDContext = nil
-			if localctx != nil { t = localctx.(*IDContext) }
-			return p.ID_Sempred(t, predIndex)
-
-
-	default:
-		panic("No predicate with index: " + fmt.Sprint(ruleIndex))
-	}
-}
-
-func (p *UrnParser) ID_Sempred(localctx antlr.RuleContext, predIndex int) bool {
-	switch predIndex {
-	case 0:
-			return len(localctx.(*IDContext).GetText()) <= 32
-
-	case 1:
-			return isIdentifier(localctx.(*IDContext).GetText())
-
-	default:
-		panic("No predicate with index: " + fmt.Sprint(predIndex))
-	}
-}
-

+ 0 - 33
listener.go

@@ -1,33 +0,0 @@
-package urn
-
-import (
-	"github.com/leodido/go-urn/grammar"
-)
-
-// Listener is ...
-type Listener struct {
-	*grammar.BaseUrnListener
-	target *URN
-}
-
-// NewListener is ...
-func NewListener(u *URN) *Listener {
-	return &Listener{
-		target: u,
-	}
-}
-
-// ExitID is called when rule iD is exited
-func (l *Listener) ExitID(ctx *grammar.IDContext) {
-	l.target.ID = ctx.GetText()
-}
-
-// ExitSS is called when rule sS is exited
-func (l *Listener) ExitSS(ctx *grammar.SSContext) {
-	l.target.SS = ctx.GetText()
-}
-
-// ExitUrn is called when rule urn is exited
-func (l *Listener) ExitUrn(ctx *grammar.UrnContext) {
-	l.target.tree = ctx.ToStringTree(nil, ctx.GetParser())
-}

+ 0 - 41
listener_test.go

@@ -1,41 +0,0 @@
-package urn
-
-import (
-	"fmt"
-	"testing"
-
-	"github.com/antlr/antlr4/runtime/Go/antlr"
-	"github.com/leodido/go-urn/grammar"
-)
-
-func TestListener(t *testing.T) {
-
-	inputs := []string{
-	//"URN:1ab:xxx",
-	}
-
-	fmt.Println("---")
-	for _, input := range inputs {
-		stream := antlr.NewInputStream(input)
-		lexer := grammar.NewUrnLexer(stream)
-		tokens := antlr.NewCommonTokenStream(lexer, 0)
-
-		parser := grammar.NewUrnParser(tokens)
-		parser.AddErrorListener(antlr.NewDiagnosticErrorListener(true))
-		parser.BuildParseTrees = true
-
-		/*
-			urn := URN{}
-			parser.AddParseListener(NewListener(&urn))
-		*/
-
-		parser.Urn()
-
-		//fmt.Printf("getstruct=> %+v\n", tree.GetStructure())
-		//fmt.Println(tree.ToStringTree(nil, parser))
-
-		// fmt.Printf("%s => %+v\n", input, urn)
-
-		fmt.Println("---")
-	}
-}

+ 0 - 34
makefile

@@ -1,34 +0,0 @@
-SHELL=/bin/bash
-
-.PHONY = clean
-
-directory := grammar
-
-# Get the path of this makefile.
-# Place this before include directives, if any.
-this := $(lastword $(MAKEFILE_LIST))
-
-$(directory)/urn_{parser,lexer,base_listener,listener,base_visitor,visitor}.go: $(directory)/Urn.g4 $(directory)/antlr
-	$(SHELL) -c "./$(directory)/antlr -Dlanguage=Go -o $(directory) -package $(directory) -listener -no-visitor $<"
-
-$(directory)/antlr:
-	@docker pull leodido/antlr
-	@docker create --name antlr leodido/antlr
-	@docker cp antlr:antlr $(directory)
-	@docker rm antlr
-
-test: tcmd = "go test -v"
-ifdef COVERAGE
-test: tcmd = "go test -v -coverprofile=cov.out"
-endif
-test: $(directory)/urn_{parser,lexer,base_listener,listener,base_visitor,visitor}.go *_test.go 
-	$(SHELL) -c $(tcmd)
-
-cov.out: 
-	$(MAKE) -f $(this) test COVERAGE=yes
-
-coverage: cov.out
-	@go tool cover -func=$<
-
-clean:
-	rm -f $(directory)/urn_{parser,lexer,base_listener,listener,base_visitor,visitor}.go $(directory)/Urn{,Lexer}.tokens $(directory)/antlr *.out

+ 58 - 64
urn.go

@@ -1,12 +1,23 @@
 package urn
 
 import (
-	"strconv"
+	"fmt"
+	"strings"
 
-	"github.com/antlr/antlr4/runtime/Go/antlr"
-	"github.com/leodido/go-urn/grammar"
+	pcre "github.com/gijsbers/go-pcre"
 )
 
+var re = `^
+	(?:(?P<pre>[uU][rR][nN]):(?!urn:))
+
+	(?P<nid>[A-Za-z0-9][A-Za-z0-9-]{0,31}):
+
+	(?P<nss>(?:[A-Za-z0-9()+,\-.:=@;$_!*']|[%][A-Fa-f0-9][A-Fa-f0-9])+)
+$`
+
+var pattern = pcre.MustCompile(re, pcre.EXTENDED)
+var hexrepr = pcre.MustCompile("[%][a-f0-9]{2}", pcre.CASELESS)
+
 // URN represents an Uniform Resource Name.
 //
 // The general form represented is:
@@ -15,70 +26,24 @@ import (
 //
 // Details at https://tools.ietf.org/html/rfc2141
 type URN struct {
-	ID   string // Namespace identifier
-	SS   string // Namespace specific string
-	tree string
-}
-
-// Error describes an error and the input that caused it.
-type Error struct {
-	Source string
-	Column int
-	Detail string
+	ID string // Namespace identifier
+	SS string // Namespace specific string
 }
 
-func (e *Error) Error() string {
-	return "\"" + e.Source + "\" causes syntax error at character " + strconv.Itoa(e.Column) + ", " + e.Detail
-}
-
-type errorListener struct {
-	*antlr.DefaultErrorListener
-	input string
-}
+// Parse is ...
+func Parse(u string) (*URN, bool) {
+	matcher := pattern.MatcherString(u, 0)
+	matches := matcher.Matches()
 
-func (l *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
-	panic(&Error{
-		Source: l.input,
-		Column: column,
-		Detail: msg,
-	})
-}
+	if matches {
+		urn := &URN{}
+		urn.ID, _ = matcher.NamedString("nid")
+		urn.SS, _ = matcher.NamedString("nss")
 
-// Parse is ...
-func Parse(u string) (*URN, error) {
-	urn, err := parse(u)
-	if err != nil {
-		return nil, err
+		return urn, matches
 	}
 
-	return urn, err
-}
-
-func parse(u string) (urn *URN, err error) {
-	errl := new(errorListener)
-	errl.DefaultErrorListener = new(antlr.DefaultErrorListener)
-	errl.input = u
-
-	stream := antlr.NewInputStream(u)
-	lexer := grammar.NewUrnLexer(stream)
-	tokens := antlr.NewCommonTokenStream(lexer, 0)
-	parser := grammar.NewUrnParser(tokens)
-	parser.RemoveErrorListeners()
-	parser.AddErrorListener(errl)
-	// parser.BuildParseTrees = false // (todo) > ?
-
-	defer func() {
-		if r := recover(); r != nil {
-			urn = nil
-			err = r.(error)
-		}
-	}()
-
-	urn = &URN{}
-	parser.AddParseListener(NewListener(urn))
-	parser.Urn()
-
-	return
+	return nil, matches
 }
 
 // String reassembles the URN into a valid URN string.
@@ -94,7 +59,36 @@ func (u *URN) String() string {
 	return res
 }
 
-// Tree returns a string representation of the resulting concrete syntax tree.
-func (u *URN) Tree() string {
-	return u.tree
+// Normalize is ...
+func (u *URN) Normalize() *URN {
+	matcher := hexrepr.MatcherString(u.SS, 0)
+	results := matcher.ExtractString()
+
+	fmt.Println("results> ", results)
+	// find all hex within u.SS
+	// lowercase any match
+	// lowercase u.ID
+	// reconstruct string
+
+	return &URN{
+		ID: strings.ToLower(u.ID),
+		// SS: ...
+	}
+}
+
+/*
+func matchAll(re pcre.Regexp, subject []byte, flags int) [][]byte {
+	m := re.Matcher(subject, 0)
+	all := [][]byte{}
+	for m.Match(subject, flags) {
+		all = append(all, subject[m.ovector[0]:m.ovector[1]])
+		subject = subject[m.ovector[1]:]
+	}
+	return all
+}
+*/
+
+// Equal is ...
+func (u *URN) Equal(x *URN) bool {
+	return *u.Normalize() == *x.Normalize()
 }

+ 2 - 6
urn_test.go

@@ -8,19 +8,15 @@ import (
 
 func TestUrnParse(t *testing.T) {
 	for ii, tt := range tests {
-		urn, err := Parse(tt.in)
+		urn, ok := Parse(tt.in)
 
-		if ok := err == nil; ok {
+		if ok {
 			require.True(t, tt.ok, herror(ii, tt))
 			require.Equal(t, tt.obj.ID, urn.ID, herror(ii, tt))
 			require.Equal(t, tt.obj.SS, urn.SS, herror(ii, tt))
-			// require.Equal(t, tt.tree, urn.Tree(), herror(ii, tt)) // (fixme) > flatten tree?
-			// Ignoring column testing since there is no error
 		} else {
 			require.False(t, tt.ok, herror(ii, tt))
-			require.Equal(t, tt.col, err.(*Error).Column, herror(ii, tt))
 			require.Empty(t, urn, herror(ii, tt))
-			// require.Empty(t, urn.Tree(), herror(ii, tt))
 		}
 	}
 }