ОПН функции с параметрами
mod() -функция
например:
входной поток:
5+5*mod(5,3*(4+3))+variable1;
что только не читал про ОПН, но как про парсить выражение с функциями,где есть несколько аргументов???
напишите пожайлуста, результат ОПН, как это обработается
вот как я думаю сделать: и результат ОПН получается:
5 5 #4 3 + 3 *,5|mod * + variable1 +
то есть # символ означающий что следует функция.
| означает конец функции и после неё сразу следует имя функции.
скажите правельные у меня мысли или естькруче способ,в общем скажите все как думаете и как делают..
пожалуйста, спасибо!
_____ 4 + 3
_________ 3 * (4 + 3)
_____________ 5, 3 * (4 + 3)
___________________ mod(5, 3 * (4 + 3))
_________________________________ mod(5, 3 * (4 + 3)) + variable1
для 3ехместной функции func вместо mod ( 5+5*func(5,3*(4+3),6)+variable1 ):
5 5 5 3 4 3 + * , 6 , func variable1 +
_____ 4 + 3
_________ 3 * (4 + 3)
_____________ 5, 3 * (4 + 3)
_________________ 5, 3 * (4 + 3), 6
________________________ func(5, 3 * (4 + 3), 6)
______________________________________ func(5, 3 * (4 + 3), 6) + variable1
Вы просто не постфиксно использовали запятую. Думайте о ней как об операторе двухместном.
с 1 запятой все ясно, но как быть со 2?
чтоб понятнее были вам мои мысли напишу небольшой пример "парсер ОПН":
// len -длина строки ОПН
int nSep=0;
// nSep - количество запятых
bool isPrevSep=false; // являтся ли предыдущий символ запятая
//
while(i<len){
if (....){ // если нашли символ функции/переменной
if (isPrevSep){
// вытаскиваем из стека параметры (интеграций=nSep+1)
// выполняем функцию
}
else{
// находим переменную
}
}
if (str==','){ // нашли в ОПН строки запятую
nSep++;
isPrevSep=true;
}
else{
// .... парсим цифры и т. п. сохраняем их в стек
// if (str=='+').... здесь складываем!
isPrevSep=false;
}
i++;
}
могут быть не точности, так как написал за 5 минут=)
но основная суть выложена!
правильно я думаю?
за ранее спасибо
где проверять наличие той или иной функции, введенная пользователем:
- где состовляется строка ОПН???
- или где уже ОПН строка разбирается??
я считаю,что правильнее проверять наличие функции/переменной, где ОПН составляется, так ??
например:
function func(a){
b=a*a;
return b;
}
t=func(10);
подскажите как парсить функцию func?
неужели, как парсер нашел вызов функции, он будет каждый раз её текст реобразовывать к ОПН???
или один раз преобразовать к ОПН, а потом её просовыполнятЬ?
тогда ещё один вопрос, как хранить эту ОПН..
в общем сплошные сложности, скажите правельный вариант пожалуйста и в общих чертах как это все сделать..
1) и ещё, как хранить данные, например значения переменных???
2)переменные же могут быть разного типа, в каком типе хранить?
спасибо
b=a;
b=b*b;
a=b;
b=0;
return a;
}
b=func(10);
как выполнить функцию func??
Вы пишете парсер вручную? :eek:
А как же lex + bison?
Не так давно делал более менее сложный парсер подмножества JavaScript на Nemerle, с использованием нашего генератора парсеров.
Вот код парсера.
А вот такие выражения он может разбирать:
x2.БлаБлаÑ = 'dfasdf"asdfsd" asds';
x = y.z = t ? a : 0x23 * 7 + 1;
; //empty statement !
function Foo(
a1 /* a1 arg*/ ,
b,
c) {
var s = t ? true : false ? h ? 7 : 8++ : g ? 3 + bar(1, 2).f : 4;
var tmp = this.xxx(/* no args! */)(a1, /* passing b*/ b, c /*and c*/).result;
return function(k, t) { return ++0x45ff+++1; };
}
Хмм трудно судить, я свой первый парсер в школе еще писал, по какому-то набору статей. В них излагались принципы построения парсера на рекурсивном спуске (сейчас я бы назвал то творение PEG-парсером).
с 1 запятой все ясно, но как быть со 2?
чтоб понятнее были вам мои мысли напишу небольшой пример "парсер ОПН":
// len -длина строки ОПН
int nSep=0;
// nSep - количество запятых
bool isPrevSep=false; // являтся ли предыдущий символ запятая
//
while(i<len){
if (....){ // если нашли символ функции/переменной
if (isPrevSep){
// вытаскиваем из стека параметры (интеграций=nSep+1)
// выполняем функцию
}
else{
// находим переменную
}
}
if (str==','){ // нашли в ОПН строки запятую
nSep++;
isPrevSep=true;
}
else{
// .... парсим цифры и т. п. сохраняем их в стек
// if (str=='+').... здесь складываем!
isPrevSep=false;
}
i++;
}
могут быть не точности, так как написал за 5 минут=)
но основная суть выложена!
правильно я думаю?
за ранее спасибо
ответьте ещё на этот вопрос=)
а во вторых, может и со скоростью выйграю!
Да и вопрос ваш -- как выполнить. Выполнить - это уже интерпретатор. Не пробовал, не знаю. =) Но прежде чем к этому этапу переходить, надо полностью парсер доделать/продумать.
Код, что вы привели, меня не пугает, возможно, т. к. у самого опыта с гулькин нос. Но это только разбор выражения. Раз у вас еще определения функций, вызовы, присваивания и т. п., то тут таким же путем, что и построение ОПН, далеко не уедешь. hardcase поправит, если я не прав. Нужно как минимум проводить лексический, синтаксический анализ. Вы лучше полностью опишите язык, парсер которого пытаетесь реализовать. Если он совсем простой, то, наверное, можно его и в лоб автоматом разбирать.
язык:
нет ограничений на тип данных, если возможно преобразовать, то преобразовывает, нет -ошибка
объявление функций...
ссылки на переменные
думаю ещё классы сделать, но пока незнаю
Yacc-подобные системы генерируют парсер по входной грамматике. Сравнения для - это где-то 3-4 тыс. строчек кода для средних размеров языка. При том, этот код совершенно не нужно отлаживать и разбираться в нем!
нет ограничений на тип данных, если возможно преобразовать, то преобразовывает, нет -ошибка
объявление функций...
ссылки на переменные
А вы уже знаете про грамматики? Языки принято формально описывать грамматиками.