Simplify parser
Change-Id: I5ae560d7c984cf9899b908adc2dd645714114202
diff --git a/parser/grammar_parser.go b/parser/grammar_parser.go
index 24cb15e..4862cea 100644
--- a/parser/grammar_parser.go
+++ b/parser/grammar_parser.go
@@ -141,75 +141,18 @@
}, nil
}
-// Parse parses a grammar string into an AST node (for backward compatibility)
-func (p *GrammarParser) Parse(input string) (ast.Node, error) {
- // Remove extra spaces around operators to help the parser
- input = strings.ReplaceAll(input, " & ", "&")
- input = strings.ReplaceAll(input, " | ", "|")
-
- // Add spaces around parentheses that are not escaped
- // We need to be careful not to break escape sequences like \(
- result := make([]rune, 0, len(input)*2)
- runes := []rune(input)
- for i, r := range runes {
- if (r == '(' || r == ')') && (i == 0 || runes[i-1] != '\\') {
- // Only add spaces if the parenthesis is not escaped and not part of an identifier
- // Check if this parenthesis is inside brackets (part of an identifier)
- insideBrackets := false
- bracketDepth := 0
- for j := 0; j < i; j++ {
- if runes[j] == '[' {
- bracketDepth++
- } else if runes[j] == ']' {
- bracketDepth--
- }
- }
- insideBrackets = bracketDepth > 0
-
- if !insideBrackets {
- result = append(result, ' ', r, ' ')
- } else {
- result = append(result, r)
- }
- } else {
- result = append(result, r)
- }
- }
- input = string(result)
-
- // Remove any extra spaces
- input = strings.TrimSpace(input)
-
- grammar, err := p.tokenParser.ParseString("", input)
- if err != nil {
- return nil, fmt.Errorf("failed to parse grammar: %w", err)
- }
-
- if grammar.Token == nil {
- return nil, fmt.Errorf("expected token expression, got mapping rule")
- }
-
- wrap, err := p.parseExpr(grammar.Token.Expr)
- if err != nil {
- return nil, err
- }
- return &ast.Token{Wrap: wrap}, nil
-}
-
-// ParseMapping parses a mapping rule string into a MappingResult
-func (p *GrammarParser) ParseMapping(input string) (*MappingResult, error) {
+// preprocessInput normalizes the input string by handling operators and parentheses
+func (p *GrammarParser) preprocessInput(input string) string {
// Remove extra spaces around operators to help the parser
input = strings.ReplaceAll(input, " & ", "&")
input = strings.ReplaceAll(input, " | ", "|")
input = strings.ReplaceAll(input, " <> ", "<>")
// Add spaces around parentheses that are not escaped
- // We need to be careful not to break escape sequences like \(
result := make([]rune, 0, len(input)*2)
runes := []rune(input)
for i, r := range runes {
if (r == '(' || r == ')') && (i == 0 || runes[i-1] != '\\') {
- // Only add spaces if the parenthesis is not escaped and not part of an identifier
// Check if this parenthesis is inside brackets (part of an identifier)
insideBrackets := false
bracketDepth := 0
@@ -231,10 +174,12 @@
result = append(result, r)
}
}
- input = string(result)
+ return strings.TrimSpace(string(result))
+}
- // Remove any extra spaces
- input = strings.TrimSpace(input)
+// ParseMapping parses a mapping rule string into a MappingResult
+func (p *GrammarParser) ParseMapping(input string) (*MappingResult, error) {
+ input = p.preprocessInput(input)
grammar, err := p.mappingParser.ParseString("", input)
if err != nil {
diff --git a/parser/grammar_parser_test.go b/parser/grammar_parser_test.go
index 5c0cc56..07f61e9 100644
--- a/parser/grammar_parser_test.go
+++ b/parser/grammar_parser_test.go
@@ -126,151 +126,8 @@
}
}
-func TestGrammarParser(t *testing.T) {
- tests := []struct {
- name string
- input string
- defaultFoundry string
- defaultLayer string
- expected ast.Node
- expectError bool
- }{
- {
- name: "Simple term with foundry and layer",
- input: "[opennlp/p=PIDAT]",
- defaultFoundry: "opennlp",
- defaultLayer: "p",
- expected: &ast.Token{
- Wrap: &ast.Term{
- Foundry: "opennlp",
- Key: "PIDAT",
- Layer: "p",
- Match: ast.MatchEqual,
- },
- },
- },
- {
- name: "Term group with and relation",
- input: "[opennlp/p=PIDAT & opennlp/p=AdjType:Pdt]",
- defaultFoundry: "opennlp",
- defaultLayer: "p",
- expected: &ast.Token{
- Wrap: &ast.TermGroup{
- Operands: []ast.Node{
- &ast.Term{
- Foundry: "opennlp",
- Key: "PIDAT",
- Layer: "p",
- Match: ast.MatchEqual,
- },
- &ast.Term{
- Foundry: "opennlp",
- Key: "AdjType",
- Layer: "p",
- Match: ast.MatchEqual,
- Value: "Pdt",
- },
- },
- Relation: ast.AndRelation,
- },
- },
- },
- {
- name: "Term group with or relation",
- input: "[opennlp/p=PronType:Ind | opennlp/p=PronType:Neg]",
- defaultFoundry: "opennlp",
- defaultLayer: "p",
- expected: &ast.Token{
- Wrap: &ast.TermGroup{
- Operands: []ast.Node{
- &ast.Term{
- Foundry: "opennlp",
- Key: "PronType",
- Layer: "p",
- Match: ast.MatchEqual,
- Value: "Ind",
- },
- &ast.Term{
- Foundry: "opennlp",
- Key: "PronType",
- Layer: "p",
- Match: ast.MatchEqual,
- Value: "Neg",
- },
- },
- Relation: ast.OrRelation,
- },
- },
- },
- {
- name: "Complex term group",
- input: "[opennlp/p=PIDAT & (opennlp/p=PronType:Ind | opennlp/p=PronType:Neg)]",
- defaultFoundry: "opennlp",
- defaultLayer: "p",
- expected: &ast.Token{
- Wrap: &ast.TermGroup{
- Operands: []ast.Node{
- &ast.Term{
- Foundry: "opennlp",
- Key: "PIDAT",
- Layer: "p",
- Match: ast.MatchEqual,
- },
- &ast.TermGroup{
- Operands: []ast.Node{
- &ast.Term{
- Foundry: "opennlp",
- Key: "PronType",
- Layer: "p",
- Match: ast.MatchEqual,
- Value: "Ind",
- },
- &ast.Term{
- Foundry: "opennlp",
- Key: "PronType",
- Layer: "p",
- Match: ast.MatchEqual,
- Value: "Neg",
- },
- },
- Relation: ast.OrRelation,
- },
- },
- Relation: ast.AndRelation,
- },
- },
- },
- {
- name: "Wildcard pattern",
- input: "[opennlp/*=PIDAT]",
- defaultFoundry: "opennlp",
- defaultLayer: "p",
- expected: &ast.Token{
- Wrap: &ast.Term{
- Foundry: "opennlp",
- Key: "PIDAT",
- Layer: "p",
- Match: ast.MatchEqual,
- },
- },
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- parser, err := NewGrammarParser(tt.defaultFoundry, tt.defaultLayer)
- require.NoError(t, err)
-
- result, err := parser.Parse(tt.input)
- if tt.expectError {
- assert.Error(t, err)
- return
- }
- require.NoError(t, err)
- assert.Equal(t, tt.expected, result)
- })
- }
-}
+// TestGrammarParser was removed as the Parse method is no longer supported
+// The functionality is now only available through ParseMapping method
func TestMappingRules(t *testing.T) {
tests := []struct {
@@ -367,6 +224,156 @@
},
},
},
+ // Additional tests to cover functionality from removed TestGrammarParser
+ {
+ name: "Simple term with foundry and layer",
+ input: "[opennlp/p=PIDAT] <> [PIDAT]",
+ expected: &MappingResult{
+ Upper: &ast.Token{
+ Wrap: &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "PIDAT",
+ Match: ast.MatchEqual,
+ },
+ },
+ Lower: &ast.Token{
+ Wrap: &ast.Term{
+ Key: "PIDAT",
+ Match: ast.MatchEqual,
+ },
+ },
+ },
+ },
+ {
+ name: "Term group with and relation",
+ input: "[opennlp/p=PIDAT & opennlp/p=AdjType:Pdt] <> [PIDAT]",
+ expected: &MappingResult{
+ Upper: &ast.Token{
+ Wrap: &ast.TermGroup{
+ Operands: []ast.Node{
+ &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "PIDAT",
+ Match: ast.MatchEqual,
+ },
+ &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "AdjType",
+ Value: "Pdt",
+ Match: ast.MatchEqual,
+ },
+ },
+ Relation: ast.AndRelation,
+ },
+ },
+ Lower: &ast.Token{
+ Wrap: &ast.Term{
+ Key: "PIDAT",
+ Match: ast.MatchEqual,
+ },
+ },
+ },
+ },
+ {
+ name: "Term group with or relation",
+ input: "[opennlp/p=PronType:Ind | opennlp/p=PronType:Neg] <> [PRON]",
+ expected: &MappingResult{
+ Upper: &ast.Token{
+ Wrap: &ast.TermGroup{
+ Operands: []ast.Node{
+ &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "PronType",
+ Value: "Ind",
+ Match: ast.MatchEqual,
+ },
+ &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "PronType",
+ Value: "Neg",
+ Match: ast.MatchEqual,
+ },
+ },
+ Relation: ast.OrRelation,
+ },
+ },
+ Lower: &ast.Token{
+ Wrap: &ast.Term{
+ Key: "PRON",
+ Match: ast.MatchEqual,
+ },
+ },
+ },
+ },
+ {
+ name: "Complex term group with nested parentheses",
+ input: "[opennlp/p=PIDAT & (opennlp/p=PronType:Ind | opennlp/p=PronType:Neg)] <> [COMPLEX]",
+ expected: &MappingResult{
+ Upper: &ast.Token{
+ Wrap: &ast.TermGroup{
+ Operands: []ast.Node{
+ &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "PIDAT",
+ Match: ast.MatchEqual,
+ },
+ &ast.TermGroup{
+ Operands: []ast.Node{
+ &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "PronType",
+ Value: "Ind",
+ Match: ast.MatchEqual,
+ },
+ &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "PronType",
+ Value: "Neg",
+ Match: ast.MatchEqual,
+ },
+ },
+ Relation: ast.OrRelation,
+ },
+ },
+ Relation: ast.AndRelation,
+ },
+ },
+ Lower: &ast.Token{
+ Wrap: &ast.Term{
+ Key: "COMPLEX",
+ Match: ast.MatchEqual,
+ },
+ },
+ },
+ },
+ {
+ name: "Wildcard pattern",
+ input: "[opennlp/*=PIDAT] <> [PIDAT]",
+ expected: &MappingResult{
+ Upper: &ast.Token{
+ Wrap: &ast.Term{
+ Foundry: "opennlp",
+ Layer: "",
+ Key: "PIDAT",
+ Match: ast.MatchEqual,
+ },
+ },
+ Lower: &ast.Token{
+ Wrap: &ast.Term{
+ Key: "PIDAT",
+ Match: ast.MatchEqual,
+ },
+ },
+ },
+ },
{
name: "Invalid mapping syntax",
input: "[PAV] -> [ADV]",
diff --git a/parser/parser.go b/parser/parser.go
index 0dc2b03..e122edc 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -242,42 +242,22 @@
return nil, fmt.Errorf("failed to parse 'wrap' field in unknown node type '%s': %w", raw.Type, err)
}
- // Check if the wrapped node is a known type
- if wrapRaw.Type == "koral:term" || wrapRaw.Type == "koral:token" || wrapRaw.Type == "koral:termGroup" {
- wrap, err := parseNode(wrapRaw)
- if err != nil {
- return nil, fmt.Errorf("error parsing wrapped node in unknown node type '%s': %w", raw.Type, err)
- }
- catchall.Wrap = wrap
- } else {
- // For unknown types, recursively parse
- wrap, err := parseNode(wrapRaw)
- if err != nil {
- return nil, fmt.Errorf("error parsing wrapped node in unknown node type '%s': %w", raw.Type, err)
- }
- catchall.Wrap = wrap
+ wrap, err := parseNode(wrapRaw)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing wrapped node in unknown node type '%s': %w", raw.Type, err)
}
+ catchall.Wrap = wrap
}
// Parse operands if present
if len(raw.Operands) > 0 {
operands := make([]ast.Node, len(raw.Operands))
for i, op := range raw.Operands {
- // Check if the operand is a known type
- if op.Type == "koral:term" || op.Type == "koral:token" || op.Type == "koral:termGroup" {
- node, err := parseNode(op)
- if err != nil {
- return nil, fmt.Errorf("error parsing operand %d in unknown node type '%s': %w", i+1, raw.Type, err)
- }
- operands[i] = node
- } else {
- // For unknown types, recursively parse
- node, err := parseNode(op)
- if err != nil {
- return nil, fmt.Errorf("error parsing operand %d in unknown node type '%s': %w", i+1, raw.Type, err)
- }
- operands[i] = node
+ node, err := parseNode(op)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing operand %d in unknown node type '%s': %w", i+1, raw.Type, err)
}
+ operands[i] = node
}
catchall.Operands = operands
}
diff --git a/parser/title_parser.go b/parser/title_parser.go
index 839ff5a..87bd809 100644
--- a/parser/title_parser.go
+++ b/parser/title_parser.go
@@ -30,9 +30,9 @@
}
}
-// ParseTitleAttribute parses a single title attribute string
+// parseTitleAttribute parses a single title attribute string
// Expects format: "foundry/layer:key" or "foundry/layer:key[:=]value"
-func (p *TitleAttributeParser) ParseTitleAttribute(title string) (*TitleAttribute, error) {
+func (p *TitleAttributeParser) parseTitleAttribute(title string) (*TitleAttribute, error) {
if title == "" {
return nil, fmt.Errorf("empty title attribute")
}
@@ -63,7 +63,7 @@
terms := make([]ast.Node, 0) // Initialize as empty slice instead of nil
for _, title := range titles {
- attr, err := p.ParseTitleAttribute(title)
+ attr, err := p.parseTitleAttribute(title)
if err != nil {
return nil, fmt.Errorf("failed to parse title '%s': %w", title, err)
}
@@ -81,22 +81,3 @@
return terms, nil
}
-
-// ToAST converts a TitleAttribute to an AST Term node
-func (attr *TitleAttribute) ToAST() ast.Node {
- return &ast.Term{
- Foundry: attr.Foundry,
- Layer: attr.Layer,
- Key: attr.Key,
- Value: attr.Value,
- Match: ast.MatchEqual,
- }
-}
-
-// String returns a string representation of the title attribute
-func (attr *TitleAttribute) String() string {
- if attr.Value != "" {
- return fmt.Sprintf("%s/%s:%s=%s", attr.Foundry, attr.Layer, attr.Key, attr.Value)
- }
- return fmt.Sprintf("%s/%s:%s", attr.Foundry, attr.Layer, attr.Key)
-}
diff --git a/parser/title_parser_test.go b/parser/title_parser_test.go
index 326625f..1a74905 100644
--- a/parser/title_parser_test.go
+++ b/parser/title_parser_test.go
@@ -8,126 +8,8 @@
"github.com/stretchr/testify/require"
)
-func TestTitleAttributeParser_ParseTitleAttribute(t *testing.T) {
- parser := NewTitleAttributeParser()
-
- tests := []struct {
- name string
- input string
- expected *TitleAttribute
- wantErr bool
- }{
- {
- name: "Parse simple title with key only",
- input: "corenlp/p:ART",
- expected: &TitleAttribute{
- Foundry: "corenlp",
- Layer: "p",
- Key: "ART",
- Value: "",
- },
- wantErr: false,
- },
- {
- name: "Parse title with key and value",
- input: "marmot/m:case:nom",
- expected: &TitleAttribute{
- Foundry: "marmot",
- Layer: "m",
- Key: "case",
- Value: "nom",
- },
- wantErr: false,
- },
- {
- name: "Parse title with colon separator for value",
- input: "marmot/m:gender:masc",
- expected: &TitleAttribute{
- Foundry: "marmot",
- Layer: "m",
- Key: "gender",
- Value: "masc",
- },
- wantErr: false,
- },
- {
- name: "Parse title with equals separator for value",
- input: "marmot/m:degree:pos",
- expected: &TitleAttribute{
- Foundry: "marmot",
- Layer: "m",
- Key: "degree",
- Value: "pos",
- },
- wantErr: false,
- },
- {
- name: "Parse title with lemma layer",
- input: "tt/l:die",
- expected: &TitleAttribute{
- Foundry: "tt",
- Layer: "l",
- Key: "die",
- Value: "",
- },
- wantErr: false,
- },
- {
- name: "Parse title with special characters in value",
- input: "tt/l:@card@",
- expected: &TitleAttribute{
- Foundry: "tt",
- Layer: "l",
- Key: "@card@",
- Value: "",
- },
- wantErr: false,
- },
- {
- name: "Empty title should fail",
- input: "",
- wantErr: true,
- },
- {
- name: "Missing foundry separator should fail",
- input: "corenlp_p:ART",
- wantErr: true,
- },
- {
- name: "Missing layer separator should fail",
- input: "corenlp/p_ART",
- wantErr: true,
- },
- {
- name: "Only foundry should fail",
- input: "corenlp",
- wantErr: true,
- },
- {
- name: "Only foundry and layer should fail",
- input: "corenlp/p",
- wantErr: true,
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- result, err := parser.ParseTitleAttribute(tt.input)
-
- if tt.wantErr {
- assert.Error(t, err)
- assert.Nil(t, result)
- } else {
- require.NoError(t, err)
- require.NotNil(t, result)
- assert.Equal(t, tt.expected.Foundry, result.Foundry)
- assert.Equal(t, tt.expected.Layer, result.Layer)
- assert.Equal(t, tt.expected.Key, result.Key)
- assert.Equal(t, tt.expected.Value, result.Value)
- }
- })
- }
-}
+// TestTitleAttributeParser_ParseTitleAttribute was removed as ParseTitleAttribute is no longer exported
+// The functionality is now only available through ParseTitleAttributesToTerms method
func TestTitleAttributeParser_ParseTitleAttributesToTerms(t *testing.T) {
parser := NewTitleAttributeParser()
@@ -177,6 +59,164 @@
input: []string{"corenlp/p:ART", "invalid_title", "tt/l:die"},
wantErr: true,
},
+ // Additional tests to cover functionality from removed TestTitleAttributeParser_ParseTitleAttribute
+ {
+ name: "Parse simple title with key only",
+ input: []string{"corenlp/p:ART"},
+ expected: []ast.Node{
+ &ast.Term{
+ Foundry: "corenlp",
+ Layer: "p",
+ Key: "ART",
+ Value: "",
+ Match: ast.MatchEqual,
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "Parse title with key and value",
+ input: []string{"marmot/m:case:nom"},
+ expected: []ast.Node{
+ &ast.Term{
+ Foundry: "marmot",
+ Layer: "m",
+ Key: "case",
+ Value: "nom",
+ Match: ast.MatchEqual,
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "Parse title with colon separator for value",
+ input: []string{"marmot/m:gender:masc"},
+ expected: []ast.Node{
+ &ast.Term{
+ Foundry: "marmot",
+ Layer: "m",
+ Key: "gender",
+ Value: "masc",
+ Match: ast.MatchEqual,
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "Parse title with equals separator for value",
+ input: []string{"marmot/m:degree:pos"},
+ expected: []ast.Node{
+ &ast.Term{
+ Foundry: "marmot",
+ Layer: "m",
+ Key: "degree",
+ Value: "pos",
+ Match: ast.MatchEqual,
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "Parse title with lemma layer",
+ input: []string{"tt/l:die"},
+ expected: []ast.Node{
+ &ast.Term{
+ Foundry: "tt",
+ Layer: "l",
+ Key: "die",
+ Value: "",
+ Match: ast.MatchEqual,
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "Parse title with special characters in value",
+ input: []string{"tt/l:@card@"},
+ expected: []ast.Node{
+ &ast.Term{
+ Foundry: "tt",
+ Layer: "l",
+ Key: "@card@",
+ Value: "",
+ Match: ast.MatchEqual,
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "Parse complex key-value with colon",
+ input: []string{"opennlp/p:PronType:Ind"},
+ expected: []ast.Node{
+ &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "PronType",
+ Value: "Ind",
+ Match: ast.MatchEqual,
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "Parse complex key-value with equals",
+ input: []string{"opennlp/p:AdjType:Pdt"},
+ expected: []ast.Node{
+ &ast.Term{
+ Foundry: "opennlp",
+ Layer: "p",
+ Key: "AdjType",
+ Value: "Pdt",
+ Match: ast.MatchEqual,
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "Parse complex nested pattern",
+ input: []string{"stts/p:ADJA"},
+ expected: []ast.Node{
+ &ast.Term{
+ Foundry: "stts",
+ Layer: "p",
+ Key: "ADJA",
+ Value: "",
+ Match: ast.MatchEqual,
+ },
+ },
+ wantErr: false,
+ },
+ // Error cases
+ {
+ name: "Empty title should fail",
+ input: []string{""},
+ wantErr: true,
+ },
+ {
+ name: "Missing foundry separator should fail",
+ input: []string{"corenlp_p:ART"},
+ wantErr: true,
+ },
+ {
+ name: "Missing layer separator should fail",
+ input: []string{"corenlp/p_ART"},
+ wantErr: true,
+ },
+ {
+ name: "Only foundry should fail",
+ input: []string{"corenlp"},
+ wantErr: true,
+ },
+ {
+ name: "Only foundry and layer should fail",
+ input: []string{"corenlp/p"},
+ wantErr: true,
+ },
+ {
+ name: "Missing key should fail",
+ input: []string{"corenlp/p:"},
+ wantErr: true,
+ },
}
for _, tt := range tests {
@@ -204,128 +244,6 @@
}
}
-func TestTitleAttribute_ToAST(t *testing.T) {
- tests := []struct {
- name string
- attr *TitleAttribute
- expected *ast.Term
- }{
- {
- name: "Convert title attribute to AST term",
- attr: &TitleAttribute{
- Foundry: "corenlp",
- Layer: "p",
- Key: "ART",
- Value: "",
- },
- expected: &ast.Term{
- Foundry: "corenlp",
- Layer: "p",
- Key: "ART",
- Value: "",
- Match: ast.MatchEqual,
- },
- },
- {
- name: "Convert title attribute with value to AST term",
- attr: &TitleAttribute{
- Foundry: "marmot",
- Layer: "m",
- Key: "case",
- Value: "nom",
- },
- expected: &ast.Term{
- Foundry: "marmot",
- Layer: "m",
- Key: "case",
- Value: "nom",
- Match: ast.MatchEqual,
- },
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- result := tt.attr.ToAST()
-
- termResult := result.(*ast.Term)
- assert.Equal(t, tt.expected.Foundry, termResult.Foundry)
- assert.Equal(t, tt.expected.Layer, termResult.Layer)
- assert.Equal(t, tt.expected.Key, termResult.Key)
- assert.Equal(t, tt.expected.Value, termResult.Value)
- assert.Equal(t, tt.expected.Match, termResult.Match)
- })
- }
-}
-
-func TestTitleAttribute_String(t *testing.T) {
- tests := []struct {
- name string
- attr *TitleAttribute
- expected string
- }{
- {
- name: "String representation without value",
- attr: &TitleAttribute{
- Foundry: "corenlp",
- Layer: "p",
- Key: "ART",
- Value: "",
- },
- expected: "corenlp/p:ART",
- },
- {
- name: "String representation with value",
- attr: &TitleAttribute{
- Foundry: "marmot",
- Layer: "m",
- Key: "case",
- Value: "nom",
- },
- expected: "marmot/m:case=nom",
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- result := tt.attr.String()
- assert.Equal(t, tt.expected, result)
- })
- }
-}
-
-func TestTitleAttributeParser_RealWorldExample(t *testing.T) {
- parser := NewTitleAttributeParser()
-
- // Example titles from the response test file
- titles := []string{
- "corenlp/p:ART",
- "marmot/m:case=nom",
- "marmot/m:gender=masc",
- "marmot/m:number=sg",
- "marmot/p:ART",
- "opennlp/p:ART",
- "tt/l:die",
- "tt/p:ART",
- }
-
- // Parse each title attribute
- for _, title := range titles {
- attr, err := parser.ParseTitleAttribute(title)
- require.NoError(t, err)
- require.NotNil(t, attr)
-
- // Verify the string representation matches
- assert.Equal(t, title, attr.String())
-
- // Verify conversion to AST works
- astNode := attr.ToAST()
- require.NotNil(t, astNode)
-
- term := astNode.(*ast.Term)
- assert.NotEmpty(t, term.Foundry)
- assert.NotEmpty(t, term.Layer)
- assert.NotEmpty(t, term.Key)
- assert.Equal(t, ast.MatchEqual, term.Match)
- }
-}
+// TestTitleAttribute_ToAST was removed as ToAST method is no longer available
+// TestTitleAttribute_String was removed as String method is no longer available
+// TestTitleAttributeParser_RealWorldExample was removed as it used the removed methods