Error 'In function 'void setup()': 13:1: error: a function-definition is not allowed here before '{' token' - tinkercad

This is my code
#include <IRremote.h>
IRrecv ir(10);
decode_results results;
void setup ()
{
for (int i=7 ; i<7,i++;)
{
pinMode(i,OUTPUT);
}
void loop()
{
if (ir.decode (&results))
{
if (result.value == 16593103)
{
zero ();
}
if (results.value == 16582963)
{
one ();
}
if (results.value == 16615543)
{
two ();
}
if (results.value == 16599223)
{
three();
}
if (results.value == 16591063)
{
four();
}
if (results.value == 16623703)
{
five();
}
if (results.value == 16607383)
{
six();
}
if (results.value == 16586989)
{
seven ();
}
if (results.value == 16619623)
{
eight();
}
if (results.value == 16603303)
{
nine ();
}
ir.resume ();
}
}
}
void zero ()
{
digitalWrite (0,0);
digitalWrite (1,1);
digitalWrite (2,1);
digitalWrite (3,1);
digitalWrite (4,1);
digitalWrite (5,1);
digitalWrite (6,1);
}
kindly help and send the correct code with a explanation, i am just a student who started with basic ir codes in tinkercad. i am trying to use different ir buttons in a ir remote to display on a seven segment display.

Related

Asio SSL full-duplex socket synchronization problem

My MVCE for SSL relay server:
#pragma once
#include <stdint.h>
#include <iostream>
#include <asio.hpp>
#include <asio/ssl.hpp>
namespace test
{
namespace setup
{
const uint32_t maxMessageSize = 1024 * 1024;
const uint32_t maxSessionsNum = 10;
}
enum class MessageType
{
LOG_ON = 0,
TEXT_MESSAGE = 1
};
class MessageHeader
{
public:
uint32_t messageType;
uint32_t messageLength;
MessageHeader(uint32_t messageType, uint32_t messageLength) : messageType(messageType), messageLength(messageLength) {}
};
class LogOn
{
public:
MessageHeader header;
uint32_t sessionId;
uint32_t isClient0;
LogOn() : header((uint32_t)MessageType::LOG_ON, sizeof(LogOn)) {}
};
class TextMessage
{
public:
MessageHeader header;
uint8_t data[];
TextMessage() : header((uint32_t)MessageType::TEXT_MESSAGE, sizeof(TextMessage)){}
};
class ClientSocket;
class Session
{
public:
ClientSocket* pClient0;
ClientSocket* pClient1;
};
Session* getSession(uint32_t sessionId);
class ClientSocket
{
public:
bool useTLS;
std::shared_ptr<asio::ip::tcp::socket> socket;
std::shared_ptr<asio::ssl::stream<asio::ip::tcp::socket>> socketSSL;
Session* pSession;
bool isClient0;
std::recursive_mutex writeBufferLock;
std::vector<char> readBuffer;
uint32_t readPos;
ClientSocket(asio::ip::tcp::socket& socket) : useTLS(false)
{
this->socket = std::make_shared<asio::ip::tcp::socket>(std::move(socket));
this->readBuffer.resize(setup::maxMessageSize + sizeof(MessageHeader));
this->readPos = 0;
}
ClientSocket(asio::ssl::stream<asio::ip::tcp::socket>& socket) : useTLS(true)
{
this->socketSSL = std::make_shared<asio::ssl::stream<asio::ip::tcp::socket>>(std::move(socket));
this->readBuffer.resize(setup::maxMessageSize + sizeof(MessageHeader));
this->readPos = 0;
}
bool writeSocket(uint8_t* pBuffer, uint32_t bufferSize)
{
try
{
std::unique_lock<std::recursive_mutex>
lock(this->writeBufferLock);
size_t writtenBytes = 0;
if (true == this->useTLS)
{
writtenBytes = asio::write(*this->socketSSL,
asio::buffer(pBuffer, bufferSize));
}
else
{
writtenBytes = asio::write(*this->socket,
asio::buffer(pBuffer, bufferSize));
}
return (writtenBytes == bufferSize);
}
catch (asio::system_error e)
{
std::cout << e.what() << std::endl;
}
catch (std::exception e)
{
std::cout << e.what() << std::endl;
}
catch (...)
{
std::cout << "Some other exception" << std::endl;
}
return false;
}
void asyncReadNextMessage(uint32_t messageSize)
{
auto readMessageLambda = [&](const asio::error_code errorCode, std::size_t length)
{
this->readPos += (uint32_t)length;
if (0 != errorCode.value())
{
//send socket to remove
printf("errorCode= %u, message=%s\n", errorCode.value(), errorCode.message().c_str());
//sendRemoveMeSignal();
return;
}
if ((this->readPos < sizeof(MessageHeader)))
{
asyncReadNextMessage(sizeof(MessageHeader) - this->readPos);
return;
}
MessageHeader* pMessageHeader = (MessageHeader*)this->readBuffer.data();
if (pMessageHeader->messageLength > setup::maxMessageSize)
{
//Message to big - should disconnect ?
this->readPos = 0;
asyncReadNextMessage(sizeof(MessageHeader));
return;
}
if (this->readPos < pMessageHeader->messageLength)
{
asyncReadNextMessage(pMessageHeader->messageLength - this->readPos);
return;
}
MessageType messageType = (MessageType)pMessageHeader->messageType;
switch(messageType)
{
case MessageType::LOG_ON:
{
LogOn* pLogOn = (LogOn*)pMessageHeader;
printf("LOG_ON message sessionId=%u, isClient0=%u\n", pLogOn->sessionId, pLogOn->isClient0);
this->isClient0 = pLogOn->isClient0;
this->pSession = getSession(pLogOn->sessionId);
if (this->isClient0)
this->pSession->pClient0 = this;
else
this->pSession->pClient1 = this;
}
break;
case MessageType::TEXT_MESSAGE:
{
TextMessage* pTextMessage = (TextMessage*)pMessageHeader;
if (nullptr != pSession)
{
if (this->isClient0)
{
if (nullptr != pSession->pClient1)
{
pSession->pClient1->writeSocket((uint8_t*)pTextMessage, pTextMessage->header.messageLength);
}
}
else
{
if (nullptr != pSession->pClient0)
{
pSession->pClient0->writeSocket((uint8_t*)pTextMessage, pTextMessage->header.messageLength);
}
}
}
}
break;
}
this->readPos = 0;
asyncReadNextMessage(sizeof(MessageHeader));
};
if (true == this->useTLS)
{
this->socketSSL->async_read_some(asio::buffer(this->readBuffer.data() + this->readPos, messageSize), readMessageLambda);
}
else
{
this->socket->async_read_some(asio::buffer(this->readBuffer.data() + this->readPos, messageSize), readMessageLambda);
}
}
};
class SSLRelayServer
{
public:
static SSLRelayServer* pSingleton;
asio::io_context ioContext;
asio::ssl::context sslContext;
std::vector<std::thread> workerThreads;
asio::ip::tcp::acceptor* pAcceptor;
asio::ip::tcp::endpoint* pEndpoint;
bool useTLS;
Session* sessions[setup::maxSessionsNum];
SSLRelayServer() : pAcceptor(nullptr), pEndpoint(nullptr), sslContext(asio::ssl::context::tlsv13_server)//sslContext(asio::ssl::context::sslv23)
{
this->useTLS = false;
this->pSingleton = this;
//this->sslContext.set_options(asio::ssl::context::default_workarounds | asio::ssl::context::no_sslv2);
this->sslContext.set_password_callback(std::bind(&SSLRelayServer::getPrivateKeyPEMFilePassword, this));
this->sslContext.use_certificate_chain_file("server_cert.pem");
this->sslContext.use_private_key_file("server_private_key.pem",
asio::ssl::context::pem);
}
static SSLRelayServer* getSingleton()
{
return pSingleton;
}
std::string getPrivateKeyPEMFilePassword() const
{
return "";
}
void addClientSocket(asio::ip::tcp::socket& socket)
{
ClientSocket* pClientSocket = new ClientSocket(socket); // use smart pointers
pClientSocket->asyncReadNextMessage(sizeof(MessageHeader));
}
void addSSLClientToken(asio::ssl::stream<asio::ip::tcp::socket>&sslSocket)
{
ClientSocket* pClientSocket = new ClientSocket(sslSocket); // use smart pointers
pClientSocket->asyncReadNextMessage(sizeof(MessageHeader));
}
void handleAccept(asio::ip::tcp::socket& socket, const asio::error_code& errorCode)
{
if (!errorCode)
{
printf("accepted\n");
if (true == socket.is_open())
{
asio::ip::tcp::no_delay no_delay_option(true);
socket.set_option(no_delay_option);
addClientSocket(socket);
}
}
}
void handleAcceptTLS(asio::ip::tcp::socket& socket, const asio::error_code& errorCode)
{
if (!errorCode)
{
printf("accepted\n");
if (true == socket.is_open())
{
asio::ip::tcp::no_delay no_delay_option(true);
asio::ssl::stream<asio::ip::tcp::socket> sslStream(std::move(socket), this->sslContext);
try
{
sslStream.handshake(asio::ssl::stream_base::server);
sslStream.lowest_layer().set_option(no_delay_option);
addSSLClientToken(sslStream);
}
catch (asio::system_error e)
{
std::cout << e.what() << std::endl;
return;
}
catch (std::exception e)
{
std::cout << e.what() << std::endl;
return;
}
catch (...)
{
std::cout << "Other exception" << std::endl;
return;
}
}
}
}
void startAccept()
{
auto acceptHandler = [this](const asio::error_code& errorCode, asio::ip::tcp::socket socket)
{
printf("acceptHandler\n");
handleAccept(socket, errorCode);
this->startAccept();
};
auto tlsAcceptHandler = [this](const asio::error_code& errorCode, asio::ip::tcp::socket socket)
{
printf("tlsAcceptHandler\n");
handleAcceptTLS(socket, errorCode);
this->startAccept();
};
if (true == this->useTLS)
{
this->pAcceptor->async_accept(tlsAcceptHandler);
}
else
{
this->pAcceptor->async_accept(acceptHandler);
}
}
bool run(uint32_t servicePort, uint32_t threadsNum, bool useTLS)
{
this->useTLS = useTLS;
this->pEndpoint = new asio::ip::tcp::endpoint(asio::ip::tcp::v4(), servicePort);
this->pAcceptor = new asio::ip::tcp::acceptor(ioContext, *pEndpoint);
this->pAcceptor->listen();
this->startAccept();
for (uint32_t threadIt = 0; threadIt < threadsNum; ++threadIt)
{
this->workerThreads.emplace_back([&]() {
#ifdef WINDOWS
SetThreadDescription(GetCurrentThread(), L"SSLRelayServer worker thread");
#endif
this->ioContext.run(); }
);
}
return true;
}
Session* getSession(uint32_t sessionId)
{
if (nullptr == this->sessions[sessionId])
{
this->sessions[sessionId] = new Session();
}
return this->sessions[sessionId];
}
};
SSLRelayServer* SSLRelayServer::pSingleton = nullptr;
Session* getSession(uint32_t sessionId)
{
SSLRelayServer* pServer = SSLRelayServer::getSingleton();
Session* pSession = pServer->getSession(sessionId);
return pSession;
}
class Client
{
public:
asio::ssl::context sslContext;
std::shared_ptr<asio::ip::tcp::socket> socket;
std::shared_ptr<asio::ssl::stream<asio::ip::tcp::socket>> socketSSL;
asio::io_context ioContext;
bool useTLS;
bool isClient0;
uint32_t readDataIt;
std::vector<uint8_t> readBuffer;
std::thread listenerThread;
Client() : sslContext(asio::ssl::context::tlsv13_client)//sslContext(asio::ssl::context::sslv23)
{
sslContext.load_verify_file("server_cert.pem");
//sslContext.set_verify_mode(asio::ssl::verify_peer);
using asio::ip::tcp;
using std::placeholders::_1;
using std::placeholders::_2;
sslContext.set_verify_callback(std::bind(&Client::verifyCertificate, this, _1, _2));
this->readBuffer.resize(setup::maxMessageSize);
this->readDataIt = 0;
}
bool verifyCertificate(bool preverified, asio::ssl::verify_context& verifyCtx)
{
return true;
}
void listenerRunner()
{
#ifdef WINDOWS
if (this->isClient0)
{
SetThreadDescription(GetCurrentThread(), L"listenerRunner client0");
}
else
{
SetThreadDescription(GetCurrentThread(), L"listenerRunner client1");
}
#endif
while (1==1)
{
asio::error_code errorCode;
size_t transferred = 0;
if (true == this->useTLS)
{
transferred = this->socketSSL->read_some(asio::buffer(this->readBuffer.data() + this->readDataIt, sizeof(MessageHeader) - this->readDataIt), errorCode);
}
else
{
transferred = this->socket->read_some(asio::buffer(this->readBuffer.data() + this->readDataIt, sizeof(MessageHeader) - this->readDataIt), errorCode);
}
this->readDataIt += transferred;
if (0 != errorCode.value())
{
this->readDataIt = 0;
continue;
}
if (this->readDataIt < sizeof(MessageHeader))
continue;
MessageHeader* pMessageHeader = (MessageHeader*)this->readBuffer.data();
if (pMessageHeader->messageLength > setup::maxMessageSize)
{
exit(1);
}
bool resetSocket = false;
while (pMessageHeader->messageLength > this->readDataIt)
{
printf("readDataIt=%u, threadId=%u\n", this->readDataIt, GetCurrentThreadId());
{
//message not complete
if (true == this->useTLS)
{
transferred = this->socketSSL->read_some(asio::buffer(this->readBuffer.data() + this->readDataIt, pMessageHeader->messageLength - this->readDataIt), errorCode);
}
else
{
transferred = this->socket->read_some(asio::buffer(this->readBuffer.data() + this->readDataIt, pMessageHeader->messageLength - this->readDataIt), errorCode);
}
this->readDataIt += transferred;
}
if (0 != errorCode.value())
{
exit(1);
}
}
MessageType messageType = (MessageType)pMessageHeader->messageType;
switch (messageType)
{
case MessageType::TEXT_MESSAGE:
{
TextMessage* pTextMessage = (TextMessage*)pMessageHeader;
printf("TEXT_MESSAGE: %s\n", pTextMessage->data);
}
break;
}
this->readDataIt = 0;
}
}
void run(uint32_t sessionId, bool isClient0, bool useTLS, uint32_t servicePort)
{
this->useTLS = useTLS;
this->isClient0 = isClient0;
if (useTLS)
{
socketSSL = std::make_shared<asio::ssl::stream<asio::ip::tcp::socket>>(ioContext, sslContext);
}
else
{
socket = std::make_shared<asio::ip::tcp::socket>(ioContext);
}
asio::ip::tcp::resolver resolver(ioContext);
asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(asio::ip::tcp::v4(), "127.0.0.1", std::to_string(servicePort));
asio::ip::tcp::no_delay no_delay_option(true);
if (true == useTLS)
{
asio::ip::tcp::endpoint sslEndpoint = asio::connect(socketSSL->lowest_layer(), endpoints);
socketSSL->handshake(asio::ssl::stream_base::client);
socketSSL->lowest_layer().set_option(no_delay_option);
}
else
{
asio::ip::tcp::endpoint endpoint = asio::connect(*socket, endpoints);
socket->set_option(no_delay_option);
}
this->listenerThread = std::thread(&Client::listenerRunner, this);
LogOn logOn;
logOn.isClient0 = isClient0;
logOn.sessionId = sessionId;
const uint32_t logOnSize = sizeof(logOn);
if (true == useTLS)
{
size_t transferred = asio::write(*socketSSL, asio::buffer(&logOn, sizeof(LogOn)));
}
else
{
size_t transferred = asio::write(*socket, asio::buffer(&logOn, sizeof(LogOn)));
}
uint32_t counter = 0;
while (1 == 1)
{
std::string number = std::to_string(counter);
std::string message;
if (this->isClient0)
{
message = "Client0: " + number;
}
else
{
message = "Client1: " + number;
}
TextMessage textMessage;
textMessage.header.messageLength += message.size() + 1;
if (this->useTLS)
{
size_t transferred = asio::write(*socketSSL, asio::buffer(&textMessage, sizeof(TextMessage)));
transferred = asio::write(*socketSSL, asio::buffer(message.c_str(), message.length() + 1));
}
else
{
size_t transferred = asio::write(*socket, asio::buffer(&textMessage, sizeof(TextMessage)));
transferred = asio::write(*socket, asio::buffer(message.c_str(), message.length() + 1));
}
++counter;
//Sleep(1000);
}
}
};
void clientTest(uint32_t sessionId, bool isClient0, bool useTLS,
uint32_t servicePort)
{
#ifdef WINDOWS
if (isClient0)
{
SetThreadDescription(GetCurrentThread(), L"Client0");
}
else
{
SetThreadDescription(GetCurrentThread(), L"Client1");
}
#endif
Client client;
client.run(sessionId, isClient0, useTLS, servicePort);
while (1 == 1)
{
Sleep(1000);
}
}
void SSLRelayTest()
{
SSLRelayServer relayServer;
const uint32_t threadsNum = 1;
const bool useTLS = true;
const uint32_t servicePort = 777;
relayServer.run(servicePort, threadsNum, useTLS);
Sleep(5000);
std::vector<std::thread> threads;
const uint32_t sessionId = 0;
threads.emplace_back(clientTest, sessionId, true, useTLS, servicePort);
threads.emplace_back(clientTest, sessionId, false, useTLS,servicePort);
for (std::thread& threadIt : threads)
{
threadIt.join();
}
}
}
What this sample does ?
It runs SSL relay server on localhost port 777 which connects two clients and allows exchanging
of text messages between them.
Promblem:
When I run that sample server returns error "errorCode= 167772441, message=decryption failed or bad record mac (SSL routines)" in void "asyncReadNextMessage(uint32_t messageSize)"
I found out this is caused by client which reads and writes to client SSL socket from separate threads (changing variable useTLS to 0 runs it on normal socket which proves that it is SSL socket problem).
Apparently TLS is not full-duplex protocol (I did not know about that). I can't synchronize access to read and write with mutex because when socket enters read state and there is no
incoming message writing to socked will be blocked forever. At this thread Boost ASIO, SSL: How do strands help the implementation?
someone recommended using strands but someone else wrote that asio only synchronizes not concurrent execution of read and write handles which does not fix the problem.
I expect that somehow there is a way to synchronize read and write to SSL socket. I'm 100% sure that problem lies in synchronizing read and writes to socket because when I wrote example with read and write to socket done by one thread it worked. However then client always expects that there is message to read which can block all write if there is not. Can it be solved without using separate sockets for reads and writes ?
Okay I figured it out by writting many diffrent samples of code including SSL sockets.
When asio::io_context is already running you can't simply schedule asio::async_write or asio::async_read from thread which is not
associated with strand connected to that socket.
So when there is:
asio::async_write(*this->socketSSL, asio::buffer(pBuffer, bufferSize), asio::bind_executor(readWriteStrand,writeMessageLambda));
but thread which is executing is not running from readWriteStrand strand then it should be written as:
asio::post(ioContext, asio::bind_executor(readWriteStrand, [&]() {asio::async_read(*this->socketSSL, asio::buffer(readBuffer.data() + this->readDataIt, messageSize), asio::bind_executor(readWriteStrand, readMessageLambda)); }));

Finding whether the binary tree is valid bst

I get Following error on running the code below for tree(2,2,2) on leetcode:
AddressSanitizer:DEADLYSIGNAL
==31==ERROR: AddressSanitizer: stack-overflow on address 0x7ffe3ba89ff8 (pc 0x000000372df9 bp 0x7ffe3ba8a010 sp 0x7ffe3ba8a000 T0)
==31==ABORTING
My code is given below:
class Solution {
public:
bool isValidBST(TreeNode* root) {
TreeNode* cur=root;
while(cur){
cout<<cur->val<<endl;
if(!cur->left) {
if(!cur->right) return 1;
int a=cur->val,b=cur->right->val;
if(a>=b )
return false;
cur=cur->right;
}
else{
TreeNode* prev=cur->left;
while(prev->right && prev->right!=cur)
prev=prev->right;
if(prev->right==NULL){
prev->right=cur;
cur=cur->left;
}
else{
prev->right=0;
if(cur->val>=cur->right->val) return 0;
cur=cur->right;
}
}
}
return 1;
}
};

Required Field Missing Error on Apex Trigger Test in Salesforce

I am failing my apex code test with the following error:
"System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Opportunity__c]: [Opportunity__c]
Stack Trace: Class.Integromat_GetAuroraArrayInfoTest.testTrigger: line 68, column 1"
Arrays_from_Aurora__c is a Child Relationship to Opportunity. Opportunity__c exists both as an opportunity field as well as an Arrays_from_Aurora__c field.
How do I fix this? Thank You!
Here is my test:
#isTest
public class Integromat_GetAuroraArrayInfoTest {
static SObject mock(String sobjectName) {
SObjectType t = Schema.getGlobalDescribe().get(sobjectName);
SObject o = t.newSobject();
Map<String, Schema.SObjectField> m = t.getDescribe().fields.getMap();
for (String fieldName : m.keySet()) {
DescribeFieldResult f = m.get(fieldName).getDescribe();
if (!f.isNillable() && f.isCreateable() && !f.isDefaultedOnCreate()) {
if (f.getType() == DisplayType.Boolean) {
o.put(f.getName(), false);
}
else if (f.getType() == DisplayType.Currency) {
o.put(f.getName(), 0);
}
else if (f.getType() == DisplayType.Date) {
o.put(f.getName(), Date.today());
}
else if (f.getType() == DisplayType.DateTime) {
o.put(f.getName(), System.now());
}
else if (f.getType() == DisplayType.Double) {
o.put(f.getName(), 0.0);
}
else if (f.getType() == DisplayType.Email) {
o.put(f.getName(), 'foo#foo.com');
}
else if (f.getType() == DisplayType.Integer) {
o.put(f.getName(), 0);
}
else if (f.getType() == DisplayType.Percent) {
o.put(f.getName(), 0);
}
else if (f.getType() == DisplayType.Phone) {
o.put(f.getName(), '555-555-1212');
}
else if (f.getType() == DisplayType.String) {
o.put(f.getName(), 'TEST');
}
else if (f.getType() == DisplayType.TextArea) {
o.put(f.getName(), 'TEST');
}
else if (f.getType() == DisplayType.Time) {
o.put(f.getName(), System.now().time());
}
else if (f.getType() == DisplayType.URL) {
o.put(f.getName(), 'http://example.com');
}
else if (f.getType() == DisplayType.PickList) {
o.put(f.getName(), f.getPicklistValues()[0].getValue());
}
}
}
return o;
}
#isTest static void testTrigger() {
SObject o = mock('Arrays_from_Aurora__c');
Test.startTest();
insert o;
update o;
delete o;
Test.stopTest();
System.assertEquals(200, Webhook.response.getStatusCode());
}}
The error message tells you exactly what's wrong. There's a required field called Opportunity__c on the object Arrays_from_Aurora__c, and your code is not populating it.
The data mocking framework you are using doesn't populate relationship fields at all. It's not going to work for the majority of Salesforce data models for that reason. You'll need to either manually construct all of the data required, or use a more sophisticated mocking framework that allows you to construct relationships between records.

