Monaco Editor - 使用递归状态匹配同一行上的任意数量的参数?
Monaco Editor - match an arbitrary number of arguments on the same row using a recursive state?
我需要以下方面的帮助:我们正在实施 Monaco Editor (https://github.com/Microsoft/monaco-editor) in a web GUI as an editor for text files in a RobotFramework-like (http://robotframework.org) space-separated 语法。每个 keyword/argument 使用两个或多个连续的 space 分隔。一个 keyword/argument 也可能包含一个或多个 space,如果它们不是连续的。
使用 Monarch 分词器,我们成功地编写了匹配行的正则表达式,我们知道将使用多少参数,但是,我们的一些关键字提供了提供任意数量参数的可能性:
keyword arg1 arg2 ... argN
^^spaces^^ ^^spaces^^ ^^spaces^^ ^^spaces^^ ^^spaces^^
我们想给每个参数一个 class 称为 'argument',space 一个 class 称为 'separator'。我们已经有了一条规则,匹配关键字和后面的 spaces,将 arg1..argN 字符串发送到状态 'arguments':
arguments: [
{
regex: /(\S.*?)(\s{2,})/,
action: { cases: {
'': [
{ token: 'argument', log: 'Matches: `[=11=]`, ``, ``' },
{ token: 'separator', next: '@arguments' },
],
'': [
{ token: 'argument' },
],
'@default': { token: 'eos', next: '@pop' }
}
},
}
],
我们认为我们可以让状态调用自身来匹配任意数量的 arg-spaces 组合。但是,标记化的控制台输出表明状态不会调用自身而是跳到下一行。
有谁知道我们做错了什么?我们的用例有更好的解决方案吗?
谢谢!
编辑:找到一个相当复杂的解决方案;它取决于两个交替状态,具有一些相当复杂的正则表达式匹配和编辑器的 "switchTo" 和 "cases" 功能的使用:
/* Arguments iterators: argument -> argseparator -> argument -> ... (end of line) */
argument: [
{
regex: /(\S.*?)(?=\s{2,}|$)/,
action: { cases: {
'@eos': { token: 'argument', next: '@pop' },
'': { token: 'argument', switchTo: '@argseparator' }
} },
}
],
argseparator: [
{
regex: /(\s{2,}?)(?=\S.*|$)/,
action: { cases: {
'@eos': { token: 'separator', next: '@pop' },
'': { token: 'separator', switchTo: '@argument' }
} },
}
],
我自己解决了。我不得不使用两个交替状态并执行一些相当复杂的正则表达式匹配以及编辑器的 "cases" 和 "swtichTo" 功能来解决我的问题。请参阅上面的编辑。
我需要以下方面的帮助:我们正在实施 Monaco Editor (https://github.com/Microsoft/monaco-editor) in a web GUI as an editor for text files in a RobotFramework-like (http://robotframework.org) space-separated 语法。每个 keyword/argument 使用两个或多个连续的 space 分隔。一个 keyword/argument 也可能包含一个或多个 space,如果它们不是连续的。
使用 Monarch 分词器,我们成功地编写了匹配行的正则表达式,我们知道将使用多少参数,但是,我们的一些关键字提供了提供任意数量参数的可能性:
keyword arg1 arg2 ... argN
^^spaces^^ ^^spaces^^ ^^spaces^^ ^^spaces^^ ^^spaces^^
我们想给每个参数一个 class 称为 'argument',space 一个 class 称为 'separator'。我们已经有了一条规则,匹配关键字和后面的 spaces,将 arg1..argN 字符串发送到状态 'arguments':
arguments: [
{
regex: /(\S.*?)(\s{2,})/,
action: { cases: {
'': [
{ token: 'argument', log: 'Matches: `[=11=]`, ``, ``' },
{ token: 'separator', next: '@arguments' },
],
'': [
{ token: 'argument' },
],
'@default': { token: 'eos', next: '@pop' }
}
},
}
],
我们认为我们可以让状态调用自身来匹配任意数量的 arg-spaces 组合。但是,标记化的控制台输出表明状态不会调用自身而是跳到下一行。
有谁知道我们做错了什么?我们的用例有更好的解决方案吗?
谢谢!
编辑:找到一个相当复杂的解决方案;它取决于两个交替状态,具有一些相当复杂的正则表达式匹配和编辑器的 "switchTo" 和 "cases" 功能的使用:
/* Arguments iterators: argument -> argseparator -> argument -> ... (end of line) */
argument: [
{
regex: /(\S.*?)(?=\s{2,}|$)/,
action: { cases: {
'@eos': { token: 'argument', next: '@pop' },
'': { token: 'argument', switchTo: '@argseparator' }
} },
}
],
argseparator: [
{
regex: /(\s{2,}?)(?=\S.*|$)/,
action: { cases: {
'@eos': { token: 'separator', next: '@pop' },
'': { token: 'separator', switchTo: '@argument' }
} },
}
],
我自己解决了。我不得不使用两个交替状态并执行一些相当复杂的正则表达式匹配以及编辑器的 "cases" 和 "swtichTo" 功能来解决我的问题。请参阅上面的编辑。