Support escaping inm grammar rules
Change-Id: I87e01605be27f165cfb4eaee69315c312e51f326
diff --git a/parser/grammar_parser.go b/parser/grammar_parser.go
index 8e46611..dadd0a2 100644
--- a/parser/grammar_parser.go
+++ b/parser/grammar_parser.go
@@ -97,7 +97,7 @@
// NewGrammarParser creates a new grammar parser with optional default foundry and layer
func NewGrammarParser(defaultFoundry, defaultLayer string) (*GrammarParser, error) {
lex := lexer.MustSimple([]lexer.SimpleRule{
- {Name: "Ident", Pattern: `[a-zA-Z][a-zA-Z0-9_]*`},
+ {Name: "Ident", Pattern: `(?:[a-zA-Z$]|\\.)(?:[a-zA-Z0-9_$]|\\.)*`},
{Name: "Punct", Pattern: `[\[\]()&\|=:/]|<>`},
{Name: "Whitespace", Pattern: `\s+`},
})
@@ -288,26 +288,48 @@
return ast.AndRelation
}
+// unescapeString handles unescaping of backslash-escaped characters
+func unescapeString(s string) string {
+ if s == "" {
+ return s
+ }
+
+ result := make([]byte, 0, len(s))
+ i := 0
+ for i < len(s) {
+ if s[i] == '\\' && i+1 < len(s) {
+ // Escape sequence found, add the escaped character
+ result = append(result, s[i+1])
+ i += 2
+ } else {
+ // Regular character
+ result = append(result, s[i])
+ i++
+ }
+ }
+ return string(result)
+}
+
// parseSimpleTerm converts a SimpleTerm into an AST Term node
func (p *GrammarParser) parseSimpleTerm(term *SimpleTerm) (ast.Node, error) {
var foundry, layer, key, value string
switch {
case term.WithFoundryLayer != nil:
- foundry = term.WithFoundryLayer.Foundry
- layer = term.WithFoundryLayer.Layer
- key = term.WithFoundryLayer.Key
- value = term.WithFoundryLayer.Value
+ foundry = unescapeString(term.WithFoundryLayer.Foundry)
+ layer = unescapeString(term.WithFoundryLayer.Layer)
+ key = unescapeString(term.WithFoundryLayer.Key)
+ value = unescapeString(term.WithFoundryLayer.Value)
case term.WithFoundryKey != nil:
- foundry = term.WithFoundryKey.Foundry
- key = term.WithFoundryKey.Key
+ foundry = unescapeString(term.WithFoundryKey.Foundry)
+ key = unescapeString(term.WithFoundryKey.Key)
case term.WithLayer != nil:
- layer = term.WithLayer.Layer
- key = term.WithLayer.Key
- value = term.WithLayer.Value
+ layer = unescapeString(term.WithLayer.Layer)
+ key = unescapeString(term.WithLayer.Key)
+ value = unescapeString(term.WithLayer.Value)
case term.SimpleKey != nil:
- key = term.SimpleKey.Key
- value = term.SimpleKey.Value
+ key = unescapeString(term.SimpleKey.Key)
+ value = unescapeString(term.SimpleKey.Value)
default:
return nil, fmt.Errorf("invalid term: no valid form found")
}
diff --git a/parser/grammar_parser_test.go b/parser/grammar_parser_test.go
index f7fefc9..c6f96d1 100644
--- a/parser/grammar_parser_test.go
+++ b/parser/grammar_parser_test.go
@@ -67,6 +67,28 @@
},
},
},
+ {
+ name: "Special symbol",
+ input: "[$\\(]",
+ defaultFoundry: "opennlp",
+ defaultLayer: "p",
+ expected: &SimpleTerm{
+ SimpleKey: &KeyTerm{
+ Key: "$(",
+ },
+ },
+ },
+ {
+ name: "Multiple escaped characters",
+ input: "[\\&\\|\\=]",
+ defaultFoundry: "opennlp",
+ defaultLayer: "p",
+ expected: &SimpleTerm{
+ SimpleKey: &KeyTerm{
+ Key: "&|=",
+ },
+ },
+ },
}
for _, tt := range tests {
@@ -81,6 +103,12 @@
}
require.NoError(t, err)
require.NotNil(t, grammar.Token, "Expected token expression")
+
+ // For testing purposes, unescape the key in the simple term
+ if grammar.Token.Expr.First.Simple.SimpleKey != nil {
+ grammar.Token.Expr.First.Simple.SimpleKey.Key = unescapeString(grammar.Token.Expr.First.Simple.SimpleKey.Key)
+ }
+
assert.Equal(t, tt.expected, grammar.Token.Expr.First.Simple)
})
}
diff --git a/parser/parser_test.go b/parser/parser_test.go
index 25b2ad1..424743d 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -11,7 +11,7 @@
// normalizeJSON normalizes JSON by parsing and re-marshaling it
func normalizeJSON(t *testing.T, data json.RawMessage) json.RawMessage {
- var v interface{}
+ var v any
err := json.Unmarshal(data, &v)
require.NoError(t, err)
@@ -708,7 +708,7 @@
require.NoError(t, err)
// Compare JSON objects
- var expected, actual interface{}
+ var expected, actual any
err = json.Unmarshal([]byte(input), &expected)
require.NoError(t, err)
err = json.Unmarshal(output, &actual)
@@ -758,7 +758,7 @@
require.NoError(t, err)
// Compare JSON objects
- var expected, actual interface{}
+ var expected, actual any
err = json.Unmarshal([]byte(input), &expected)
require.NoError(t, err)
err = json.Unmarshal(output, &actual)