Simple MATLAB lexer program - matlab

I created a simple lexer program from MATLAB code where, when the user types a string, the lexemes in that string are categorized. However, when I enter a string in the command window the identifiers are not getting displayed.
The code is as follows :
function determineLexemes()
j = 0;
prompt = 'Enter string : ';
str = input(prompt);
arr = char(str);
strTwo = '';
display('Symbol Table');
fprintf('Lexeme \t\t Token \n');
k = length(arr);
for i = 1: k
if(arr(i) == '+')
fprintf('+ \t\t ADD_OP \n');
end
if(arr(i) == '-')
fprintf('- \t\t SUB_OP \n');
end
if(arr(i) == '*')
fprintf('* \t\t MULT_OP \n');
end
if(arr(i) == '/')
fprintf('/ \t\t DIV_OP \n');
end
if(arr(i) == '(')
fprintf('( \t\t LEFT_PAREN \n');
end
if(arr(i) == ')')
fprintf(') \t\t RIGHT_PAREN \n');
end
if(arr(i) == '=')
fprintf('= \t\t EQUAL_OP \n');
end
x = str2num(arr(i));
y = isletter(arr(i));
if(y || (isempty(x) ==0))
strTwo = strcat(strTwo,arr(i));
end
if(~ischar(arr(i)) && ~isnumeric(arr(i)))
if(~isspace(arr(i)) && ~isempty(strTwo))
m(j) = strTwo;
if(isNumeric(strTwo(1)) && regexp('.*[a-zA-]+.*'))
disp(strcat('Error. Potential variable (', strTwo, ') whose name starts with digit found'));
strTwo = '';
j = j + 1;
end
if(~(isNumeric(strTwo(1) && regexp('.*[a-zA-]+.*'))))
disp(strcat(m(j), ('\t\t IDENTIFIER')));
strTwo = '';
j = j + 1;
end
end
end
end
end
And the intended output, when '(2a + b)' is entered to the user prompt,is as follows:
However, the output currently does not identify identifiers (i.e. 2a and b in this example).
Any help on this problem is appreciated.

I tried to keep the changes needed by your code to a minimum, but there were quite a number of mistakes (even things like isNumeric instead of isnumeric or a missing argument for the regex function).
Hope you'll be satisfied with this.
function determineLexemes()
j = 1;
prompt = 'Enter string : ';
str = input(prompt);
arr = char(str);
strTwo = '';
display('Symbol Table');
fprintf('Lexeme \t\t Token \n');
k = length(arr);
for i = 1: k
if(arr(i) == '+')
fprintf('+ \t\t ADD_OP \n');
end
if(arr(i) == '-')
fprintf('- \t\t SUB_OP \n');
end
if(arr(i) == '*')
fprintf('* \t\t MULT_OP \n');
end
if(arr(i) == '/')
fprintf('/ \t\t DIV_OP \n');
end
if(arr(i) == '(')
fprintf('( \t\t LEFT_PAREN \n');
end
if(arr(i) == ')')
fprintf(') \t\t RIGHT_PAREN \n');
end
if(arr(i) == '=')
fprintf('= \t\t EQUAL_OP \n');
end
x = str2num(arr(i));
y = isletter(arr(i));
if(y || ~isempty(x))
strTwo = strcat(strTwo,arr(i));
end
if(~isspace(arr(i)) && ~isempty(strTwo))
if(~isempty(str2num(strTwo(1))) && any(regexp(strTwo,'.*[a-zA-]+.*')))
fprintf(strcat('Error. Potential variable (', strTwo, ') whose name starts with digit found \n'));
strTwo = '';
j = j + 1;
else
if isempty(str2num(strTwo(1)))
fprintf(strcat(strTwo, ('\t\t IDENTIFIER \n')));
strTwo = '';
j = j + 1;
end
end
end
end
end

Related

While loop keeps going even though creteria has been met

Hello I need this count to stop once my variable 'fourMil' is <= o but the loop keeps going and IDK why. Some help would be appreciated.
% Sum of the Fibonacci pair numbers until 4 million
clc
clear
fibo_list = [];
for i = (0:31)
if (i == 0 || i == 1 || i == 2)
fibo_list(end+1) = i + 1;
else
fibo_list(end+1) = fibo_list(end) + fibo_list(end-1);
end
end
filtered_list = [];
fourMil = 4000000;
while fourMil > 0
for i = fibo_list
if mod(i,2) == 0
filtered_list(end+1) = i;
fourMil = fourMil - filtered_list(end);
end
end
end
sumation = sum(filtered_list);
fprintf('the sum of the Fibo numbers is %i\n', sumation)
You can use a break statement to break the while loop when a condition is met:
while fourMil > 0
for i = fibo_list
if mod(i,2) == 0
filtered_list(end+1) = i;
if (fourMil - filtered_list(end)<0)
break; %This will break the loop
end
fourMil = fourMil - filtered_list(end)
end
end
end