PubSubClient & ArduinoJSON - Arduino passing char to digitalWrite

I am not sure how to pass the values in the function in order to be used within the digitalWrite functions.
I'm getting the following error:
error: cannot convert 'String' to 'uint8_t' {aka unsigned char}' for argument '1' to 'void digitalWrite(uint8_t, uint8_t)'
pubsub callback
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("New message on [");
Serial.print(topic);
Serial.print("] ");
Serial.println("");
char s[length];
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
s[i]=payload[i];
}
StaticJsonBuffer<500> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(s);
if (!root.success()) {
Serial.println("parseObject() failed");
}
String relay = root["relay"]; // "relayOne"
int time = root["timestamp"]; // 1351824120
String trigger = root["trigger"]; // "ON"
// Feel free to add more if statements to control more GPIOs with MQTT
commander(relay, trigger);
}
commander function
void commander(String relay, String trigger) {
if(trigger == "ON"){
Serial.print("Turning ");
Serial.println(relay);
Serial.println(" on");
digitalWrite(relay, HIGH);
} else if(trigger == "OFF"){
Serial.println(relay);
digitalWrite(relayOne, LOW);
Serial.print("TRIGGERED!");
} else {
// turn all the LEDs off:
for (int pin = 0; pin < relayPinCount; pin++) {
digitalWrite(relayPins[pin], LOW);
}
}
Serial.println();
}
void commander(String relay, String trigger) {
uint8_t pinNo;
if ( relay == "relayOne" ) {
pinNo = RELAY_1_PIN;
} else
if ( relay == "anotherRelay" ) {
pinNo = OTHER_RELAY_PIN;
} else
if ( ... ) {
...
} else {
return;
}
if(trigger == "ON"){
Serial.print("Turning ");
Serial.println(relay);
Serial.println(" on");
digitalWrite(pinNo, HIGH);
} else if(trigger == "OFF"){
Serial.println(relay);
digitalWrite(pinNo, LOW);
Serial.print("TRIGGERED!");
} else {
// turn all the LEDs off:
for (int pin = 0; pin < relayPinCount; pin++) {
digitalWrite(relayPins[pin], LOW);
}
}
Serial.println();
}

