Нет, такой гарантии нет. Он не определен в соответствии со стандартом C ++.
Bjarne Stroustrup также явно говорит об этом в разделе «Язык программирования C ++», раздел 6.2.2, с некоторыми аргументами:
Better код может быть сгенерирован при отсутствии ограничений на порядок оценки выражения
blockquote>Хотя это технически относится к более ранней части того же раздела, где говорится, что порядок оценки частей выражения также undefined, т.е.
int x = f(2) + g(3); // undefined whether f() or g() is called first
В зависимости от того, что вы на самом деле хотите от этих строк, вы можете использовать парсер, например, parsimonious
:
from parsimonious.nodes import NodeVisitor
from parsimonious.grammar import Grammar
grammar = Grammar(
r"""
command = set operand to? number (operator number)* middle? to? numsys? number
operand = (~r"words?" / "speed") ws
middle = (~r"[Ww]ords" / "bits")+ ws number
to = ws "to" ws
number = ws ~r"[-\d.]+" "kts"? ws
numsys = ws ("oct" / "hex") ws
operator = ws "and" ws
set = ~"[Ss]et" ws
ws = ~r"\s*"
"""
)
class HorribleStuff(NodeVisitor):
def __init__(self):
self.cmds = []
def generic_visit(self, node, visited_children):
pass
def visit_operand(self, node, visited_children):
self.cmds.append(('operand', node.text))
def visit_number(self, node, visited_children):
self.cmds.append(('number', node.text))
examples = ['Set word 45 and 46 to hex 331',
'set words 45 and 46 bits 3..7 to 280',
'set word 45 to oct 332',
'set speed to 60kts Words 3-4 to hex 34']
for example in examples:
tree = grammar.parse(example)
hs = HorribleStuff()
hs.visit(tree)
print(hs.cmds)
Это даст
[('operand', 'word '), ('number', '45 '), ('number', '46 '), ('number', '331')]
[('operand', 'words '), ('number', '45 '), ('number', '46 '), ('number', '3..7 '), ('number', '280')]
[('operand', 'word '), ('number', '45 '), ('number', '332')]
[('operand', 'speed '), ('number', '60kts '), ('number', '3-4 '), ('number', '34')]
Я предлагаю вам разработать программу, которая постепенно исследует синтаксис, который люди использовали для написания сценариев.
Например, каждая инструкция в ваших примерах разбита на часть устройства и часть настроек. Так что вы можете попробовать сопоставить каждую строку с регулярным выражением ^(.+) set (.+)
. Если вы найдете линии, которые не соответствуют этому шаблону, распечатайте их. Изучите выходные данные, найдите общий шаблон, соответствующий некоторым из них, добавьте соответствующее регулярное выражение в вашу программу (или измените существующее регулярное выражение) и повторите. Продолжайте до тех пор, пока вы не узнаете (в очень общем виде) каждую строку ввода.
(Поскольку заглавные буквы кажутся непоследовательными, вы можете либо выполнять регистронезависимые совпадения, либо конвертировать каждую строку в строчные, прежде чем начинать ее обрабатывать. В более общем случае вы можете найти другие «нормализации», которые упрощают последующую обработку. Например, если люди были непоследовательны в отношении пробелов, вы можете конвертировать каждый пробел символов пробела в один пробел.)
(Если ваш ввод содержит опечатки, например, кто-то написал «ste» для «set», то вы можете изменить регулярное выражение, чтобы учесть это (... (set|ste) ...
), или перейдите (копия) во входной файл и просто исправьте опечатку.)
Затем вернитесь к строкам, которые соответствовали ^(.+) set (.+)
, распечатайте просто первая группа для каждой, и повторите описанный выше процесс только для этих подстрок. Затем повторите процедуру для второй группы в каждой инструкции «set». И так далее, рекурсивно.
В конце концов, ваша программа станет парсером языка сценариев. В этот момент вы можете начать добавлять код для преобразования каждой распознанной конструкции в язык вывода.
В зависимости от вашего опыта работы с Python, вы можете найти способы сделать код кратким.