How can i end an if statement and break out of all others?

I am making a black jack program for a class, and i have a series of "if loops"my issue is thatwhen i say yes, hit me with another card, it proceeds to the next step as i would like, but when i say "no, i am holding", it still asks me if i would like to hit again. How can i make it so that when i say no, I then end the function completly? program is below.
players=input('Welcome to Matjack! Aces count as 11, and face cards count as 10. Please enter the number of players:')
if players==1;
card_1=randi(11,1);
card_2=randi(11,1);
fprintf ('Face up card is %d! Face down is unknown!',card_1)
hit=input(' Hit? Y/N:','s')
if hit=='Y';
card_3=randi(11,1);
cards=card_1+card_3;
player_1=card_1+card_2+card_3;
if player_1<21;
fprintf('Value of face up cards is %d. Face down is still unknown!',cards);
hit=input(' Hit again? Y/N:','s')
if hit=='Y';
card_4=randi(11,1);
cards=card_1+card_3+card_4;
player_1=card_1+card_2+card_3+card_4;
end
if player_1>21 ;
fprintf ('Player one broke! Total card value was %d',player_1)
end
if hit=='N';
player_1=card_1+card_2+card_3;
fprintf ('Player one holds! Total card value was %d',player_1)
end
end
if player_1<21
fprintf('Value of face up cards is %d. Face down is still unknown!',cards);
hit=input(' Hit again? Y/N:','s')
if hit=='Y';
card_5=randi(11,1);
cards=card_1+card_3+card_4+card_5;
player_1=card_1+card_2+card_3+card_4+card_5;
end
if player_1>21 ;
fprintf ('Player one broke! Total card value was %d',player_1)
end
if hit=='N';
player_1=card_1+card_2+card_3+card_4;
fprintf ('Player one holds! Total card value was %d',player_1)
end
end
if player_1<21
fprintf('Value of face up cards is %d. Face down is still unknown!',cards);
hit=input(' Hit again? Y/N:','s')
if hit=='Y';
card_6=randi(11,1);
cards=card_1+card_3+card_4+card_5+card_6;
player_1=card_1+card_2+card_3+card_4+card_5+card_6;
end
if player_1>21 ;
fprintf ('Player one broke! Total card value was %d',player_1)
end
if hit=='N';
player_1=card_1+card_2+card_3+card_4+card_5;
fprintf ('Player one holds! Total card value was %d',player_1)
end
end
if player_1<21
fprintf('Value of face up cards is %d. Face down is still unknown!',cards);
hit=input(' Hit again? Y/N:','s')
if hit=='Y';
card_7=randi(11,1);
cards=card_1+card_3+card_4+card_5+card_6+card_7;
player_1=card_1+card_2+card_3+card_4+card_5+card_6+card_7;
end
if player_1>21 ;
fprintf ('Player one broke! Total card value was %d',player_1)
end
if hit=='N';
player_1=card_1+card_2+card_3+card_4+card_5+card_6;
fprintf ('Player one holds! Total card value was %d',player_1)
end
end
end
if hit=='N';
player_1=card_1+card_2;
fprintf ('Player one holds! Total card value was %d',player_1)
end
end
I worked on it a bit. Some functions you might want to add are the split, put in suits, and add in persistent player names. I tried to put in descriptive variable and function names.
function Matjack
global AllCards decks
AllCards = [];
clc
DealerHitOnSoft17 = 1;
disp('Welcome to Matjack! Aces count as 11, and face cards count as 10.')
if DealerHitOnSoft17
disp('Dealer hits on soft 17')
else
disp('Dealer holds on soft 17')
end
NumberPlayers = input('Please enter the number of players:');
decks = input('How many decks of cards do you want to play with? ');
playerName = cellfun(#(n) strjoin({'Player ', num2str(n)}, ' '), num2cell((1:NumberPlayers)'), 'uni', 0);
dealerCards = DealCards(2, []);
if Blackjack('Dealer', dealerCards)
printHand('Dealer''s', dealerCards)
disp('You lose')
return
end
printHand('Dealer''s', dealerCards(1))
playerHands = cellfun(#(n) DealCards(n, []), num2cell(2 * ones( NumberPlayers, 1)), 'uni', 0);
isPlaying = ones(size(playerHands));
for i = 1:NumberPlayers
isPlaying(i) = ~Blackjack(['Player ', num2str(i)], playerHands{i});
end
while any(isPlaying)
for i = 1:NumberPlayers
if isPlaying(i)
printHand(playerName{i}, playerHands{i})
if strcmpi(input([playerName{i}, ' has ', num2str(sumHand(playerHands{i}, 0)),'. Hit? Y/N:'],'s'), 'y')
playerHands{i} = DealCards(1, playerHands{i});
printHand(playerName{i}, playerHands{i})
disp([playerName{i}, ' has ', num2str(sumHand(playerHands{i}, 0)),'.'])
if sumHand(playerHands{i}, 0) > 21
disp([playerName{i}, ' busts!'])
isPlaying(i) = 0;
end
else
disp([playerName{i}, ' holds at ', num2str(sumHand(playerHands{i}, 0)),'.'])
isPlaying(i) = 0;
end
end
end
end
printHand('Dealer''s', dealerCards)
while sumHand(dealerCards, DealerHitOnSoft17) < 17
dealerCards = DealCards(1, dealerCards);
printHand('Dealer', dealerCards)
if sumHand(dealerCards, DealerHitOnSoft17) > 21
disp('Dealer busts!')
elseif sumHand(dealerCards, DealerHitOnSoft17) > 17
disp(['Dealer holds at ', num2str(sumHand(dealerCards, DealerHitOnSoft17)),'.'])
else
disp(['Dealer has ', num2str(sumHand(dealerCards, DealerHitOnSoft17)),'.'])
end
end
cellfun(#(name, h) WinDrawLose(name, sumHand(h, 0), sumHand(dealerCards, DealerHitOnSoft17)), playerName, playerHands);
end
function hand = DealCards(N, hand)
global AllCards decks
possibleCards = randi(52 * decks, N, 1);
[C, ia, ~] = unique([AllCards; possibleCards], 'stable');
ia = ia - length(AllCards);
ia(ia < 1) = [];
n = length(AllCards) + N - length(C);
AllCards = C;
hand = [hand; possibleCards(ia)];
if n > 0
hand = DealCards(n, hand);
end
end
function printHand(player, hand)
ord = horzcat('Ace', cellfun(#num2str, num2cell(2:10), 'uni', 0), 'Jack', 'Queen', 'King');
hand = mod(hand - 1, 13) + 1;
if length(hand) == 1
disp([player, ' face up card is ', strjoin(ord(hand), ', '), '. Face down is unknown!'])
elseif length(hand) > 1
disp([player, ' cards are ', strjoin(ord(hand), ', '), '.'])
end
end
function S = sumHand(hand, dealerSoft)
hand = mod(hand - 1, 13) + 1;
hand(hand >= 10) = 10;
hand(hand == 1 ) = 11;
S = sum(hand);
while ((S > 21) && any(hand == 11))
if ~(dealerSoft && ((17 <= S) && (S <= 21)))
n = find(hand == 11, 1, 'first');
hand(n) = 1;
S = sum(hand);
end
end
end
function bj = Blackjack(player, hand)
if (length(hand) == 2) && (sumHand(hand, 0) == 21)
bj = 1;
disp([player, ' hit blackjack!'])
else
bj = 0;
end
end
function WinDrawLose(name, player, dealer)
if ((player < dealer) && (dealer <= 21)) || (player > 21)
disp([name, ' loses.'])
elseif (player == dealer)
disp([name, ' draws.'])
else
disp([name, ' wins.'])
end
end

Matlab wont quit using the cross sign in the waitbar when there is an out of bound exception for the image

The value for the columns is 51 and 50, but when we use anything more than that the waitbar freezes due to index out of bound exception since its a large image and it wont fit in there, so the matlab dosent shut using the waitbar or anything. Need a way to shut the matlab when it encounters any error.
h = waitbar(0,'Progress','Name','Calculating Feature Heights...',...
'CreateCancelBtn','setappdata(gcbf,''canceling'',1)');
setappdata(h,'canceling',0); %initiallizes waitbar
s1 = size(A);
s2 = size(B);
if (s1(1) < s2(1))
n = s1(1);
else
n = s2(1); % ensures that bounds of i are within the bounds of both images
end
for i = 21:1:n % sets bounds for rows
if getappdata(h,'canceling') %checks for user pushing the cancel button on the waitbar
break
end
waitbar(i/(n-1),h) %progress bar
for j = 61:1:(m-60) % sets bounds for columns
if A(i,j) == A(i,j-1) %if adjacent pixels are the same,
Z(i,j) = Z(i,j-1); %they have the same height
disp(i,j) = disp(i,j-l);
elseif A((i), j) == B(i, j) && A(i,j) ~= A(i,j-1) && A(i,j-1) == B(i,j-1)
Z(i,j) = Z0; %condiions for pixels/features in the 'focal plane'
disp(i,j) = 0;
else
for l = 1:1:20 %sets scan range in rows for disparity
for k = 1:1:60 %sets disparity scan range in cols
if (A(i,j) == B(i-l, j-k) && B(i-l, j-k-1) == B(i-l, j-k))
Z(i,j) = Z(i-l,(j-k-1)); %allows for multipixel features
disp(i,j) = disp(i-l,(j-k-1));
break
elseif (A(i, j) == B(i-l, j-k) && B(i-l, j-k-1) ~= B(i-l, j-k))
xA = [i j];
xB = [i-l j-k];
d = xB-xA;
Z(i,j) = Z0 - (fl*shift)/sqrt((d(1)^2)+(d(2)^2));
disp(i,j) = sqrt((d(1)^2)+(d(2)^2));
break
elseif (A(i,j) == B(i-l, j+k) && B(i-l, j+k-1) == B(i-l, j+k))
Z(i,j) = Z(i-l,(j+k-1));
disp(i,j) = disp(i-l,(j+k-1));
break
elseif (A(i, j) == B(i-l, j+k) && B(i-l, j+k-1) ~= B(i-l, j+k))
xA = [i j];
xB = [i-l j+k];
d = xB-xA;
Z(i,j) = Z0 - (fl*shift)/sqrt((d(1)^2)+(d(2)^2));
disp(i,j) = sqrt((d(1)^2)+(d(2)^2));
break
else
continue
end
end
end
end
end
end
delete(h)
Use a try/catch block.
try
% whatever that might error
catch
delete(h)
end

How to loop for desired output?

HI everyone I have a matrix input program as shown below. However I fail to loop for empty or complex or NaN input. I had tired various kind of method but is still not work. Sincerely hope to get advice from you all in order to solve this problem.
clear;clc
m=2;
for i = 1:m
for j = 1:m;
element_A = ['Enter the element in row ' num2str(i) ', col ' num2str(j) ': '];
A(i,j) = input(element_A);
while isnan(A(i,j)) || ~isreal(A(i,j)) || isempty(A(i,j))
fprintf('Input not valid')
element_A = ['Enter the element in row ' num2str(i) ', col ' num2str(j) ': '];
A(i,j) = input(element_A);
end
end
end
%% sample loop
m = str2double( input('??? : ', 's') );
while isnan(m) || ~isreal(m) || m<0
m = str2double( input('Enter valid value : ', 's') );
end
You should be checking for NaN, complex values and empty inputs before you assign them in A. You can do it like this:
m=2;
A = zeros(m); % You do not have to do this but it will increase the performance of your code.
for idx = 1:m
for jdx = 1:m;
element_A = ['Enter the element in row ' num2str(idx) ', col ' num2str(jdx) ': '];
inputElement = input(element_A);
while isempty(inputElement) || isnan(inputElement) || ~isreal(inputElement)
fprintf('Invalid input');
inputElement = input(element_A);
end
A(idx,jdx) = inputElement;
end
end
Notice that I moved isempty check to first place. || is a short circuit operator and will not check the next values is the first element gives true. If it is checked after, say isnan, it will give an error.

Correct way of using validatestring?

I am trying to search for hello inside a text file in matlab with the following code:
fid = fopen(filename, 'r');
if (fid == -1)
error('cnt open');
end
i = 0;
while (i == 0)
str = 'hello';
validStrings = fgets(fid);
validStr = validatestring(str,validStrings);
disp(validStr)
if (line == -1)
i = 1;
else
fprintf(1, '%s', line);
end
end
fclose(fid);
Can i not use validStrings in this case? I get error
??? Error using ==> validatestring
Valid strings must be a cell array of strings.
The function expects a cell of strings:
A = cell(100,1); // use a bigger number if you have a large file
while (i == 0)
str = 'hello';
validStrings = fgets(fid);
j = 1;
[A{j} remain] = strtok(validStrings, ' '); //or other delimiter than spaces
while(size(remain,2) ~= 0)
[A{j} remain] = strtok(str, ' ');
j = j+1;
end
validStr = validatestring(str,A);
disp(validStr)
if (line == -1)
i = 1;
else
fprintf(1, '%s', line);
end
end