how to find the first and follow values of grammar

i have the following grammar and i would like to create the First & follow table. if i have a case that the first of non terminal is epsilon should i take also all the terminals that came after this non terminal from is rule?
S-> ABC
A->Aa/aB
B->Bb/epsilon
C->Cc/epsilon
and my question is:
in the first of C i need to get First(C) = {epsilon,c) and First(B) = {epsilon,b)?
i got the following results but still i think i have problems:
|first|follow
S |a |$
A |a |a
B |eps,b|b,a,$
C |eps,c|$
Finding the FIRST and Follow of a Grammar written in txt FILE:
#include<stdio.h>
#include<string.h>
#define size 10
int i,j,l,m,n=0,o,p,nv,z=0,x=0;
char str[size],temp,temp2[size],temp3[20],*ptr;
struct prod
{
char left_of_non_term[size],right_of_nonTerm[size][size],first[size],fol[size];
int n;
}pro[size];
int main()
{
FILE *f;
for(i=0;i<size;i++)
pro[i].n=0;
f=fopen("lab6.txt","r");
while(!feof(f))
{
fscanf(f,"%s",pro[n].left_of_non_term);
if(n>0)
{
if( strcmp(pro[n].left_of_non_term,pro[n-1].left_of_non_term) == 0 )
{
pro[n].left_of_non_term[0]='\0';
fscanf(f,"%s",pro[n-1].right_of_nonTerm[pro[n-1].n]);
pro[n-1].n++;
continue;
}
}
fscanf(f,"%s",pro[n].right_of_nonTerm[pro[n].n]);
pro[n].n++;
n++;
}
printf("\nGiven Grammar");
printf("\n-------------\n");
for(i=0;i<n;i++)
for(j=0;j<pro[i].n;j++)
printf("%s = %s\n",pro[i].left_of_non_term,pro[i].right_of_nonTerm[j]);
pro[0].first[0]='#';
for(i=0;i<n;i++)
{
for(j=0;j<pro[i].n;j++)
{
if( pro[i].right_of_nonTerm[j][0]<65 || pro[i].right_of_nonTerm[j][0]>90 )
{
pro[i].first[strlen(pro[i].first)]=pro[i].right_of_nonTerm[j][0];
}
else if( pro[i].right_of_nonTerm[j][0]>=65 && pro[i].right_of_nonTerm[j][0]<=90 )
{
temp=pro[i].right_of_nonTerm[j][0];
if(temp=='S')
pro[i].first[strlen(pro[i].first)]='#';
findter();
}
}
}
printf("-------------");
printf("\n\nFIRST\n");
for(i=0;i<n;i++)
{
printf("\n%s -> { ",pro[i].left_of_non_term);
for(j=0;j<strlen(pro[i].first);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].first[l]==pro[i].first[j])
break;
if(l==-1)
printf("%c ",pro[i].first[j]);
}
printf("}");
}
for(i=0;i<n;i++)
temp2[i]=pro[i].left_of_non_term[0];
pro[0].fol[0]='$';
for(i=0;i<n;i++)
{
for(l=0;l<n;l++)
{
for(j=0;j<pro[i].n;j++)
{
ptr=strchr(pro[l].right_of_nonTerm[j],temp2[i]);
if( ptr )
{
p=ptr-pro[l].right_of_nonTerm[j];
if(pro[l].right_of_nonTerm[j][p+1]>=65 && pro[l].right_of_nonTerm[j][p+1]<=90)
{
for(o=0;o<n;o++)
if(pro[o].left_of_non_term[0]==pro[l].right_of_nonTerm[j][p+1])
strcat(pro[i].fol,pro[o].first);
}
else if(pro[l].right_of_nonTerm[j][p+1]=='\0')
{
temp=pro[l].left_of_non_term[0];
if(pro[l].right_of_nonTerm[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
}
else
pro[i].fol[strlen(pro[i].fol)]=pro[l].right_of_nonTerm[j][p+1];
}
}
}
}
printf("\n\n\n");
for(i=0;i<n;i++)
{
printf("\nFOLLOW (%s) -> { ",pro[i].left_of_non_term);
for(j=0;j<strlen(pro[i].fol);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].fol[l]==pro[i].fol[j])
break;
if(l==-1)
printf("%c",pro[i].fol[j]);
}
printf(" }");
}
printf("\n");
//getch();
}
void findter()
{
int k,t;
for(k=0;k<n;k++)
{
if(temp==pro[k].left_of_non_term[0])
{
for(t=0;t<pro[k].n;t++)
{
if( pro[k].right_of_nonTerm[t][0]<65 || pro[k].right_of_nonTerm[t][0]>90 )
pro[i].first[strlen(pro[i].first)]=pro[k].right_of_nonTerm[t][0];
else if( pro[k].right_of_nonTerm[t][0]>=65 && pro[k].right_of_nonTerm[t][0]<=90 )
{
temp=pro[k].right_of_nonTerm[t][0];
if(temp=='S')
pro[i].first[strlen(pro[i].first)]='#';
findter();
}
}
break;
}
}
}
void findfol()
{
int k,t,p1,o1,chk;
char *ptr1;
for(k=0;k<n;k++)
{
chk=0;
for(t=0;t<pro[k].n;t++)
{
ptr1=strchr(pro[k].right_of_nonTerm[t],temp);
if( ptr1 )
{
p1=ptr1-pro[k].right_of_nonTerm[t];
if(pro[k].right_of_nonTerm[t][p1+1]>=65 && pro[k].right_of_nonTerm[t][p1+1]<=90)
{
for(o1=0;o1<n;o1++)
if(pro[o1].left_of_non_term[0]==pro[k].right_of_nonTerm[t][p1+1])
{
strcat(pro[i].fol,pro[o1].first);
chk++;
}
}
else if(pro[k].right_of_nonTerm[t][p1+1]=='\0')
{
temp=pro[k].left_of_non_term[0];
if(pro[l].right_of_nonTerm[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
chk++;
}
else
{
pro[i].fol[strlen(pro[i].fol)]=pro[k].right_of_nonTerm[t]
[p1+1];
chk++;
}
}
}
if(chk>0)
break;
}
}
Also Make a text File named it lab6.txt . and put grammers like below
S ABCDE
A a|0
B b|0
C c
D d|0
E e|0
Here space after NonTerminal Indicates the -> this sign and 0 indicates epsilon.