diff -r 02229133df43 -r 51a3d6f39944 svghmi/parse_labels.ysl2 --- a/svghmi/parse_labels.ysl2 Tue Sep 13 16:51:54 2022 +0200 +++ b/svghmi/parse_labels.ysl2 Tue Sep 13 16:53:15 2022 +0200 @@ -2,7 +2,7 @@ // Parses: -// "HMI:WidgetType|freq:param1:param2@path1,path1min,path1max@path2" +// "HMI:WidgetType|freq:param1:param2@a=path1,path1min,path1max@b=path2#a+b>3" // // Into: // widget type="WidgetType" id="blah456" { @@ -13,39 +13,39 @@ // path value="path4" index="path4" type="HMI_LOCAL"; // } // -const "pathregex",!"'^([^\[,]+)(\[[^\]]+\])?([-.\d,]*)$'"!; +const "pathregex",!"'^(\w+=)?([^,=]+)([-.\d,]*)$'"!; const "newline" | const "twonewlines", "concat($newline,$newline)"; template "*", mode="parselabel" { - const "part","@inkscape:label"; + const "label","@inkscape:label"; const "desc", "svg:desc"; // add svg:desc field if continuation "\" marker is found at the end of label - const "len","string-length($part)"; - const "has_continuation", "substring($part,$len,1)='\\'"; - const "label" choose{ + const "len","string-length($label)"; + const "has_continuation", "substring($label,$len,1)='\\'"; + const "full_decl" choose{ when "$has_continuation" { const "_continuation", "substring-before($desc, $twonewlines)"; const "continuation" choose { when "$_continuation" value "$_continuation"; otherwise value "$desc"; } - value "concat(substring($part,1,$len - 1),translate($continuation,$newline,''))"; + value "concat(substring($label,1,$len - 1),translate($continuation,$newline,''))"; } - otherwise value "$part"; + otherwise value "$label"; } const "id","@id"; - const "description", "substring-after($label,'HMI:')"; + const "declaration", "substring-after($full_decl,'HMI:')"; - const "_args", "substring-before($description,'@')"; + const "_args", "substring-before($declaration,'@')"; const "args" choose { when "$_args" value "$_args"; - otherwise value "$description"; + otherwise value "$declaration"; } const "_typefreq", "substring-before($args,':')"; @@ -66,37 +66,59 @@ attrib "type" > «$type» if "$freq" { if "not(regexp:test($freq,'^[0-9]*(\.[0-9]+)?[smh]?'))" { - error > Widget id:«$id» label:«$label» has wrong syntax of frequency forcing «$freq» + error > Widget id:«$id» label:«$full_decl» has wrong syntax of frequency forcing «$freq» } attrib "freq" > «$freq» } + + // find "#" + JS expr at the end + const "tail", "substring-after($declaration,'@')"; + const "taillen","string-length($tail)"; + const "has_enable", "contains($tail, '#')"; + const "paths" choose{ + when "$has_enable" { + value "substring-before($tail,'#')"; + } + otherwise value "$tail"; + } + if "$has_enable" { + const "enable_expr", "substring-after($tail,'#')"; + attrib "enable_expr" value "$enable_expr"; + } + foreach "str:split(substring-after($args, ':'), ':')" { arg { attrib "value" > «.» } } - const "paths", "substring-after($description,'@')"; + + // for stricter syntax checking, this should make error + // if $paths contains "@@" or ends with "@" (empty paths) + foreach "str:split($paths, '@')" { if "string-length(.) > 0" path { // 1 : global match + // 2 : assign= // 2 : /path - // 3 : [accepts] - // 4 : min,max + // 3 : min,max const "path_match", "regexp:match(.,$pathregex)"; + const "pathassign", "substring-before($path_match[2],'=')"; const "pathminmax", "str:split($path_match[4],',')"; - const "path", "$path_match[2]"; - const "path_accepts", "$path_match[3]"; + const "path", "$path_match[3]"; const "pathminmaxcount", "count($pathminmax)"; - attrib "value" > «$path» - if "string-length($path_accepts)" - attrib "accepts" > «$path_accepts» + if "not($path)" + error > Widget id:«$id» label:«$full_decl» has wrong syntax + + attrib "value" value "$path"; + if "$pathassign" + attrib "assign" value "$pathassign"; choose { when "$pathminmaxcount = 2" { attrib "min" > «$pathminmax[1]» attrib "max" > «$pathminmax[2]» } when "$pathminmaxcount = 1 or $pathminmaxcount > 2" { - error > Widget id:«$id» label:«$label» has wrong syntax of path section «$pathminmax» + error > Widget id:«$id» label:«$full_decl» has wrong syntax of path section «$pathminmax» } } if "$indexed_hmitree" choose { @@ -110,7 +132,7 @@ const "item", "$indexed_hmitree/*[@hmipath = $path]"; const "pathtype", "local-name($item)"; if "$pathminmaxcount = 3 and not($pathtype = 'HMI_INT' or $pathtype = 'HMI_REAL')" { - error > Widget id:«$id» label:«$label» path section «$pathminmax» use min and max on non mumeric value + error > Widget id:«$id» label:«$full_decl» path section «$pathminmax» use min and max on non mumeric value } if "count($item) = 1" { attrib "index" > «$item/@index»